I had the following problem in our project: my customer has a long list with many text fields. I should give his users a tool for quick navigation in this list, as well as for searching and editing elements. The best solution was a text filter. When a user enters a text into it, the list automatically is filtered by all columns as follows:
First I
added XsltListViewWebPart (XLVWP) with a default view, then I added an input
text box with a 'Search' button:
<input type="text" name="searchText" />
<button type="submit">Search</button>
I configured
a new ParameterBinding element in the XLVWP to bind it with my text box:
<ParameterBinding Name="SearchText" Location="Form(searchText)" DefaultValue="" />
Into View parameter I have added following query:
<Query>
<Where>
<Or>
<Or>
<Contains>
<FieldRef Name="Title"/>
<Value Type="Text">{SearchText}</Value>
</Contains>
<Contains>
<FieldRef Name="Author"/>
<Value Type="Text">{SearchText}</Value>
</Contains>
</Or>
<Contains>
<FieldRef Name="PostCategory"/>
<Value Type="Text">{SearchText}</Value>
</Contains>
</Or>
</Where>
<OrderBy>
<FieldRef Name="PublishedDate" Ascending="FALSE"/>
</OrderBy>
</Query>
<Where>
<Or>
<Or>
<Contains>
<FieldRef Name="Title"/>
<Value Type="Text">{SearchText}</Value>
</Contains>
<Contains>
<FieldRef Name="Author"/>
<Value Type="Text">{SearchText}</Value>
</Contains>
</Or>
<Contains>
<FieldRef Name="PostCategory"/>
<Value Type="Text">{SearchText}</Value>
</Contains>
</Or>
</Where>
<OrderBy>
<FieldRef Name="PublishedDate" Ascending="FALSE"/>
</OrderBy>
</Query>
Now that I
enter a text into my filter text box and press
'Search' button my list is filtered by Title, Author and Category
columns. I can see here 3 important problems:
1.
the user has to press
'Search' button to start filtering instead of simply entering the text
2.
The user has to wait for page reload
3.
When the user
first opens this page the list is empty because the filter is empty.
I started
fixing these problems one by one. First I added asynchronous update to my list
view. Check 'Enable Asynchronous Update' and 'Show Manual Refresh Button' in
the properties of XLVWP :
Users have
got a manual refresh button in the right-hand upper corner of the list:
When they
enter a text into the filter text box and press this button, XLVWP is filtered
without the page reload. I found an
event receiver in IE developer tools:
javascript: __doPostBack('ctl00$m$g_09891d16_ead7_4eb6_9588_3c2eb636c6eactl02','cancel');return false;
I added it
to the onkeyup event handler of my filter text box and then removed 'Search' button:
Search: <input onkeyup="javascript: __doPostBack('ctl00$m$g_09891d16_ead7_4eb6_9588_3c2eb636c6ea$ctl02','cancel');" />
Great, now
the list is filtered without page update while the user inputs the text. Ok,
but there remains the last problem: an empty list when the user first comes to
the page. To solve it I used a calculated field in my list: _TitleToFilter with
formula: ="###"&Title. Then I added a default value to the
binding parameter: ###
<ParameterBinding Name="SearchText" Location="Form(searchText)" DefaultValue="###" />
In the query I replaced Title column with _TitleToFilter:
<Contains>
<FieldRef Name="_TitleToFilter"/>
<Value Type="Text">{SearchText}</Value>
</Contains>
<FieldRef Name="_TitleToFilter"/>
<Value Type="Text">{SearchText}</Value>
</Contains>
Now that the
filter is empty, the sequence of three sharps (###) is used as a filter
pattern. And all items have this substring in their _TitleToFilter column.
Ok, but a
new problem occured: when the user clears the filter text box, the list becomes
empty. The default value does not apply because the filter sends a postback
parameter but with an empty value. So I added a new hidden field to send the
filter value to my XLVWP and fill this field with javascript while the user
enters the text into the filter:
<input type="hidden" name="searchText" id="searchText" />
Search: <input onkeyup="document.getElementById('searchText').value = this.value == '' ? '###' : this.value; javascript: __doPostBack('ctl00$m$g_09891d16_ead7_4eb6_9588_3c2eb636c6ea$ctl02','cancel');" />
Search: <input onkeyup="document.getElementById('searchText').value = this.value == '' ? '###' : this.value; javascript: __doPostBack('ctl00$m$g_09891d16_ead7_4eb6_9588_3c2eb636c6ea$ctl02','cancel');" />
Now it works
perfectly. There is no need for the manual refresh button now. To remove it
form XLVWP you can just uncheck 'Show Manual Refresh Button' in its properties.