3.2.0

Filter built into header in Extended Grid

Hi Alex,

Please lend some insight to my issue.

I am trying to build filtering functionality into a row of headers in the extended grid v2.02

I simply apply a input template to the second row of headers in the grid and run a filtering function (based on the standard template found in the forum) upon onControlValidated of the input tempate applied to the header.

(see sample code below)

This works adequately except for these 2 main issues frustrating me :
1) When one of the filter cells is validated, the filtering function runs forcing an implicit refresh() of the grid. When this is done things start to go wrong. :-) Namely :
a) clicking on the same filter cell - that was just used - again directly after the filter run and trying to validate it again fails (i.e it does nothing and no filter is run) - I noticed also that this cell also now generates a "clicked" event not a "edit started" event as usual (checked using the window.status outputs). Further no other cell can be selected as selection appears to be disabled or broken at that time.
b) secondly I noticed that after the filter run, clicking on anything else (although selection doesn't work) and THEN clicking on the same filter cell that was just used, works correctly. (I.e. an "edit started" event is fired and the filter runs successfully upon valitation completing)

2) I would love to be able to find a way to reassign focus to the filter cell that was just used after the "refresh()". I've tried passing the source of the filter to the function and manually focussing and selecting in javascript to no avail.

Any help/info regarding these issues will be greatly appreciated.

Thanks in advance.
Code sample :
<html>
<head>
    <title>ActiveWidgets Examples</title>
    <script src="../../runtime/lib/aw.js"></script>
    <link href="../../runtime/styles/xp/aw.css" rel="stylesheet"/>
</head>
<body>
<style>

    #myGrid { width: 400px}
    #myGrid .aw-grid-row {height: 20px; border-bottom: 1px solid #ccc}
    /*	Alternate row colors */
    #myGrid .aw-alternate-even {background: #fff;}
    #myGrid .aw-alternate-odd {background: #eee;}
    /* Selected rows */
    #myGrid .aw-rows-selected {background: #316ac5;}
    #myGrid .aw-column-0 {width: 50px; border-right: 1px dotted #ccc;}
    #myGrid .aw-column-1 {width: 150px; border-right: 1px dotted #ccc;}
    #myGrid .aw-column-2 {text-align: right}
    #myGrid .aw-column-3 {text-align: right}
    #myGrid .aw-column-4 {text-align: right}
</style>
<script>
    var myData = [
        ["MSFT","Microsoft Corporation", "314,571.156", "32,187.000", "55000"],
        ["ORCL", "Oracle Corporation", "62,615.266", "9,519.000", "40650"],
        ["SAP", "SAP AG (ADR)", "40,986.328", "8,296.420", "28961"],
        ["CA", "Computer Associates Inter", "15,606.335", "3,164.000", "16000"],
        ["ERTS", "Electronic Arts Inc.", "14,490.895", "2,503.727", "4000"],
        ["SFTBF", "Softbank Corp. (ADR)", "14,485.840", ".000", "6865"],
        ["VRTS", "Veritas Software Corp.", "14,444.272", "1,578.658", "5647"],
        ["SYMC", "Symantec Corporation", "9,932.483", "1,482.029", "4300"],
        ["INFY", "Infosys Technologies Ltd.", "9,763.851", "830.748", "15400"],
        ["INTU", "Intuit Inc.", "9,702.477", "1,650.743", "6700"],
        ["ADBE", "Adobe Systems Incorporate", "9,533.050", "1,230.817", "3341"],
        ["PSFT", "PeopleSoft, Inc.", "8,246.467", "1,941.167", "8180"],
        ["SEBL", "Siebel Systems, Inc.", "5,434.649", "1,417.952", "5909"],
        ["BEAS", "BEA Systems, Inc.", "5,111.813", "965.694", "3063"],
        ["SNPS", "Synopsys, Inc.", "4,482.535", "1,169.786", "4254"],
        ["CHKP", "Check Point Software Tech", "4,396.853", "424.769", "1203"],
        ["MERQ", "Mercury Interactive Corp.", "4,325.488", "444.063", "1822"],
        ["DOX", "Amdocs Limited", "4,288.017", "1,427.088", "9400"],
        ["CTXS", "Citrix Systems, Inc.", "3,946.485", "554.222", "1670"],
        ["KNM", "Konami Corporation (ADR)", "3,710.784", ".000", "4313"]
    ];
    var myRow = ["MSFT","Microsoft Corporation", "314,571.156", "32,187.000", "55000"]
    var myHeaders = ["Ticker", "Company Name", "Market Cap.", "$ Sales", "Employees"];

    var obj = new AW.Grid.Extended;
    obj.setId("myGrid");	// necessary for CSS rules

    obj.setColumnCount(5);
    obj.setRowCount(20);
    obj.setCellText(myData);

    obj.setHeaderCount(2);
    obj.setHeaderText(myHeaders,0);

    /*Apply a input template to the second row of headers*/
    for (var i = 0; i < myData.length;i++){
        var filterInputTemplate = new AW.UI.Input;
        //Function for completed validation
        filterInputTemplate.onControlValidated = function(text,col,row){
            window.status = "validated - text:" + text + "\ncol:" + col + "\nrow:" + row;
            filterFunction(this);
        }
        //Output a clicked event
        filterInputTemplate.onControlClicked = function(event,col,row){
            window.status = "clicked:\ncol:" + col + "\nrow:" + row;
        }
        //Output a editstarted event
        filterInputTemplate.onControlEditStarted = function(event,col,row){
            window.status = "editstarted:\ncol:" + col + "\nrow:" + row;
        }
        
        obj.setHeaderTemplate(filterInputTemplate, i,1);
    }
    /*End of filter input*/



    document.write(obj);
