Download Source Code and Sample application : Excel's Filter Dialog My GridView Filter Extender
Download Source Code and Sample application :
The above Screen Shots look promising , don't they ?So, How would one go about building such a control ? Well, I have it laid out in front of you .1) Find all unique Strings in the same column 2) Build a lookup table that stores the Unique string and the row Indices for the rows that contain the Unique String3) Once user builds a Filter Expression and clicks on "Ok" , Filter the Rows in the Table based on the Expression.4) For Now , the Filter Expression can only be a sequence of strings that the user wants to see in the grid.
Ex : If your grid looks like this :
The filter expression would be a comma-separated string that contains the unique strings to match in the rows.
var _currentRowFilter = "Ajax,Moo"
The lookup Table would look like this :
_lookupTable Select All "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23" Ajax "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16" Moo "17,18,19,20,21,22,23" so , if we want to filter the rows , we would need to :
1) Hide all Rows to begin with . HideRows : this.lookupTable["Select All"]
2) Show only those rows that are found in the lookup table against the filter Terms. ShowRows :this.lookupTable["Ajax"]
That's about the algorithm / design for the extender to work .Getting this working is another matter altogether.Once you have understood this , lets start:
Find all unique Strings in the same column :
once you find all the unique strings in all subsequent rows for the same column , we will need to build the checkbox list that will allows the user to select the filter Terms. I.e this :
This is a bit tricky , the way one would go about doing this would be :
Find out which Column the Extender is added in .Find the Cell Index of the Column , lets say _cellIndex For all subsequent rows in the table, Lookup the innerText of the Cell with CellIndex cellIndex.
For Each Row Read the innerText of the Cell at CellIndex cellIndex. IF the string read is not yet present in the lookup Table then BEGIN add it to the lookup Table along with the rowIndex of the current Row END ELSE if string is already present in the lookupTable then
Begin add the RowIndex to the lookupTable[string] location. END IF
Once you have found all the Unique Strings , build the CheckBoxList and attach the appropriate handlers .
Once user builds a Filter Expression and clicks on "Ok" , Filter the Rows in the Table based on the Expression.
Hide All Rows .Get all the Rows in the Table other than the header and the footer , _rowsInTable.Get the Current Search Filter by adding all the strings that are checked in the CheckBoxList.For each term in the Search Filter , get the appropriate row Indices , For each row Index in the Row Indices, _rowIndex assign the cssClass _inFilterCssClass to the _rowsInTable[_rowIndex].
This is all neat , what if I have multiple columns in my GridView and I want to filter each succeeding Column depending on the previous Column?
Well, I have thought about that too ..This is what we would do :Every FilterExtender (a) can have a Dependent Filter (b) , if filter (b) is used to filter data ( it raises the itemFiltered Event ),then the Filter (a) has to rebuild its index to remove any index text that was removed as a result of the filter expression on filter (b).Important Note about the DependentFilterID If a FilterExtender (a) has a FilterExtender (b) as its Dependent Filter ID , they both should have the matching values for the InFilterCssClass and the NotInFilterCssClass attributes.
<Raj:GridViewFilterExtender DependentFilterId="optionListPnl"
$find(<filterBehaviorID>).set_dependentFilterId(<dependentFilterId>)
Attributes :
Events :
<Raj:OptionPickerBehavior runat="server" ID="optionListPnl" TargetControlID="btnToggle" blah blah blah OnOkScript="okClickHandler" OnCancelScript ="cancelClickHandler" OnClientItemFiltered ="itemFilteredHandler" OnClientItemSelected ="itemSelectedHandler"> </Raj:OptionPickerBehavior>
<script language="javascript" type="text/javascript"> function itemSelectedHandler(element,args) { Sys.Debug.trace( args.get_text() + " " + args.get_isChecked()); } function itemFilteredHandler(element,args) { Sys.Debug.trace( args.get_item() + " " + args.get_filterText()); } function okClickHandler(element,args) { Sys.Debug.trace( "Ok Button was clicked" ); } function cancelClickHandler(element,args) { Sys.Debug.trace( "Cancel Button was clicked"); } function traceCall(msg) { $get("traceDiv").appendChild(document.createTextNode(msg)); } </script>
b) Script
$find("BehaviorId").add_onOk( okClickHandler ); $find("BehaviorId").add_onCancel( cancelClickHandler ); $find("BehaviorId").add_itemFiltered( itemFilteredHandler ); $find("BehaviorId").add_itemSelected( itemSelectedHandler );
That's it for now ! Do give feedback on the control if you get a chance to use it / look at it .
PingBack from http://pooltoysite.info/story.php?id=3484
A very good implementation. The downside is when you load a more realistic gridview with 2,000 rows or so and 500 or so unique entries - the execution is very slow - but this is client side.
I see it's about two years old... any updates?
awesome !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
exactly what i am searching
thanx a lot
good one..