jqGrid Filter Toolbar initial default value
Asked Answered
C

5

12

I'm using jqGrid with the filter toolbar, i need to set an initial default filter value to one of the fields so that only rows with status 'Open' are displayed by default, but the user can display Closed rows if desired.

At the moment i have a workaround like this

setTimeout(function() {$('#gs_Status').val('Open');$("#eventsGrid")[0].triggerToolbar()},500);

but it results in a second request and is pretty bad really.

Does anybody know how to do this?

Edit: A bit more research tells me this is probably impossible :(

Colossal answered 13/3, 2010 at 23:10 Comment(0)
D
1

Have you looked at Toolbar Searching and Add-On Grid Methods in the jqGrid documentation wiki? It looks like you may be able to use filterToolbar to set a filter, and triggerToolbar to set the filter. I have not tried this myself, but you could probably do this in loadComplete, once data has been loaded for the grid.

Does this help?

Densimeter answered 14/3, 2010 at 15:30 Comment(0)
D
38

There are a few steps to do this:

  1. pass a default value in the column model search options
  2. prevent the default form data load process
  3. trigger a filter toolbar data load when the table is ready

In a bit more detail:

Set the grid datatype to local (this prevents the initial data load) and set the default value for the search options:

  $("#mytable").jqGrid({
    datatype: "local",
    colNames:['Keyword','Selected'], 
    colModel:[
     {name:'keyword',
      sortable:true,
      searchoptions: { defaultValue:'golf' }
    },
    {name:'selected',
      sortable:false,
      searchoptions: { }
    },
    ....
    ....

Then add the filter toolbar, set the data type and url, and trigger the load:

  $('#mytable').jqGrid('filterToolbar', {autosearch: true});
  $('#mytable').setGridParam({datatype: 'json', url:'/get_data.php'});
  $('#mytable')[0].triggerToolbar();
Dickey answered 2/7, 2010 at 12:11 Comment(2)
This is what I'd like to do, but it doesnt work unless I wrap the triggerToolbar call in a setTimeout like the way he's doing in the original question :(Lund
@Lund thanks so much for your comment, i also needed the setTimeout for this. this solution is working quite good - the short flickering at the first load when the filtered data is rendered is a bit irritating tho.Colophon
D
3

All the tips I read didn't work for me. So I tried a lot and did some research in the jqGrid source code. It's much easier to integrate a "default value" or "saved search values" functionality, if you use the beforeRequest event.

I had to solve some problems:

  1. Although it's the beforeRequest event, the search parameters you set there won't be used until you call triggerToolbar.
  2. triggerToolbar does not only set the new request with the new search parameters, but also triggers a reload of the table data - but the previous request is still running, so you do the same request twice (both with the new search parameters).
  3. Set default values but allow the user to clear/overwrite them.
  4. Avoid endless loops and keep the old search functionality.

Here's the code:

beforeRequest: function ()
{
    // Activate filter toolbar and define "beforeSearch" callback
    // to avoid a second search request on page load, triggered 
    // by "triggerToolbar()" when not set.
    //
    // Important: 
    // "beforeSearch" has to return true to avoid the second
    // request on page load, but it has to return false for all
    // following searches (otherwise it wouldn't be possible to
    // submit new searches by pressing Enter in search input fields).
    $("#myTable").jqGrid('filterToolbar', {
        beforeSearch: function(){
            if ($(this).data('firstSearchAbortedFlag') != '1')
            {
                $(this).data('firstSearchAbortedFlag', '1');
                return true;
            }

            // Return false or add your customizations here...
            return false;
        }
    });

    if ($(this).data('defaultValuesSetFlag') != '1')
    {
        // Set flag to set default only the first time when
        // the page is loaded.
        $(this).data('defaultValuesSetFlag', '1');

        // Set default values...
        // (id = 'gs_' + fieldname)
        $('#gs_field_a').val('value a');
        $('#gs_field_b').val('value b');

        // Call "triggerToolbar" to use the previously set
        // parameters for the current search.
        // 
        // Important: 
        // Set "beforeSearch" callback for "filterToolbar" to avoid
        // a second search request, triggered by "triggerToolbar".
        $("#myTable")[0].triggerToolbar();
    }
}

I hope this helps you!

Decoder answered 10/5, 2011 at 7:7 Comment(0)
D
1

Have you looked at Toolbar Searching and Add-On Grid Methods in the jqGrid documentation wiki? It looks like you may be able to use filterToolbar to set a filter, and triggerToolbar to set the filter. I have not tried this myself, but you could probably do this in loadComplete, once data has been loaded for the grid.

Does this help?

Densimeter answered 14/3, 2010 at 15:30 Comment(0)
R
1

I fixed it in different way then the answers above, im abusing the beforeRequest function to add initial de default values to the post data.

Had contact with the creator of jqGrid, the default value option is only for advanced searching.

I Wrote an function that you can set on the onBeforeRequest function that function will grab all default values in search options and append it to the post data. So the default value will be added in the initial request.

To ensure you still can use the onbeforeRequest event I`m change the onBeforeRequest in the end of the code (this.p.beforeRequest = function() {}). You can change it into what ever you want and call it. The next time you'll do an request that function will be used and this function will be dismissed (because of overriding).

function() {

    var defaultSearchOptions = [];
    var colModel = this.p.colModel;

    // loop trough each column and check if they have an default value in search options
    // and add them to the array
    $.each(colModel, function (index, column) {

        if (column.hasOwnProperty('searchoptions')) {

            var searchOptions = column.searchoptions;

            if (searchOptions.hasOwnProperty('defaultValue')) {

                defaultSearchOptions[defaultSearchOptions.length++] =
                {
                    ""field"": column.index,
                    ""op"": ""bw"",
                    ""data"": searchOptions.defaultValue
                };
            }
        }
    });


    // if there are any default search options retrieve the post data
    if (defaultSearchOptions.length > 0) {

        var postData = this.p.postData;

        var filters = {};

        // check if post data already has filters
        if (postData.hasOwnProperty('filters')) {
            filters = JSON.parse(postData.filters);
        }

        var rules = [];

        // check if filtes already has rules
        if (filters.hasOwnProperty('rules')) {
            rules = filters.rules;
        }

        // loop trough each default search option and add the search option if the filter rule doesnt exists
        $.each(defaultSearchOptions, function (defaultSearchOptionindex, defaultSearchOption) {

            var ruleExists = false;

            $.each(rules, function (index, rule) {

                if (defaultSearchOption.field == rule.field) {
                    ruleExists = true;
                    return;
                }
            });

            if (ruleExists == false) {
                rules.push(defaultSearchOption);
            }
        });

        filters.groupOp = 'AND';
        filters.rules = rules;

        // set search = true
        postData._search = true;
        postData.filters = JSON.stringify(filters);
    }

    this.p.beforeRequest = function() { // your before request function here };
    this.p.beforeRequest.call(this);
}

Hope this helps

Rib answered 6/3, 2012 at 10:2 Comment(0)
Q
0

After reading through Ziege's answer, I thought about what was happening there. I came up with a much simpler way to get default values initialized before the first request goes to the server.

Here's a full working example. The idea is that there is a column filter with a drop-down of statuses, "Active" and "Closed", where I want the default to be "Active". The code has comments to explain what's happening:

$('#deals').jqGrid({
    colNames: ['...','Status','...'],
    colModel: [
        { ... },
        // Use the defaultValue attribute to set your defaults in the searchOptions object
        { name: 'Status', stype: 'select', searchoptions: { defaultValue: 'Active', value: {"":"All","Active":"Active","Closed":"Closed",}, sopt: [ 'eq'] }, width: 60 },
        { ... }
    ],
    // Here's where we intercept each server request to cancel it if it's the first one. 
    // Returning false from this method causes the request to the server to be aborted.
    beforeRequest: function () {
        // Define a local reference to the grid
        var $requestGrid = $(this);
        // Check a data value for whether we've completed the setup. 
        // This should only resolve to true once, on the first run.
        if ($requestGrid.data('areFiltersDefaulted') !== true) {
            // Flip the status so this part never runs again
            $requestGrid.data('areFiltersDefaulted', true);
            // After a short timeout (after this function returns false!), now
            // you can trigger the search
            setTimeout(function () { $requestGrid[0].triggerToolbar(); }, 50);
            // Abort the first request
            return false;
        }
        // Subsequent runs are always allowed
        return true;
    },
    url: 'Url/to/your/action',
    datatype: 'json',
    mtype: 'POST',
    pager: '#deals-pager',
    rowNum: 15,
    sortname: 'Status',
    sortorder: 'desc',
    viewrecords: true,
    height: '100%'
}).jqGrid('filterToolbar', { stringResult: true });

This also works with Lib.Web.Mvc library (.NET) which doesn't support the local datatype.

If you have multiple grids, or want to move the beforeRequest logic to a library for sharing, simply define it as a standalone function and reference it by name in your grid setup:

function jqGridFilterSetupRequestHandler = function () {
    var $requestGrid = $(this);
    if ($requestGrid.data('areFiltersDefaulted') !== true) {
        $requestGrid.data('areFiltersDefaulted', true);
        setTimeout(function () { $requestGrid[0].triggerToolbar(); }, 50);
        return false;
    }
    return true;
}

$('#deals').jqGrid({
    colNames: ['...','Status','...'],
    colModel: [
        { ... },
        // Use the defaultValue attribute to set your defaults in the searchOptions object
        { name: 'Status', stype: 'select', searchoptions: { defaultValue: 'Active', value: {"":"All","Active":"Active","Closed":"Closed",}, sopt: [ 'eq'] }, width: 60 },
        { ... }
    ],
    beforeRequest: jqGridFilterSetupRequestHandler,
    url: 'Url/to/your/action',
    datatype: 'json',
    mtype: 'POST',
    pager: '#deals-pager',
    rowNum: 15,
    sortname: 'Status',
    sortorder: 'desc',
    viewrecords: true,
    height: '100%'
}).jqGrid('filterToolbar', { stringResult: true });
Quinate answered 2/2, 2017 at 3:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.