3.2.0

when will ajax paging be available?

Hi Alex,

I love the grid and have purchased it (2.0). I really NEED ajax paging though. Do you have any idea as to when this might be available (even in beta... I'll test for you).

Basically, I need the grid to be able to batch some number of rows but I'll set an total row amount. If the user scrolls past the batched rows, an ajax callback happens (with a url that is set & parameters indicating desired rows) and then the grid displays the rows. Thanks, Alex.

Joe
Joe Hudson
April 20,
Joe,

from your description it looks more like virtual mode with incremental data uploading (in small chunks) and not paging in the traditional sense. If this is true, I will be able to make an example of customized data model. Tell me which data format you are going to use (json/xml/csv?).
Alex (ActiveWidgets)
April 20,
If I can do this now, that would be AWESOME!!!

I actually use array-based data. Here is an example of a grid:

<style>
#locations {height: 80px; width: 620px; margin: 0px; border: none; font: menu;}
#locations .aw-column-0 {display: none!important;}
#locations .aw-column-1 {width: 198.45px; }
#locations .aw-column-2 {width: 368.55px; }
#locations .aw-row-selector {width: 32px; text-align: center}
#locations .aw-alternate-odd {background: #D6DFFF;}
#locations .aw-grid-cell {border-right: 1px solid threedlightshadow;}
#locations .aw-grid-row {height: 20px; border-bottom: 1px solid threedlightshadow;}
#locations .aw-mouseover-row .aw-row-selector {color: red;}

</style>
<div style="margin-bottom: 5px">
<script language="javascript">
var locationsEntries = [
["23", "Charlotte, NC", "United States"],
["1", "Houston, TX", "United States"]
];
var locationsGrid = new AW.UI.Grid;
locationsGrid.setCellText(locationsEntries);
locationsGrid.setHeaderText(["","Name","Region"]);
locationsGrid.setRowCount(2);
locationsGrid.setColumnCount(3);
locationsGrid.setSelectorVisible(true);
locationsGrid.setSelectorText(function(i){return this.getRowPosition(i)+1});
locationsGrid.setSelectionMode("single-row");
locationsGrid.setId("locations");
document.write(locationsGrid);
</script>
</div>


So, if I initially loaded 25 rows into the grid but the dataset (in the database) had 1500 rows, how would that work? I assume I would call:
locationsGrid.setRowCount(1500);
But what is the code to do a server call to retrieve that data and add to the grid when the user scrolls past 25?

Thank you so much, Alex.

Joe

Joe Hudson
April 20,
I don't have complete working solution, but here is a small demo which may help you to start.

The grid calls table.getData(col, row) method for the the cells data. If particular row is missing than the table returns empty string and adds row index to the range of row indices to be retrieved. The table model then initiates the remote request passing the starting row and the number of rows to retrieve. When the data is received it is added to the main array and the grid is repainted.

For the purpose of this demo the actual request is replaced by simply 0.5 sec timeout and fake array data. In actual implementation you'd have to make JSON array on the server and eval it in table.response() callback.

<html>
<head>
    <script src="../../runtime/lib/aw.js"></script>
    <link href="../../runtime/styles/xp/aw.css" rel="stylesheet"></link>
</head>
<body>
<style>

</style>
<script>

var MyTable = AW.HTTP.Request.subclass();

MyTable.create = function(){

    var obj = this.prototype;

    obj._data = []; // data array
    obj._min = -1;   // min requested index
    obj._max = -1;   // max requested index
    obj._loading = false;  // request state

    // returns cell data
    obj.getData = function(col, row){

        if(this._data[row]){
            return this._data[row][col];
        }

        // if data not is available - remember requested rows range
        this._min = this._min < 0 ? row : Math.min(row, this._min);
        this._max = this._max < 0 ? row : Math.max(row, this._max);

        // schedule data request
        if (!this._loading){
            this._loading = true;
            this.setTimeout(function(){
                // initiates the data request
                var startIndex = this._min > 20 ? this._min - 20 : 0;
                var rowCount = this._max - this._min + 41;

                // initialize http request object
                this.setURL("..some request url..");
                this.setParameter("startIndex", startIndex);
                this.setParameter("rowCount", rowCount);
                this.request();

            }, 0);
        };

        // if data is not loaded - return empty string
        return "";
    }

    // override with fake request method for demo purposes
    obj.request = function(){
        this.setTimeout(function(){
            this.response("..returned data string..");
        }, 500);
    }

    // callback to process returned data
    obj.response = function(data){

        if (!this._data.length){
            this._data = [];
        }

        this._min = -1;
        this._max = -1;
        this._loading = false;

        // for demo only, should take from the returned data
        var startIndex = Number(this._startIndexParameter);
        var rowCount = Number(this._rowCountParameter);

        window.status = "Loaded rows " + startIndex + "-" + (startIndex+rowCount);

        var i, j;

        for (i=startIndex;i<startIndex+rowCount;i++){

            this._data[i] = [];

            for(j=0;j<20;j++){
                // for demo only, should take from the returned data
                this._data[i][j] = i + "." + j;
            }
        }

        if (this.$owner){
            this.$owner.setRowCount(1000); //should take from the returned data
            this.$owner.refresh();
        }
    }
}


    var table = new MyTable();
    table.setParameter("startIndex", 0);
    table.setParameter("rowCount", 50);
    table.request();

    var obj = new AW.UI.Grid;

    obj.setColumnCount(10);
    obj.setCellModel(table);

    document.write(obj);

</script>
</body>
</html>

Alex (ActiveWidgets)
April 20,
I would also be extremely interested in this. We also deal with large data sets and if we could bring them in a page at a time that would be great. we use CSV.

In my case we are pulling data from a servlet in CSV forum. We would need a mechanism that would increment Page up, Page Down, beginning and end.

WeeJavaDude
April 20,
It should also work for CSV with minor changes. Current AW.CSV.Table parses the text into js array, so it is nearly the same.
Alex (ActiveWidgets)
April 20,
This is great. Thanks, Alex.

Is there any way, right now, that I could use the
table.setParameter("rowCount", 50);
method to represent the whole set:
table.setParameter("rowCount", 1500); and somehow have the grid to the callback when it hit a row that has not been loaded to avoid a full repaint... maybe could then do a row by row repaint and keep cursor position?

I have absolutely no idea how I would do this... is something that could be done currently with a script similar to the one above? I would be extremely grateful if you could show me how to do something like that. Thank you very much.

Joe
Joe Hudson
April 20,
Will this only work for v2? I am stuck with 1.0 for the time being.

Thanks
Nick
July 24,
Result please an example without virtual demonstration.
In what kind the server should return data?
Thanks
Valeri
February 11,
Could you give an example of this using CSV? I am still confused.

Thanks
Rob
June 7,
I understand that I would replace the setURL with my url that is going to generate the XML.

However, I don't see anything that actually calls that URL. Do I need to replace the obj.request function code with my own code to make a call to that URL?

Could you give me some idea of what that might look like?

Thanks,

Jim
Jim Nickel
November 7,
Ok,

I have figured out more stuff since my last post (lets hope!)

So....here is my example code....not quite there yet.

<html> 
<head> 
    <script src="../../runtime/lib/aw.js"></script> 
    <link href="../../runtime/styles/xp/aw.css" rel="stylesheet"></link> 
</head> 
<body> 
<style> 

</style> 
<script> 

var MyTable = AW.HTTP.Request.subclass(); 

MyTable.create = function(){ 

    var obj = this.prototype; 

    obj._data = []; // data array 
    obj._min = -1;   // min requested index 
    obj._max = -1;   // max requested index 
    obj._loading = false;  // request state 

    // returns cell data 
    obj.getData = function(col, row){ 

        if(this._data[row]){ 
            return this._data[row][col]; 
        } 

        // if data not is available - remember requested rows range 
        this._min = this._min < 0 ? row : Math.min(row, this._min); 
        this._max = this._max < 0 ? row : Math.max(row, this._max); 

        // schedule data request 
        if (!this._loading){ 
            this._loading = true; 
            this.setTimeout(function(){ 
                // initiates the data request 
                var startIndex = this._min > 20 ? this._min - 20 : 0; 
                var rowCount = this._max - this._min + 41; 

                // initialize http request object
                this.setURL("index.php"); 
                this.setParameter("offset", startIndex); 
                this.setParameter("limit", rowCount); 
                this.request(); 

            }, 0); 
        }; 

        // if data is not loaded - return empty string 
        return ""; 
    } 

// I figured out that this next piece has to be completely commented out for things to work

    // override with fake request method for demo purposes 
//    obj.request = function(){ 
//        this.setTimeout(function(){ 
//            this.response("..returned data string.."); 
//        }, 500); 
//    } 

    // callback to process returned data 
    obj.response = function(data){ 

        if (!this._data.length){ 
            this._data = []; 
        } 

        this._min = -1; 
        this._max = -1; 
        this._loading = false; 
   
        // this is here for debug to see what we get back
        alert(data);

       // How to process the XML into the right format?

        // for demo only, should take from the returned data 
        var startIndex = Number(this._startIndexParameter); 
        var rowCount = Number(this._rowCountParameter); 

        window.status = "Loaded rows " + startIndex + "-" + (startIndex+rowCount); 

        var i, j; 

        for (i=startIndex;i<startIndex+rowCount;i++){ 

            this._data[i] = []; 

            for(j=0;j<20;j++){ 
                // for demo only, should take from the returned data 
                this._data[i][j] = i + "." + j; 
            } 
        } 

        if (this.$owner){ 
            this.$owner.setRowCount(1000); //should take from the returned data 
            this.$owner.refresh(); 
        } 
    } 
} 


    var table = new MyTable();

// missing table.setURL ?

    table.setParameter("offset", 0); 
    table.setParameter("limit", 50); 
    table.request(); 

    var obj = new AW.UI.Grid; 

    obj.setColumnCount(10); 
    obj.setCellModel(table); 

    document.write(obj); 

</script> 
</body> 
</html>


The original example did not have a table.setURL.
However, without the table.setURL, my index.php never gets called until I scroll.
So...I put one in that looks like this:

table.setURL("index.php");


Does that mean that I don't need the one further up in the code?

Anyway, now my index.php DOES get called and seems to return valid XML.

However, it seems like it is now stuck in an endless loop - just keeps calling my index.php over and over.

Is it something to do with the table.setParameter("limit", 50); ?

Also, I know I need to take out the example response and put in my real data instead, but I don't know if I need to parse the XML myself or if there is a function that will handle it for me?

If anyone can help, I would be most appreciative.

Thanks,

Jim

Jim Nickel
November 8,
Bump....anyone?
Jim Nickel
November 12,
Nevermind....the problem is because I hadn't yet taken out the sample response code and the startIndexParameter and the rowCountParameter weren't set. Had nothing to do with my PHP or other code.

I still am unsure of the XML parsing though....

Do I need to parse the XML myself and fill this._data[][] ?

Also....what about sorting? Should I assume that I need to replace the onclick events for the headers with calls to the table.request again with new parameters for sorting?

Jim
Jim Nickel
November 13,

This topic is archived.

See also:


Back to support forum