Data Grid Header Filter Renderer or how do I get aheader to filter the data in a datagrid.

Ask a Question related to Macromedia Flex General Discussion, Design and Development.

  1. #1

    Default Data Grid Header Filter Renderer or how do I get aheader to filter the data in a datagrid.

    Okay so on the same theme as why isn't the datagrid like Excel, I have created
    a (very cool) Filter header.

    1) The filter looks like any other header (thanks to the alpha ability on the
    dropdown_mc), except when you do a mouse roll over
    2) What you are filtering on is actually part of the header text (a smoke and
    mirrors thing thanks to how the combo box gets it's label) in italics and
    non-bold thanks to TextFormatting.
    3) You can have multiple header filters for different columns, the natural
    conjunction with multiple header filters is AND.
    4) Due to the CON in the next section you can add items to the dataProvider
    and it will automatically populate the new piece of data into the drop down.
    5) All function is the default, meaning essentially you don't wish to filter
    on that column.
    6) before adding items you can do a
    HeaderFilter.showItem(grid._name,itemToAdd) and it will verify that no column
    has issue with displaying the item so that you can add it if you wish.

    CONS
    1) you must maintain the same dataProvider.
    2) sorting is no good. you might want to re-sort after a filter is done (but
    providing events and what not are still something I need to provide, probable a
    modelChanged event utilizing the eventName 'filter'

    There is still a lot to do for this renderer to make it more usable, but I
    figure I've gotten everyone to a dropping off point it shouldn't be too hard.
    As I progress with this I'll post more to this thread

    // THE FOLLOWING IS AN EXAMPLE USING THE HEADER FILTER
    <mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" xmlns="../*"
    initialize="doInit()" >

    <mx:Script>
    <![CDATA[

    function doInit()
    {

    if(grid.dataProvider == undefined)
    grid.dataProvider = new Array();
    var v=0;
    var object = new Object();
    object.optionName = "1";
    object.description="ABC";
    var object2 = new Object();
    object2.optionName = "1";
    object2.description="X,YZ";
    grid.dataProvider.addItem(object);
    grid.dataProvider.addItem(object2);

    object = new Object();
    object.optionName="2";
    object.description="ABC";
    grid.dataProvider.addItem(object);
    }

    ]]>
    </mx:Script>
    <mx:Panel title="Header Filter" width="100%" height="100%">
    <mx:DataGrid id="grid" width="100%" height="100%"
    sortableColumns="false" hGridLines="false" vGridLines="false" >
    <mx:columns>
    <mx:Array>
    <mx:DataGridColumn width="300" headerText="Option"
    columnName="optionName" headerRenderer="{renderer.HeaderFilter}" />
    <mx:DataGridColumn width="300" headerText="Option Description"
    columnName="description" headerRenderer="{renderer.HeaderFilter}"/>
    </mx:Array>
    </mx:columns>
    </mx:DataGrid>
    </mx:Panel>
    </mx:Application>

    // THE FOLLOWING SHOULD GO IN renderer/HeaderFilter.mxml file
    <?xml version="1.0" encoding="utf-8"?>
    <mx:ComboBox xmlns:mx="http://www.macromedia.com/2003/mxml" verticalGap="0"
    horizontalGap="0" marginLeft="0" marginRight="0"
    cornerRadius="0" change="handleChange(event)"
    mouseOver="if(!_showingDropdown)doLater(this,'doSh ow'); mouseOut=false;"
    mouseOut="mouseOut=true; if(!_showingDropdown)doLater(this,'doHide');"
    initialize="handleInitialize()" >

    <mx:Script>
    <![CDATA[


    private static var filteredInfo:Object;
    static function removeModelChangedListeners(name)
    {
    var temp = filteredInfo[name]['columns'];
    if(temp == undefined || temp.length <1) return;
    for(var i =0;i<temp.length;i++)
    {
    temp[i].removeModelChangedListener();
    }
    }
    static function addModelChangedListeners(name)
    {
    var temp = filteredInfo[name]['columns'];
    if(temp == undefined || temp.length <1) return;
    for(var i =0;i<temp.length;i++)
    {
    temp[i].addModelChangedListener();
    }
    }
    static function showItem(name,item):Boolean
    {
    var temp = filteredInfo[name]['columns'];
    if(temp == undefined || temp.length <1) return true;
    var ret:Boolean = true;
    for(var i =0;ret && i<temp.length;i++)
    {
    if(temp[i] == undefined ) continue;
    ret = ret && temp[i].isShown(item);
    }
    return ret;
    }
    function handleInitialize()
    {
    doHide();
    if(filteredInfo == undefined)
    filteredInfo = {};
    if(filteredInfo[listOwner._name] == undefined)
    {
    filteredInfo[listOwner._name] = {};
    filteredInfo[listOwner._name]['fdata'] = new Array();
    filteredInfo[listOwner._name]['columns'] = new Array();
    }
    fData = filteredInfo[listOwner._name]['fdata'];
    filteredInfo[listOwner._name]['columns'].push(this);
    dataProvider = new Array();

    listener = new Object();
    listener.modelChanged = mx.utils.Delegate.create(this,handleModelChanged);
    addModelChangedListener();
    if(listOwner.length>0)
    {

    doLater(this,'handleModelChanged',[{target:listOwner,eventName:'updateAll'}]);
    }
    doLater(this,'dissolve',[75,0]);
    this.setStyle('themeColor',_root.getStyle("themeCo lor"));
    }
    private var listOwner : MovieClip;//reference set by Flex upon instantiation
    (owner component)
    private var hO : Object; //reference set by Flex upon instantiation (owner
    component)
    private var column : Object; //set by Flex upon instantiation by owner
    component

    private var headerText:String;
    private var fData:Array; // filtered data.
    private var listener:Object;
    var mouseOut:Boolean = true;
    function doShow()
    {
    this.downArrow_mc.alpha=65;
    this.border_mc.alpha = 65;
    this.text_mc.border_mc.alpha = 65;
    }
    function doHide()
    {
    this.downArrow_mc.alpha=0;
    this.border_mc.alpha = 0;
    this.text_mc.border_mc.alpha = 0;
    }
    function setValue(val:String)
    {
    headerText = val;
    }
    function close():Void
    {
    if(mouseOut)
    doLater(this,'doHide');
    super.close();
    }
    function handleModelChanged(event:Object):Void
    {
    var sel = selectedItem;

    if(dataProvider.getItemAt(0) == "All" && (event.eventName == 'addItems'
    ||event.eventName == 'updateAll') )
    {
    dataProvider.removeItemAt(0);
    }
    if(event.eventName == 'addItems')
    {
    for(var i = event.firstItem ;i<=event.lastItem;i++)
    {
    dataProvider.addItem(''+event.target.getItemAt(i)[column.columnName]);
    }
    dataProvider.sort(1);
    }
    else if(event.eventName == 'updateAll')
    {
    removeAll();
    var arr = new Array();
    var input = listOwner.dataProvider;
    for(var i =0;i<input.length;i++)
    {
    arr.push(''+input[i][column.columnName]);
    }
    arr.sort(1);
    dataProvider = arr;
    }
    else
    {
    return;
    }
    var found = null;
    for(var i =length-1;i>-1;i--)
    {
    if(getItemAt(i-1) == getItemAt(i))
    {
    removeItemAt(i);
    if(found != null)
    found--;
    }else if(found == null && sel == getItemAt(i) )
    {
    found =i;
    }
    }
    addItemAt(0,"All");
    if(found != null)
    {
    selectedIndex =found+1;
    }
    else
    {
    selectedIndex = 0;
    }
    }
    function isShown(item):Boolean
    {
    if(this.selectedIndex <1 || item == undefined ) return true;
    return ((''+item[this.column.columnName] )== this.selectedItem);
    }
    function setSelectedIndex(v:Number) : Void
    {
    super.setSelectedIndex(v);
    updateLabel();
    }
    function updateLabel()
    {
    var tf = new TextFormat();
    tf.italic=true;
    tf.bold = false;
    tf.color = 0x666666;
    text_mc.label.setTextFormat(headerText.length,text _mc.label.length,tf);
    }
    function draw() : Void
    {
    super.draw();
    updateLabel();
    }
    function removeModelChangedListener()
    {
    listOwner.dataProvider.removeEventListener("modelC hanged",listener);
    }
    function addModelChangedListener()
    {
    listOwner.dataProvider.addEventListener("modelChan ged",listener);
    }
    function handleChange()
    {
    // first ignore updates
    removeModelChangedListeners(listOwner._name);
    if(selectedIndex ==0)
    {
    var temp:Array = new Array();
    //put all back.
    for(var i =fData.length-1;i>-1;i--)
    {
    if(fData[i] == undefined) continue;
    if(showItem(listOwner._name,fData[i]))
    {
    temp.push(fData[i]);
    fData[i] = undefined;
    }
    }
    listOwner.dataProvider.addItemsAt(0,temp);
    }
    else
    {
    //search for others and add to fdata.
    for(var i=listOwner.length;i>=0;i--)
    {
    if(listOwner.getItemAt(i)== undefined) continue;
    if(!showItem(listOwner._name,listOwner.getItemAt(i )))
    {
    fData.push(listOwner.removeItemAt(i));
    }
    }
    var temp:Array = new Array();
    for(var i =fData.length-1;i>-1;i--)
    {
    if( fData[i] != undefined
    && showItem(listOwner._name,fData[i]))
    {
    temp.push(fData[i]);
    fData[i] = undefined;
    }
    }
    listOwner.dataProvider.addItemsAt(0,temp);

    }
    // put listener back
    addModelChangedListeners(listOwner._name);
    }
    function get selectedLabel() : String
    {
    if(selectedIndex == undefined || selectedIndex <1) return headerText;
    return headerText +" = "+ super.selectedLabel;
    }
    ]]>
    </mx:Script>
    </mx:ComboBox>

    bdeen Guest

  2. Similar Questions and Discussions

    1. Filter table by column data type
      Hello everyone, I'm using VB Script, SQL 2K. Is it possible to create a recordset from a table based on the column data type? Hypothetically,...
    2. Filter XML Data for Text Fields.
      Hi, I'm trying to display a single record out of an XML database into dynamic fields in my MovieClip. I need to be able return a single record...
    3. #40499 [NEW]: filter sapi does not register any highlightning filter
      From: php at henke37 dot cjb dot net Operating system: any PHP version: 6CVS-2007-02-15 (CVS) PHP Bug Type: Apache2 related...
    4. How to get head text in datagrid header renderer
      Hi, I will create a checkbox in one of datagrid's header. And I write a header renderer. Now I want to use the data grid's column header text as...
    5. Filter Data Grid With calendar control
      Hi, Hope this is the correct forum to post in. I am new to ASP.NET. I have a calendar control that I am using to select a date and then that date...
  3. #2

    Default Re: Data Grid Header Filter Renderer or how do I get aheader to filter the data in a datagrid.

    Very damn cool.
    Tracy
    ntsiii Guest

  4. #3

    Default Re: Data Grid Header Filter Renderer or how do I get aheader to filter the data in a datagrid.

    Thanks Tracy for all the kudos you've given me today, I think I've used up my
    cool implementations for the year though.

    I have an expanding datagrid component, but It's a little more difficult to
    use, you have to have your dataprovider items implement an interface, it's
    fairly easy to implement 3 set and 3 get methods. I'm thinking about posting
    it as well, but it's a more volatile renderer, it especially doesn't like
    sorting of any type and you have to recode if you want to use the filter as
    well.

    Nice thing about it is I use the values of the Tree skins to skin my
    expansions, so themes and colors that effect the tree effect it, but I'm still
    a little skiddish about posting it, i think it needs a lot of testing I'll
    probably wait until I have it in production.

    bdeen Guest

  5. #4

    Default Re: Data Grid Header Filter Renderer or how do I get aheader to filter the data in a datagrid.

    update.
    1) uses the filterModel eventName on the modelChanged event when the filter is
    changed, thus giving the end user the opportunity to update a sorting function,
    also includes an attribute filteredData that holds the array of filtered out
    data.
    2) removes all filtered data when an updateAll eventName on the modelChanged
    event occurs
    3) add static function getFiteredData(name) that returns filteredData array.
    4) the only time that the drop down has all contents removed and re-populated
    is when an updateAll eventName on the modelChanged event occurs. When an
    addItems eventName on the modelChanged event occurs then the recently added
    items are combed through and their data added to the drop down list.
    5) Added filterType to filterModel eventName on the modelChanged event that
    will be
    a)startedUpdatingDropDown -- indicates that we are no longer registered
    interest in updates to the data provider modehChanged event
    b)finishedUpdatingDropDown-- indicates that we have registered
    interest in updates to the data provider modehChanged event
    c)update -- indicates that a filter has occurred and what has been
    filtered from the dataprovider.

    Use 5a and 5b if you regularly update your datagrid, this will allow you to
    realize that between 5a and 5b that no updates to the drop down will occur if
    you make changes to the dataprovider.



    <?xml version="1.0" encoding="utf-8"?>
    <mx:ComboBox xmlns:mx="http://www.macromedia.com/2003/mxml" verticalGap="0"
    horizontalGap="0" marginLeft="0" marginRight="0"
    cornerRadius="0" change="handleChange(event)"
    mouseOver="if(!_showingDropdown)doLater(this,'doSh ow'); mouseOut=false;"
    mouseOut="mouseOut=true; if(!_showingDropdown)doLater(this,'doHide');"
    initialize="handleInitialize()" >

    <mx:Script>
    <![CDATA[


    private static var filteredInfo:Object;
    static function removeModelChangedListeners(name)
    {
    var temp = filteredInfo[name]["columns"];
    if(temp == undefined || temp.length <1) return;
    for(var i =0;i<temp.length;i++)
    {
    temp[i].removeModelChangedListener();
    }
    }
    static function addModelChangedListeners(name)
    {
    var temp = filteredInfo[name]["columns"];
    if(temp == undefined || temp.length <1) return;
    for(var i =0;i<temp.length;i++)
    {
    temp[i].addModelChangedListener();
    }
    }
    static function getFiteredData(name):Array
    {
    return filteredInfo[name]["fdata"];
    }
    static function showItem(name,item):Boolean
    {
    var temp = filteredInfo[name]["columns"];
    if(temp == undefined || temp.length <1) return true;
    var ret:Boolean = true;
    for(var i =0;ret && i<temp.length;i++)
    {
    if(temp[i] == undefined ) continue;
    ret = ret && temp[i].isShown(item);
    }
    return ret;
    }
    function handleInitialize()
    {
    doHide();
    if(filteredInfo == undefined)
    filteredInfo = {};
    if(filteredInfo[listOwner._name] == undefined)
    {
    filteredInfo[listOwner._name] = {};
    filteredInfo[listOwner._name]["fdata"] = new Array();
    filteredInfo[listOwner._name]["columns"] = new Array();
    }
    fData = filteredInfo[listOwner._name]["fdata"];
    filteredInfo[listOwner._name]["columns"].push(this);
    dataProvider = new Array();

    listener = new Object();
    listener.modelChanged = mx.utils.Delegate.create(this,handleModelChanged);
    addModelChangedListener();
    if(listOwner.length>0)
    {

    doLater(this,"handleModelChanged",[{target:listOwner,eventName:"updateAll"}]);
    }
    this.setStyle("themeColor",_root.getStyle("themeCo lor"));
    }
    private var listOwner : MovieClip;//reference set by Flex upon instantiation
    (owner component)
    private var hO : Object; //reference set by Flex upon instantiation (owner
    component)
    private var column : Object; //set by Flex upon instantiation by owner
    component

    private var headerText:String;
    private var fData:Array; // filtered data.
    private var listener:Object;
    var mouseOut:Boolean = true;
    function doShow()
    {
    this.downArrow_mc.alpha=65;
    this.border_mc.alpha = 65;
    this.text_mc.border_mc.alpha = 65;
    }
    function doHide()
    {
    this.downArrow_mc.alpha=0;
    this.border_mc.alpha = 0;
    this.text_mc.border_mc.alpha = 0;
    }
    function setValue(val:String)
    {
    headerText = val;
    }
    function close():Void
    {
    if(mouseOut)
    doLater(this,"doHide");
    super.close();
    }
    function handleModelChanged(event:Object):Void
    {
    var sel = selectedItem;

    if(dataProvider.getItemAt(0) == "All" && (event.eventName == "addItems"
    ||event.eventName == "updateAll") )
    {
    dataProvider.removeItemAt(0);
    }
    if(event.eventName == "addItems")
    {
    for(var i = event.firstItem ;i<=event.lastItem;i++)
    {
    dataProvider.addItem(""+event.target.getItemAt(i)[column.columnName]);
    }
    dataProvider.sort(1);
    }
    else if(event.eventName == "updateAll")
    {
    removeAll();
    fData.length=0;
    var arr = new Array();
    var input = listOwner.dataProvider;
    for(var i =0;i<input.length;i++)
    {
    arr.push(""+input[i][column.columnName]);
    }
    arr.sort(1);
    dataProvider = arr;
    }
    else
    {
    return;
    }
    var found = null;
    for(var i =length-1;i>-1;i--)
    {
    if(getItemAt(i-1) == getItemAt(i))
    {
    removeItemAt(i);
    if(found != null)
    found--;
    }else if(found == null && sel == getItemAt(i) )
    {
    found =i;
    }
    }
    addItemAt(0,"All");
    if(found != null)
    {
    selectedIndex =found+1;
    }
    else
    {
    selectedIndex = 0;
    }
    }
    function isShown(item):Boolean
    {
    if(this.selectedIndex <1 || item == undefined ) return true;
    return ((""+item[this.column.columnName] )== this.selectedItem);
    }
    function setSelectedIndex(v:Number) : Void
    {
    super.setSelectedIndex(v);
    updateLabel();
    }
    function updateLabel()
    {
    var tf = new TextFormat();
    tf.italic=true;
    tf.bold = false;
    tf.color = 0x666666;
    text_mc.label.setTextFormat(headerText.length,text _mc.label.length,tf);
    }
    function draw() : Void
    {
    super.draw();
    updateLabel();
    }
    function removeModelChangedListener()
    {
    listOwner.dataProvider.removeEventListener("modelC hanged",listener);
    }
    function addModelChangedListener()
    {
    listOwner.dataProvider.addEventListener("modelChan ged",listener);
    }
    function handleChange()
    {
    // first ignore updates
    listOwner.dataProvider.dispatchEvent({type:"modelC hanged",
    eventName:"filterModel",filterType:'startedUpdatin gDropDown'});
    removeModelChangedListeners(listOwner._name);
    if(selectedIndex ==0)
    {
    var temp:Array = new Array();
    //put all back.
    for(var i =fData.length-1;i>-1;i--)
    {
    if(fData[i] == undefined) continue;
    if(showItem(listOwner._name,fData[i]))
    {
    temp.push(fData[i]);
    fData[i] = undefined;
    }
    }
    listOwner.dataProvider.addItemsAt(0,temp);
    }
    else
    {
    //search for others and add to fdata.
    for(var i=listOwner.length;i>=0;i--)
    {
    if(listOwner.getItemAt(i)== undefined) continue;
    if(!showItem(listOwner._name,listOwner.getItemAt(i )))
    {
    fData.push(listOwner.removeItemAt(i));
    }
    }
    var temp:Array = new Array();
    for(var i =fData.length-1;i>-1;i--)
    {
    if( fData[i] != undefined
    && showItem(listOwner._name,fData[i]))
    {
    temp.push(fData[i]);
    fData[i] = undefined;
    }
    }
    listOwner.dataProvider.addItemsAt(0,temp);

    }
    // notify people about the change
    listOwner.dataProvider.dispatchEvent({type:"modelC hanged",
    eventName:"filterModel",filterType:"update", filteredData:fData});
    // put listener back
    addModelChangedListeners(listOwner._name);
    listOwner.dataProvider.dispatchEvent({type:"modelC hanged",
    eventName:"filterModel",filterType:'finishedUpdati ngDropDown'});
    listOwner.dataProvider.dispatchEvent({type:"modelC hanged",
    eventName:"filterModel",filteredData:fData});

    }
    function get selectedLabel() : String
    {
    if(selectedIndex == undefined || selectedIndex <1) return headerText;
    return headerText +" = "+ super.selectedLabel;
    }
    ]]>
    </mx:Script>
    </mx:ComboBox>

    bdeen Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139