Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6038897
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T06:17:21+00:00 2026-05-23T06:17:21+00:00

I have a custom FilterColumnHeaderRenderer with an HBox, inside a Label for the Column

  • 0

I have a custom FilterColumnHeaderRenderer with an HBox, inside a Label for the Column Header, a Textinput for the filter text and Label to clear the filter. Now I want that the column sorting only takes place on clicking the title.

Currently the I use the sortCompareFunction on HeaderRelease for the whole columnHeader.

How would you solve this requierement?

Full Code, SearchableDataGrid:

package components{
import flash.events.TextEvent;

import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.controls.DataGrid;
import mx.controls.dataGridClasses.DataGridColumn;
import mx.core.ClassFactory;
import mx.events.DataGridEvent;
import mx.formatters.DateFormatter;
import mx.utils.ObjectUtil;

[Event(name="itemsFiltered", type="components.SearchableDataGridFilterEvent")]
public class SearchableDataGrid extends DataGrid{
    private var _searchableDataProvider:ArrayCollection;
    private var _filterStrings:Object = new Object();
    private var _dataTypes:Object = new Object();
    private var _fieldFocus:String = "";
    private var _totalItems:int = 0;
    private var _dataFormatter:DateFormatter = null;
    public var _reloadQuery:Boolean = false;

    public function SearchableDataGrid(){
        super();
        init();
    }

    private function init():void{
        //initialise a standart DateFormatter
        var ft:DateFormatter = new DateFormatter();
        ft.formatString = "YYYY-MM-DD";
        this.dateFormatter = ft;    
    }

    private function numericSortByField(fieldName:String):Function { 
        return function(obj1:Object, obj2:Object):int  {  
            var testFlag1:Boolean = isNaN( Number( obj1[fieldName] ) ); 
            var testFlag2:Boolean = isNaN( Number( obj2[fieldName] ) ); 
            // if one value is not a number => string compare
            if (testFlag1 || testFlag2){
                var value1:String = (obj1[fieldName] == '' || obj1[fieldName] == null) ? null : new String(obj1[fieldName]);
               var value2:String = (obj2[fieldName] == '' || obj2[fieldName]== null) ? null : new String(obj2[fieldName]);
               return ObjectUtil.stringCompare( value1, value2, true );
            }else{
                var value1Number:Number = (obj1[fieldName] == '' || obj1[fieldName] == null) ? null : new Number(obj1[fieldName]);       
                var value2Number:Number = (obj2[fieldName] == '' || obj2[fieldName] == null) ? null : new Number(obj2[fieldName]);      
                return ObjectUtil.numericCompare(value1Number, value2Number);
            } 
        } 
    }

    private function setHeaderRenderer():void{
        var hr:FilterHeaderRendererFactory = new FilterHeaderRendererFactory(this);
        for(var i:int = 0; i < super.columns.length; i++){
            super.columns[i].showDataTips = true;
            super.columns[i].headerRenderer = hr;
            super.columns[i].itemRenderer = new ClassFactory(components.SearchableDGItemRenderer);;
            super.columns[i].sortCompareFunction = this.numericSortByField(super.columns[i].dataField);
        }
    }

    private function dataBindingChanged():void{
        if (_reloadQuery == false){
            _filterStrings = new Object();
        }else{
            Alert.show("You are reloading the same query, your filter strings are reapplied", "Information");
        }
        _dataTypes = new Object();
        _fieldFocus = "";
        setHeaderRenderer();
        prepareDataFilter();
    }


    public function set searchableDataProvider(val:ArrayCollection):void{
        this._searchableDataProvider = val;
        _totalItems = val.length;

        this.dataProvider = this._searchableDataProvider;
        dataBindingChanged();
    }


    private function prepareDataFilter():void{
        this._searchableDataProvider.filterFunction = dataFilter;
        this._searchableDataProvider.refresh();
        var ev:SearchableDataGridFilterEvent = new SearchableDataGridFilterEvent(this._searchableDataProvider.length, this._totalItems, this.filterStrings);
        this.dispatchEvent(ev);
    }

    private function dataFilter(item:Object):Boolean{
            var isMatch:Boolean = true;

            for (var field:String in _filterStrings){
                var sP:String = _filterStrings[field]; //searchpattern
                if(sP == null){
                    continue;
                }

                if(item[field] == null){
                    isMatch = false;
                    return isMatch;
                }

                var pattern:RegExp = new RegExp("^" + sP.toLowerCase().replace(new RegExp(/%/g), ".*"));
                if(item[field] is Date){
                    //special check for date columns
                    if(!pattern.test(this.dateFormatter.format(item[field] as Date)))
                    {
                        isMatch = false;
                        return isMatch;
                    }
                }else{
                    //its not a date column
                    if(!pattern.test((item[field].toString()).toLowerCase()))
                    {
                        isMatch = false;
                        return isMatch;
                    }
                }
            }
            return isMatch;
        }

    public function get filterStrings():Object{
        return this._filterStrings;
    }

    public function setFilterString(fieldName:String, value:String):void{
        this._filterStrings[fieldName] = value;

        if(value == ""){
            delete this._filterStrings[fieldName];
        }
        _fieldFocus = fieldName;
        prepareDataFilter();
    }

    public function getFilterString(fieldName:String):String{
        if(this._filterStrings[fieldName] == null){
            return "";
        }
        return this._filterStrings[fieldName];
    }

    public function setDataType(fieldName:String, value:String):void{
        this._dataTypes[fieldName] = value;
    }

    public function getDataType(fieldName:String):String{
        if(this._filterStrings[fieldName] == null){
            return "";
        }
        return this._filterStrings[fieldName];
    }

    public function getFieldFocus():String{
        return this._fieldFocus;
    }

    public function set dateFormatter(val:DateFormatter):void{
        this._dataFormatter = val;
    }

    public function get dateFormatter():DateFormatter{
        return this._dataFormatter;
    }
}

}