</script>
<script>
    function filterFunction(source){
        alert("filter runs here...");
        obj.clearSortModel();
        obj.clearSelectionModel();
        //does some filtering that leading to a...
        obj.refresh();
        //Then try to resend the focus to the source object 
        try {
            source.focus();
            source.select();
        }
        catch(ex){
            //alert(ex.message);
        }
    }
</script>
</body>
</html>
StefK
June 11,
Hi Alex, any info on this issue?
Should I try another method, perhaps?

Thanks
StefK
June 13,
The issue is likely related to the onRowIndicesChanged event handler, which is triggered by setRowIndices([..]) method. The default handler calls grid.refresh() and this breaks editing procedure in the input box. The possible solution is to replace full grid refresh with just rows area refresh. For this purpose you have to define your own onRowIndicesChanged handler (and cancel the default one) -

obj.onRowIndicesChanged = function(indices){

    var positions = [];
    for (var i=0; i<indices.length; i++){
        positions[indices[i]] = i;
    }
    this.setRowPosition(positions);
    //this.refresh(); // breaks editing

    // default refresh method
    var refresh = AW.System.HTML.prototype.refresh;

    refresh.call(this.getRowsTemplate(0));
    refresh.call(this.getRowsTemplate(1));
    refresh.call(this.getRowsTemplate(2));

    // cancel default event handler
    return true;
};


In the extended grid the rows area is repeated three times (left fixed, central scrolling, right fixed), so you should refresh all of them.
Alex (ActiveWidgets)
June 13,
Thanks a million Alex I'll give it a try and let you know. :-)
Enjoy the day.
StefK
June 14,
Hi again Alex,

The "patched" event solution you posted above is working very well. :)
The only issue that I've seen so far is that the sorting arrow in the header is not displaying, after a sort. I guess this is because sorting procedure also relies on the full "refresh" provided by the original "onRowIndicesChanged" to update the other screen elements (like the header,etc). So there might be more niggles waiting to be uncovered as well.

I'll dig through the AW source to try and find a work around, but I'll appreciate it if you could possibly help with a way to at least refesh the top header (not the new filter with input as discussed above though) as well, if it is possible.

Thanks a lot.
StefK
June 14,
Yes, you need to refresh the top headers row as well :-)

obj.onRowIndicesChanged = function(indices){

    var positions = [];
    for (var i=0; i<indices.length; i++){
        positions[indices[i]] = i;
    }
    this.setRowPosition(positions);
    //this.refresh(); // breaks editing

    // default refresh method
    var refresh = AW.System.HTML.prototype.refresh;

    refresh.call(this.getRowsTemplate(0));
    refresh.call(this.getRowsTemplate(1));
    refresh.call(this.getRowsTemplate(2));

    refresh.call(this.getHeadersTemplate(0, 0));
    refresh.call(this.getHeadersTemplate(0, 1));
    refresh.call(this.getHeadersTemplate(0, 2));

    // cancel default event handler
    return true;
};
Alex (ActiveWidgets)
June 14,
Great. Thanks Alex. Works perfectly.

One (hopefully last ;-)) question regarding this...

When the filter is run, and the new (reduced) set of row indices is loaded, the grid row area scrolling still remains unfreshed and unaware of the new row count. (I.O.W It's too large, and scrolls to a blank area. :-))

Is there a way I can refresh this as well?

As a blind try, I have added just :
refresh.call(this.getScrollTemplate());


, to the patched onRowIndicesChanged function but it breaks the grid. Badly. :-)

Any advice please?
Thanks again.
StefK
June 15,
*bump*
StefK
June 20,
Yes, it is necessary to force scrollHeight recalculation after filtering -

this.raiseEvent("adjustScrollHeight");
this.raiseEvent("adjustScrollBars");


Complete code -

obj.onRowIndicesChanged = function(indices){

    var positions = [];
    for (var i=0; i<indices.length; i++){
        positions[indices[i]] = i;
    }
    this.setRowPosition(positions);
    //this.refresh(); // breaks editing

    // default refresh method
    var refresh = AW.System.HTML.prototype.refresh;

    refresh.call(this.getRowsTemplate(0));
    refresh.call(this.getRowsTemplate(1));
    refresh.call(this.getRowsTemplate(2));

    refresh.call(this.getHeadersTemplate(0, 0));
    refresh.call(this.getHeadersTemplate(0, 1));
    refresh.call(this.getHeadersTemplate(0, 2));

    // trigger scroll height recalc
    this.raiseEvent("adjustScrollHeight");
    this.raiseEvent("adjustScrollBars");

    // cancel default event handler
    return true;
};


Alex (ActiveWidgets)
June 25,
To see the effect of the patch, make sure you've disabled (comment) any call of obj.refresh() in your code.
MF
October 16,
How can I make the second header not visible. I mean using a toggle button, how do I make it appear and disappear?
Isaac (BMS)
February 15,
StefK:
Could you contribute the filtering you were working?
Isaac (BMS)
February 20,

This topic is archived.

See also:


Back to support forum