How to reload JQuery grid keeping scroll position and collapse elements open
Asked Answered
K

4

7

I'm currently working with JQuery plugin for struts2. I would like to know how to reload a JQuery grid without loosing the current scroll position and collapse rows.

In order to reload the data in the grid I'm using the following javascript code:

var timerID = setInterval("RefreshGridData()", 5000);
function RefreshGridData() {
    $("#griditems").trigger("reloadGrid");
}

The jsp of the grid is the following:

<s:url id="itemsurl" action="getItemsJson.action" />
<s:url id="subitemsurl" action="getSubItemsJson.action" />
<sjg:grid id="griditems" caption="Items and Subitems" dataType="json"
    href="%{itemsurl}" pager="false" viewrecords="true" height="400"
    gridModel="gridModel" rowNum="-1" sortable="true">

    <sjg:grid id="gridsubitems" subGridUrl="%{subitemsurl}"
        gridModel="gridModel" rowNum="-1">
        <sjg:gridColumn name="subcol1" index="subcol1" title="SubColumn 1"
            width="120" />
        <sjg:gridColumn name="subcol2" index="subcol2" title="SubColumn 2"
            align="left" width="120" />
    </sjg:grid>

    <sjg:gridColumn name="col1" index="col1" title="Column 1" sortable="true"
        width="80"/>
    <sjg:gridColumn name="col2" index="col2"
        title="Column 2" sortable="true" />
    <sjg:gridColumn name="col3" index="col3" title="Column 3"
        sortable="true" />
</sjg:grid>

Any comments on how to implement this are welcome.

Thanks in advance.

Karlmarxstadt answered 18/4, 2011 at 17:42 Comment(2)
You should include more information about the jqGrid which you try to reload.Elderberry
Thanks for the suggestion Oleg, I just added the code of the grid.Karlmarxstadt
A
9
var scrollPosition = 0

function RefreshGridData() {
    scrollPosition = jQuery("#griditems").closest(".ui-jqgrid-bdiv").scrollTop()
    $("#griditems").trigger("reloadGrid");
}

after data is loaded in event loadComplete

jQuery("#griditems").closest(".ui-jqgrid-bdiv").scrollTop(scrollPosition)

EDIT :

var ids = new Array();


jQuery("#jqgrid_id").jqGrid({
...
   gridComplete: function(){ 
      var rowIds = $("#jqgrid_id").getDataIDs();
      $.each(ids, function (index, data) {
        if (data == 1){
           $("#jqgrid_id").expandSubGridRow(rowId); 
        }
      });
   },
   subGridRowExpanded: function(pID, id){ 
      ids[id] = 1;
   },
   subGridRowColapsed: function(pID, id){ 
      ids[id] = 0;
   },

...
});

not sure if this will work i didn't test it tut it should be something like that

EDIT

setGridParam - not suire if it will work on events but you might try that

i couldn't find how to attach subGridRowExpanded topick using tag library in struts but try changing config after grid is constructed by taglibrary

$("#griditems").setGridParam({subGridRowExpanded: function(pID, id){ ids[id] = 1;}});
$("#griditems").setGridParam({subGridRowColapsed: function(pID, id){ ids[id] = 0;}});
$("#griditems").setGridParam({gridComplete: function(){ 
      var rowIds = $("#jqgrid_id").getDataIDs();
      $.each(ids, function (index, data) {
        if (data == 1){
           $("#jqgrid_id").expandSubGridRow(rowId); 
        }
      });
   }});

EDIT

ok different aproach :

var scrollPosition = 0
var ids = new Array();

function RefreshGridData() {
        ids = new Array();
        $('tr:has(.sgexpanded)').each(function(){ids.push($(this).attr('id'))});
        scrollPosition = jQuery("#griditems").closest(".ui-jqgrid-bdiv").scrollTop()
        $("#griditems").trigger("reloadGrid");
    }

and when load of grid is complete :

jQuery.each(ids, function (id,data) {
           $("#jqgrid_id").expandSubGridRow(data);
           jQuery("#griditems").closest(".ui-jqgrid-bdiv").scrollTop(scrollPosition);
      });
