Forum Replies Created

Viewing 15 posts - 16 through 30 (of 30 total)
  • Author
    Posts

  • TP_DTNA
    Participant

    supun151515, I just implemented a caching solution that intercepts the server calls in the loadServerData callback method. I specify one parameter that is a window size about three times the viewable size, and if the user scrolls close enough to the end of the cache, it asynchronously loads the next chunk of content and has it ready just in time before the user scrolls there. I also have some special provisions to expire the cache explicitly and with a maximum lifetime parameter.

    You are right, by default the server calls are excessive, request redundant data, and create a poor user experience. The approach I just coded and tested works so well that the users only see the loading spinner upon page load, scrolling very far quickly, and filtering and sorting. It creates a cache for each hash of the sort and filter parameters. With the timed expiry, it’s not a giant memory leak. Even without that, it still uses way less memory than we did before when loading the entire data set up front.

    I’m still seeing a little flicker when it renders, but I have an idea to try before giving up on that.

    I’d love to post my code, but I’m not at liberty to do so. The idea is sound and a solution can be had if you’re willing to code it!


    TP_DTNA
    Participant

    Huzzah! That clued me into the exact problem and I was able to fix it. Here’s what was happening:

    The callback argument in loadServerData is a function that takes one argument, an object with ‘records’ as an array of data objects and ‘totalrecords’ as a number of total rows in the data set. My problem was that I was starting the index of the records array at zero. Even though it expects an array of a few dozen values, that array needs to start at an index that matches the recordstartindex value (extracted from the loadServerData’s 1st/serverdata argument)

    Doing that solved my issue perfectly and I am very relieved. It would have saved me a lot of time to read about that in the documentation!

    The other issue, and perhaps this needs its own post, is that my grid data is polluted with members such that I have to reserve these field names and avoid using them: [‘boundindex’, ‘uniqueid’, ‘visibleindex’]. Another one called ‘uid’ is in there, but it doesn’t get overwritten if I provide my own. If I don’t, it appears with the same value as one of the other reserved fields. Not only do I have to avoid using these names as fields in my data, but I also have to strip them out in certain cases. Why did these values need to merge into my data instead of having their own space? The docs don’t seem to mention these either.

    Thanks for your help!


    TP_DTNA
    Participant

    This also seems to happen even when the callback is called synchronously. I’m hoping there’s as easy fix for this, like I’m not connecting some obscure property somewhere.


    TP_DTNA
    Participant

    Nadezhda, unfortunately that callback did not do what I need because I need to prevent the change based on what happens when the change is attempted. For columntypes beside checkbox, I can achieve this by having a cellendedit callback on the column that returns false. But when doing that on a checkbox, it allows the change. How can I prevent the change using cellendedit?

    I’ve slightly modified the example found here below in this post:

    var data = generatedata(50);
     var source = {
         localdata: data,
         datafields: [{
             name: 'quantity',
             type: 'number'
         }, {
             name: 'price',
             type: 'number'
         }],
         datatype: "array"
     };
    
    var isEditable = function (row) {
        var value = $('#jqxgrid').jqxGrid('getcellvalue', row, "quantity");
        if (value < 5)
            return false;
    }
    
     var adapter = new $.jqx.dataAdapter(source);
     $("#jqxgrid").jqxGrid({
         width: 200,
         editable: true,
         theme: 'energyblue',
         source: adapter,
         columns: [{
             text: 'Quantity',
             datafield: 'quantity',
             width: 80,
             cellsalign: 'right'
         }, {
             columntype: 'checkbox',
             text: 'Unit Price',
             datafield: 'price',
             cellsalign: 'right',
             cellsformat: 'c2',
             cellbeginedit: isEditable,
             cellendedit: function() { return false; }
         }]
     });
    

    If you simply comment out the line with “columntype: ‘checkbox’,”, you’ll notice that it prevents changing the column. Not so if it’s a checkbox. How do I prevent the change?


    TP_DTNA
    Participant

    Brilliant! That is exactly the answer I need. Thank you so much for answering so quickly. This helps us a lot.


    TP_DTNA
    Participant

    Nadezhda, there is no mention of the buttonclick callback in either of the links you posted. I only know about this feature from happening upon it in the examples. I’m looking for something similar to bind an event to a checkbox column to act when the checkbox is toggled. How would I go about doing that? Is there a place where these secret callbacks are listed?

    in reply to: Filters the data Filters the data #80822

    TP_DTNA
    Participant

    I was having this exact same problem, and the best solution that works reliably for me is to never change the source property on the grid, such as $(‘#grid’).jqxGrid(‘source’,dataApater); That will internally call updatebounddata() without preserving the sort and filter. This is true even if you are using autoloadstate, in which case it will restore everything *except* sort and filter (like column width, name, order, visibility, paging, etc).

    So that means I’m left with initializing the grid with a known data source the first time I need it, and then using $(grid).jqxGrid(‘updatebounddata’,’sort’,’filter’); This is not especially clear from the documentation: “You can pass ‘filter’ or ‘sort’ as parameter, if the update reason is change in ‘filtering’ or ‘sorting’.” <- I do this every time because the users expect their sorts and filters to stay right where they left them, and there’s no case where I don’t want this.

    I used to initialize the grids separately, then simply call .jqxGrid(‘source’, data) when the user wanted fresh data, and my code was neat and sensible. But the one problem is that will reliably lose my sorts and filters. So now I have to put in extra code to see if it’s being used for the first time or not, then initialize or update depending on which. I think discarding two arbitrary properties of the grid state with autoload is a bug, but I still love the jqWidgets for being extremely useful and helpful for what I need.

    Here’s my post about this: http://www.jqwidgets.com/community/topic/losing-sort-and-filter-with-autoloadstate/


    TP_DTNA
    Participant

    “We also recommend to initialize the grid with source. Then you will not have such a problem.”

    That works for the first time I load a grid (except for the ones that fail silently, WHY!!?). Subsequent updates done this way still lose the sort and filter.

    Is there better way to reload a grid with new data than updating its source property? I’ve seen this pattern used many times in the examples. Should I destroy and create a new grid every time? Stick exclusively to using ‘updatebounddata’? I have my grid initialization separate from the parts that utilize them later, updating the source/dataAdpater upon user input. I’ll need to add more code to check if they’re being used for the first time or not in order to implement these workarounds if that’s what I need to do.

    *moments later*
    I tried coding some extra logic to detect first/later use: initialize grid with an established source on first use, use updatebounddata (with sort and filter) on subsequent use. Other than the problems I’m having getting some grids to initialize (probably my fault, but tough to debug!), this seems to be an effective, if messy, workaround.

    I’d still appreciate a proper fix, but at least I feel a little less stuck now.

    Thanks for pointing me in a useful direction!


    TP_DTNA
    Participant

    Well… that was a fine solution until other grids I hadn’t previously tested start having errors in the _preparecolumngroups and _render methods. It will be nice to get this fixed.


    TP_DTNA
    Participant

    Funny, most of the official answers I see about the autostate features sound like “it doesn’t work very well, don’t use it.” Could save a lot of people some time if it said as much in the documentation along with a list of events to bind to, so that one could implement their own more easily. I’m already using a hack to strip selection state from being saved.

    Instead of waiting for a fix, I simply hacked the jqxgrid.js at the propertyChangedHandler in the ‘source’ case to call updatebounddata() with ‘sort’ and ‘filter’ string arguments to get what I need. If anyone complains, I’ll remind them that we have fancy paid support and that you’re looking into a solution.


    TP_DTNA
    Participant

    Ah, I got the error to reproduce! If you re-run the code after modifying the grid (filters, sorts, column widths), you’ll see that the sort and filters are lost, but the column widths are retained.

    Link: https://www.jseditor.io/?key=grid-loadstate-losing-filter-sort-bug

    JS code:

    
    $(document).ready(function () {
    var gridSource = {
        url: '/jquery-widgets-demo/demos/sampledata/beverages.txt',
        type: 'GET',
      
        datatype: 'json',
    
        datafields: [
            { name: 'calories' },
            { name: 'id' },
            { name: 'name' },
            { name: 'totalfat' },
            { name: 'protein' },
        ],
      
        downloadComplete: function(data, status, jqXHR) {
            return data;
        }
    }
    
    var DA = new $.jqx.dataAdapter(gridSource); 
    
    var gridOptions = {
        autosavestate: true,
        autoloadstate: true,
        columnsresize: true,
        sortable:      true,
        selectionmode: 'singlerow',
        filterable:    true,
        showfilterrow: true,
        
        columns: [
            { text: 'calories', datafield: 'calories' },
            { text: 'id'      , datafield: 'id' },
            { text: 'name'    , datafield: 'name' },
            { text: 'protein' , datafield: 'protein' },
            { text: 'totalfat', datafield: 'totalfat' },
        ]
    }
    // fine here
    $('#theGrid').jqxGrid(gridOptions);
    // I expect grid's sort and filter states to be lost during this
    $('#theGrid').jqxGrid('source', DA);
    });
    

    TP_DTNA
    Participant

    Okay, I found a source of beverages to use, and my example is complete and working, but I’m not reproducing the error in the jsEditor. I’ll keep trying and see what’s different between my example and the real implementation that I can’t paste.


    TP_DTNA
    Participant

    I nearly have an example worked out, but I’m having a hard time finding an accessible json table data source to effectively reproduce this issue. I tried one source I found online, but I’m stuck with http-from-https or “No Access-Control-Allow-Origin header” errors. Is there a convenient URL I can plug in to the dataAdapter’s source to use in the jsEditor that gives json table data? Most of the examples I see on the docs use local data sources, and I want to reproduce my setup to better reproduce the error.

    If I can get that, I’ll have an example for you soon after. Thanks.

    Edit: here is what I have started. I’m discarding the ajax request results entirely and returning hardcoded table data in the downloadComplete function. But the grid is showing “No data to display.” I don’t see what I’m missing. I have the grid parameters, the data source, the data adapter connecting to the source, and the grid connecting to the data adapter. I’m not even able to demo the bug I’m trying to show yet because I’m not getting this to work either. https://www.jseditor.io/?key=grid-loadstate-losing-filter-sort-bug


    TP_DTNA
    Participant

    I had a similar problem that was due to my using the same DOM id’s on different pages on the same server. Because the autosave/load feature stores keys using those names, I was having a conflict that was messing with my column orders. Would be nice to have a fix for that instead of the usual “save and load the state non-automatically” answer.


    TP_DTNA
    Participant

    Is it a solution to just implement a custom aggregate function, one that ignores rows you don’t want in the average?

    There’s a aggregate property in the column definition, looks like:

    aggregates: [‘count’, {
    ‘Cappuccino Items’: function (aggregatedValue, currentValue) {
    if (currentValue == “Cappuccino”) {
    return aggregatedValue + 1;
    }
    return aggregatedValue;
    }
    }]

    example seen here: http://jsfiddle.net/jqwidgets/3y7RN/

Viewing 15 posts - 16 through 30 (of 30 total)