jQuery jqGrid 过滤器工具栏初始默认值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2440417/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 13:31:09  来源:igfitidea点击:

jqGrid Filter Toolbar initial default value

jqueryjqgrid

提问by Paul Creasey

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.

我将 jqGrid 与过滤器工具栏一起使用,我需要为字段之一设置初始默认过滤器值,以便默认情况下仅显示状态为“打开”的行,但用户可以根据需要显示已关闭的行。

At the moment i have a workaround like this

目前我有这样的解决方法

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

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 :(

编辑:更多的研究告诉我这可能是不可能的:(

采纳答案by Justin Ethier

Have you looked at Toolbar Searchingand Add-On Grid Methodsin the jqGrid documentation wiki? It looks like you may be able to use filterToolbarto set a filter, and triggerToolbarto 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.

您是否查看过 jqGrid 文档 wiki 中的工具栏搜索附加网格方法?看起来您可以filterToolbar用来设置过滤器,并triggerToolbar设置过滤器。我自己没有尝试过,但是loadComplete一旦为网格加载了数据,您就可以在.

Does this help?

这有帮助吗?

回答by Mark B

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
  1. 在列模型搜索选项中传递默认值
  2. 阻止默认的表单数据加载过程
  3. 当表准备好时触发过滤器工具栏数据加载

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:

然后添加过滤器工具栏,设置数据类型和url,并触发加载:

  $('#mytable').jqGrid('filterToolbar', {autosearch: true});
  $('#mytable').setGridParam({datatype: 'json', url:'/get_data.php'});
  $('#mytable')[0].triggerToolbar();

回答by Ziege

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

我阅读的所有提示都对我不起作用。所以我尝试了很多,并在jqGrid源代码中做了一些研究。如果您使用beforeRequest事件,则集成“默认值”或“保存的搜索值”功能要容易得多。

I had to solve some problems:

我必须解决一些问题:

  1. Although it's the beforeRequestevent, the search parameters you set there won't be used until you call triggerToolbar.
  2. triggerToolbardoes 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.
  1. 尽管是beforeRequest事件,但您在那里设置的搜索参数在您调用 之前不会使用triggerToolbar
  2. triggerToolbar不仅使用新的搜索参数设置新请求,还会触发表数据的重新加载 - 但前一个请求仍在运行,因此您执行相同的请求两次(均使用新的搜索参数)。
  3. 设置默认值但允许用户清除/覆盖它们。
  4. 避免无限循环并保留旧的搜索功能。

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!

我希望这可以帮助你!

回答by daanl

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.

我以与上面的答案不同的方式修复它,我滥用 beforeRequest 函数将初始默认值添加到发布数据。

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

与jqGrid的创建者有过接触,默认值选项仅用于高级搜索。

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.

我写了一个函数,您可以在 onBeforeRequest 函数上设置该函数,该函数将获取搜索选项中的所有默认值并将其附加到发布数据。所以默认值会被添加到初始请求中。

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).

为了确保您仍然可以使用 onbeforeRequest 事件,我更改了代码末尾的 onBeforeRequest (this.p.beforeRequest = function() {})。您可以将其更改为您想要的任何内容并调用它。下次您发出请求时,将使用该函数并且该函数将被取消(因为覆盖)。

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

希望这可以帮助

回答by C???

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.

通读Ziege 的回答后,我想到了那里发生的事情。我想出了一个更简单的方法来在第一个请求到达服务器之前初始化默认值。

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.Mvclibrary (.NET) which doesn't support the localdatatype.

这也适用于Lib.Web.Mvc不支持local数据类型的库 (.NET) 。

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:

如果您有多个网格,或者想要将 beforeRequest 逻辑移动到一个库中进行共享,只需将其定义为一个独立的函数并在您的网格设置中按名称引用它:

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 });