Almsman answered 19/4, 2011 at 11:55 Comment(11)
Thanks for your answer firegnom. Your answer was helpful to save the scroll position of the JQuery grid. However, I still have the problem that the expanded subitems in the subgrid get collapsed everytime the grid is reloaded. Any ideas?Karlmarxstadt
only idea is very nasy connect to events subGridRowExpanded and subGridRowColapsed they give id write those id's to array and using function $("#jqgrid_id").expandSubGridRow(rowId); expand all onloadAlmsman
Thanks again for your answer firegnom. I think this solution should work, however, I haven't found which events are fired when a subgrid row is expanded/collapsed. Do you know this already?Karlmarxstadt
firegnom. I see that the fired events are subGridRowExpanded and subGridRowCollapsed as you indicated. However, even though I subscribed to listen to those events, the function is never reached. $.subscribe('subGridRowExpanded', function(pID, id) { $("#testp").html("Received!"); });Karlmarxstadt
as far as i know you don't subscribe to those events you need to add them during construction of jqgrid like shown in example i gave above.Almsman
ok i now see your problem struts2 taglib is limited but try adding event after using setGridParam not sure if it will work thoughAlmsman
I tried to set the grid parameters after construction as you mentioned. Unfortunatelly though, this is not working with jquery tags plugin. What seems to me is that the publish/subscribe framework used in struts2 does not support the subGridRowExpanded/Collapsed topics. I'll have to try to implement this differently.Karlmarxstadt
ok different approach : $('tr:has(.sgexpanded)') will give you all expanded rows look last editAlmsman
@Almsman : using the code shown at the end of this comment, it's possible to set the function which is triggered on subGridRowExpanded event. However, it seems that when setting a function it just overwrites the original functionality of the 'plus' sign since after setting a new function my functionality is executed but the subgrid is not actually being expanded. <br/> jQuery("#testgrid").jqGrid('setGridParam', {subGridRowExpanded: function(pID, id){$("#test_p").html("Row id: " + id);}});Karlmarxstadt
@firegnom: I'll try to implement your new suggestionKarlmarxstadt
@Karlmarxstadt yep struts2 taglig is connecting to subGridRowExpanded and by changing it you will lose its functionality :( linkto source : code.google.com/p/struts2-jquery/source/browse/branches/3.0.0/…Almsman
K
0

I finally solved my problem. Thanks to the useful information provided by firegnom in his answer and comments I got a big push forward to create an implementation of a jQuery grid (with subgrid), using Struts2 tags, which keeps its previous scroll position and expanded/collapsed state after reloading it.

JavaScript

var scrollPosition = 0;
    var ids;
    var timerID = setInterval("RefreshGridData()", 5000);



function RefreshGridData() {
    var num;
    ids = new Array();  
    scrollPosition = jQuery("#testgrid").closest(".ui-jqgrid-bdiv").scrollTop();            
    jQuery("#testgrid tr:has(.sgexpanded)").each(function(){
        num = $(this).attr('id');
        if (isDigit(num)) {         
            ids.push(num);
        }
    }); 
    $("#testgrid").trigger("reloadGrid");           
}               

function isDigit(num) {         
    if (num.length > 1){return false;}                                  
    if (num > 0 && num < 20) {return true;}     
    return false;
}


$(document).ready(function () {         
$.subscribe('testgridReloded', function(event, element) {   
    var i;
    for (i = 0; i < ids.length; i = i+1) {                  
        $("#testgrid").jqGrid('expandSubGridRow', ids[i]);
    }    



    var t = setTimeout("setScrollPos()", 300);
    });
}); 



function setScrollPos() {
    jQuery("#testgrid").closest(".ui-jqgrid-bdiv").scrollTop(scrollPosition);
}

I used the isDigit function because the first element found with class sgexpanded is always 0 and that is not a valid row number in a grid since rows start counting from 1. Another observation is that I set a timer before calling the setScrollPos function because my grid doesn't have a scroll bar before a certain number of rows are expanded, and since the expanding effect is not immediate, it's necessary to set the scroll position after a certain time.

Grid tags code

<s:url id="gridurl" action="getJsonGridData.action" />

<sjg:grid id="testsubgrid" subGridUrl="%{subgridurl}"
    gridModel="gridModel" rowNum="-1" >
    <sjg:gridColumn name="sub1" index="sub1" title="Sub Col 1"
        width="80" />
    <sjg:gridColumn name="sub2" index="sub2" title="Sub Col 2"
        align="left" width="80" />
</sjg:grid>

<sjg:gridColumn name="col1" index="col1" title="Grid Col 1" sortable="true" width="120" />
<sjg:gridColumn name="col2" index="col2" title="Grid Col 2" width="120" />
<sjg:gridColumn name="col3" index="col3" title="Grid Col 3 width="120" />
</sjg:grid>

Hope it helps somebody.

Cheers.

Karlmarxstadt answered 21/4, 2011 at 14:42 Comment(2)
Not nice mate you have just taken my ideas , formated code nicely and posted as Your own answer not nice !!!Almsman
@firegnom: You're right, I used your ideas to find a proper solution to my problem. I though it would be useful to have everything summarized in one correct answer. Anyway, I really don't mind about being the owner of the answer. Now I gave the answer to you. Thanks again for your support.Karlmarxstadt
C
0

To load the page in-place (which keeps curent scroll position) simply use:

$("#mygrid").trigger("reloadGrid",[{current:true}]);
Comport answered 15/10, 2014 at 20:47 Comment(0)
U
0

I've solve the problem by adding this

var offset = $("#" + *subgrid_table_id*).offset();
var w = $(window);
var fromTop = offset.top - w.scrollTop();
$('html, body').animate({
    scrollTop: offset.top - fromTop
}, 1);

this code keep the last position of grid

Uniform answered 12/4, 2016 at 3:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.