Full Code, FilterColumnHeaderRenderer:

package components{
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.events.TextEvent;
import flash.text.TextField;
import flash.ui.Keyboard;

import mx.containers.HBox;
import mx.containers.Tile;
import mx.containers.VBox;
import mx.controls.Button;
import mx.controls.Label;
import mx.controls.LinkButton;
import mx.controls.TextInput;
import mx.controls.dataGridClasses.DataGridColumn;
import mx.events.DataGridEvent;
import mx.events.FlexEvent;

public class FilterColumnHeaderRenderer extends VBox{
    private var title:Label;
    private var filter:TextInput;
    private var clearFilter:Label;
    private var filterHBox:HBox;
    private var tfHasFocus:Boolean = false;
    private var dataFieldName:String;
    private var dataObj:DataGridColumn;
    private var _dataGrid:SearchableDataGrid;

    public function FilterColumnHeaderRenderer(){
        super();
        this.verticalScrollPolicy = "off";
        this.horizontalScrollPolicy = "off";

        this.addEventListener(FlexEvent.CREATION_COMPLETE, creationComplete);

        title = new Label();
        filter = new TextInput();
        clearFilter  = new Label();
        filterHBox  = new HBox();

        title.percentWidth = 100;
        filterHBox.percentWidth = 100;

        clearFilter.width = 10;
        clearFilter.toolTip = "Clear the filter for this column"
        clearFilter.htmlText = "x";     

        this.addChildAt(title, 0);
        filterHBox.addChildAt(clearFilter, 0);
        filterHBox.addChildAt(filter, 1);
        this.addChildAt(filterHBox, 1);

        clearFilter.addEventListener(MouseEvent.CLICK, resetFilter);

        filter.addEventListener(FocusEvent.FOCUS_IN, hasFocus);
        filter.addEventListener(FocusEvent.FOCUS_OUT, lostFocus);
        filter.addEventListener(TextEvent.TEXT_INPUT, textChange);
        filter.addEventListener(KeyboardEvent.KEY_DOWN, textKeyDown);

        title.addEventListener(DataGridEvent.HEADER_RELEASE, onHeaderRelease);

    }

    private function onHeaderRelease( event:DataGridEvent ): void {
        var rdr:FilterColumnHeaderRenderer = event.itemRenderer as FilterColumnHeaderRenderer;
        var dataGrid:SearchableDataGrid = SearchableDataGrid(event.target);
        var dataField:String = event.dataField;
        var columnIndex:int = event.columnIndex;
    }

    private function resetFilter(event:MouseEvent):void{
        var tmpFieldName:String = event.currentTarget.parent.parent.fieldName;
        this._dataGrid.setFilterString(dataFieldName, "");
        this.filter.text = "";
    }

    private function textKeyDown(event:KeyboardEvent):void{
        if(this._dataGrid){
            if(event.keyCode == flash.ui.Keyboard.BACKSPACE){
                var actString:String = this.filter.text;
                this._dataGrid.setFilterString(dataFieldName, actString.substr(0, (actString.length > 0 ? actString.length - 1 : 0)));
            }
        }
    }

    private function creationComplete(event:FlexEvent):void{
        if(this._dataGrid != null && this._dataGrid.getFieldFocus() == dataFieldName){
            this.filter.setFocus();
        }
    }

    public function textChange(event:TextEvent):void{
        if(this._dataGrid)
        {
            this._dataGrid.setFilterString(dataFieldName, this._dataGrid.getFilterString(dataFieldName) + event.text);
        }
    }

    private function hasFocus(event:FocusEvent):void{
        tfHasFocus = true;
    }

    private function lostFocus(event:FocusEvent):void{
        tfHasFocus = false;
    }

    override public function set data(value:Object):void{
        dataObj = (value as DataGridColumn);

        dataFieldName = dataObj.dataField;

        this.title.text = dataObj.headerText;
        this.title.toolTip = dataObj.headerText;

        if(this._dataGrid)
        {
            var fs:String = this._dataGrid.filterStrings[dataFieldName];
            if(fs != null){
                this.filter.text = fs;
            }
        }

        this.dispatchEvent(new FilterColumnHeaderRendererCreatedEvent(this, true));
    }


    public function get hasTextFocus():Boolean{
        return this.tfHasFocus;
    }

    public function get fieldName():String{
        return this.dataFieldName;
    }

    public function setText(newText:String):void{
        this.filter.text = newText;
    }

    public function set dataGrid(value:SearchableDataGrid):void{
        this._dataGrid = value;
    }

    public function get dataGrid():SearchableDataGrid{
        return this._dataGrid;
    }   
}

}

