Professional Web Applications Themes

Data Grid Header Filter Renderer or how do I get aheader to filter the data in a datagrid. - Macromedia Flex General Discussion

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 ...

  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. #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

  3. #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

  4. #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

Similar Threads

  1. Filter table by column data type
    By Brandon Taylor in forum Dreamweaver AppDev
    Replies: 3
    Last Post: August 9th, 05:24 AM
  2. Filter XML Data for Text Fields.
    By casloco in forum Macromedia Flash Data Integration
    Replies: 0
    Last Post: July 2nd, 03:02 AM
  3. #40499 [NEW]: filter sapi does not register any highlightning filter
    By php at henke37 dot cjb dot net in forum PHP Bugs
    Replies: 0
    Last Post: February 15th, 06:31 PM
  4. How to get head text in datagrid header renderer
    By xiva in forum Macromedia Flex General Discussion
    Replies: 1
    Last Post: December 7th, 03:09 PM
  5. Filter Data Grid With calendar control
    By Joey Durham in forum ASP.NET General
    Replies: 1
    Last Post: July 6th, 12:00 AM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not 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