سؤال

In the app I'm building, I have a data grid and some select boxes where the user can set filters and upon a selection it makes an AJAX call to get a new array of data from the server.

I have the grid initializing with default filters, but I can't figure out how to wipe the grid of all rows, and re-populate with a fresh array. I was trying dataView, but after reading some posts this seems to not be the answer. I find the official example-6 (ajax example) confusing.

I would like column sorting and column re-ordering to be retained when new data is loaded.

Here is the js I currently have which only initializes properly:

$(function(){

    //update the grid when select values change
    $('#qol_options :input').change(function(){
        update_grid_data();
    });


    init_grid = function(){

        // set grid options 
        var grid;
        var columns = [
            {id: "village", name: "Village", field: "village", sortable: true},
            {id: "setting", name: "Setting", field: "setting", sortable: true},
            {id: "hood", name: "N.hood", field: "hood", sortable: true},
            {id: "timespan", name: "Time", field: "timespan", sortable: true},
            {id: "count_0", name: "0", field: "count_0", sortable: true, width: 10},
            {id: "count_1", name: "1", field: "count_1", sortable: true, width: 10},
            {id: "count_2", name: "2", field: "count_2", sortable: true, width: 10},
            {id: "count_3", name: "3", field: "count_3", sortable: true, width: 10},
            {id: "count_4", name: "4", field: "count_4", sortable: true, width: 10},
            {id: "count_6", name: "6", field: "count_6", sortable: true, width: 10},
            {id: "count_7", name: "7", field: "count_7", sortable: true, width: 10},
            {id: "count_8", name: "8", field: "count_8", sortable: true, width: 10},
            {id: "count_total", name: "Total", field: "count_total", sortable: true},
            {id: "pos_perc", name: "%", field: "pos_perc", sortable: true},
            {id: "decile", name: "Decile", field: "decile", sortable: true},
        ];

        var options = {
            enableCellNavigation: true,
            enableColumnReorder: true,
            multiColumnSort: true
        };

        //get default grid data (all)
        var grid_data = [{'village':0, 'setting':0, 'hood':0, 'timespan':0, 'count_0':0, 'count_1':0, 'count_2':0, 'count_3':0, 'count_4':0, 'count_6':0, 'count_7':0, 'count_8':0, 'count_total':0, 'pos_perc':0, 'decile':0}]; 

        //create the grid instance
        this_grid = new Slick.Grid("#data_table_container", grid_data, columns, options);

        update_grid_data();
    }


    update_grid_data = function(){
        var settingID = $('#settingID').val();
        var villageID = $('#villageID').val();
        var hoodID = $('#hoodID').val();

        //init the grid
        $.ajax({
            type: "POST",
            url: '<cfoutput>#APPLICATION.site_prefix#</cfoutput>/_global/ajax/ajax_handlers.cfm',
            data: {'action': 'get_qol_report_data', 'villageID': villageID, 'settingID': settingID, 'hoodID': hoodID, 'itemID': 0, 'categoryID': 0},
            dataType: 'json',

            success: function(data) {
                push_data_to_grid(data);
            }
        });
    }


    push_data_to_grid = function(data){
        this_grid.setData(data);
        this_grid.render();
    }

    //execute the grid init 
    init_grid();
});
هل كانت مفيدة؟

المحلول

I've faced the same problem. Please, try the below code.

function updateGridView(){
  data_view.beginUpdate();
  data_view.setItems(update_data);
  data_view.endUpdate();
  data_view.refresh();
  grid.invalidate();
}
function grid_refresh(){
$.ajax("<cfoutput>#APPLICATION.site_prefix#</cfoutput>/_global/ajax/ajax_handlers.cfm",{
  dataType : "json",
  complete: function(xhr){
      update_data = eval(xhr.responseText);
      updateGridView();
  }
})
}

Just call the grid_refresh() function.

نصائح أخرى

I implemented something like this myself and here is how I have done it. I do use the dataview which will be wiped out every times and also the grid object which will be overwritten. I am not using your code, but instead I will show you the template which I use, I actually call the same function for loading & reloading but just make sure to empty() out the grid before you reload, see 1st line of code:

<div id="myGrid" style="width:100%;height:680px;"></div>

Then I made myself a button with an onclick event that looks something like this onclick=populateMyGrid() as a refresh button (it's actually a reload icon to make it nicer) and that event will call my function to reload the data through the $.getJSON() jQuery function, see the following code:

// Display some Market Indexes on a bar on top of the Grid 
function populateMyGrid() {
    // empty out the Grid before refreshing the data
    $('#myGrid').empty();

    // columns & options definition....
    columns = [ 
        { id: "village", ............
    ];
    options = {
       enableCellNavigation: true,              
        editable: true,
        ............
    };

    ajaxURL = 'myPhpAjaxFileToPullData.php?action=getdata';

    $.getJSON(ajaxURL, function (ServerResponse) {
        dataView = new Slick.Data.DataView();
        grid = new Slick.Grid('#myGrid', dataView, columns, options);
        ............

        // initialize the model after all the events have been hooked up
        dataView.beginUpdate();
        dataView.setItems(ServerResponse.data);
        dataView.endUpdate();

        // Refresh the data render, if user only clicked on the refresh button instead of refreshing the whole page from browser 
        grid.updateRowCount();
        grid.render();
    }); // end of getJSON        
} // end of populateMyGrid

From this code, the important part of it is to empty out the grid at first and then the last 2 rows of code for refreshing your grid with new data and make sure to re-render at last. That is the way I have it working, works like a charm...oh and I also display a text showing last refresh date+time, so it's more obvious to the user of how old the data is!

Even though it's not your code sample, you should get the idea...hope it helps :)

Also if you want to repopulate the grid with some kind of filtering you send the filtering via the ajaxURL of the $.getJSON or you could also replace it with a $.post and send it via the data property as your started, if you do it that way then move all your code into the success function (or a function call). Here is a possible solution for replacing the $.getJSON call... but please note that I did not try it but it should work:

//init the grid
$.ajax({
    type: "POST",
    url: '<cfoutput>#APPLICATION.site_prefix#</cfoutput>/_global/ajax/ajax_handlers.cfm',
    data: {'action': 'get_qol_report_data', 'villageID': villageID, 'settingID': settingID, 'hoodID': hoodID, 'itemID': 0, 'categoryID': 0},
    dataType: 'json',
    success : getData
});

function getData() {
    dataView = new Slick.Data.DataView();
    grid = new Slick.Grid('#myGrid', dataView, columns, options);
    ............

    // initialize the model after all the events have been hooked up
    dataView.beginUpdate();
    dataView.setItems(ServerResponse.data);
    dataView.endUpdate();

    // Refresh the data render, if user only clicked on the refresh button instead of refreshing the whole page from browser 
    grid.updateRowCount();
    grid.render();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top