Full Code, FilterHeaderRendererFactory:

package components{
import mx.controls.DataGrid;
import mx.core.ClassFactory;
import mx.core.IFactory;

public class FilterHeaderRendererFactory implements IFactory{
    private var _base_factory:ClassFactory;
    private var _grid:SearchableDataGrid;


    public function FilterHeaderRendererFactory(grid:SearchableDataGrid){
        _base_factory = new ClassFactory(FilterColumnHeaderRenderer);
        _grid = grid;
    }

    public function newInstance():*{
        var o:FilterColumnHeaderRenderer = _base_factory.newInstance() as FilterColumnHeaderRenderer;
        o.dataGrid = _grid;
        return o;
    }
}

}

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T06:17:22+00:00Added an answer on May 23, 2026 at 6:17 am

    Conceptually; I’d do it this way:

    Dispatch a custom event from your custom header. Make sure it bubbles. Listen for that event on the DataGrid and then sort your dataProvider directly without using the built in DataGrid functionality.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have custom classes that I currently instantiate within App.xaml as resources. I want
I have custom slider that I use the following touch event to respond to:
I have custom JSP tags that generate some HTML content, along with some javascript
I have Custom uitableviewcell: ScrollViewCell I want to know what the difference is between
I have custom Question objects which I render into html form elements. I want
I have custom class that extends WebViewPage that I use as the base for
I have created custom post types that also have custom meta_boxes I've created. Currently,
I have custom coded several enterprise applications for mid to large organizations to use
I have custom errors configured in my web.config, but IIS 6.0 is returning the
I have custom configuration section within web.config file. I'm lingering between: Reading it into

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.