【问题标题】:how to persist current row in jqgrid如何在jqgrid中保留当前行
【发布时间】:2012-01-22 16:12:48
【问题描述】:

如果再次打开网格或刷新页面,如何保留当前行?

Persisting jqGrid column preferences 中的答案描述了如何保持列宽和其他一些参数。

在这个答案演示中,我单击了某行并按了 F5 。上一个单击的行未突出显示。 如何在本地存储中保存/恢复当前行?

更新

如果在应用程序中修改了 jqGrid 列结构并且用户再次从浏览器打开应用程序, restorecolumnstate 在缺少某些元素的情况下创建无效的 colmodel。这会导致 refreshSearchingToolbar 出现异常,该异常假定所有 colmodel 元素都存在。

如何解决这个问题?在这种情况下如何检测修改后的 colmodol 而不是恢复 colmodel ?还是应该 restoreColumnState 更新 colModel 以便创建正确的数组?

**更新 2 **

如果 myColumnsState.permutation 包含空值 $grid.jqGrid("remapColumns", myColumnsState.permutation, true) 创建无效的 colmodel。这是 VS 调试器在 remapColumns 调用之前和之后的屏幕截图

之后:

我通过将代码更改为来解决此问题

    if (isColState && myColumnsState.permutation.length > 0) {
        var i, isnull = false;
        for (i = 0; i < myColumnsState.permutation.length; i = i + 1) {
            if (myColumnsState.permutation[i] == null) {
                isnull = true;
                break;
            }
        }
        if (!isnull) {
            $grid.jqGrid("remapColumns", myColumnsState.permutation, true);
        }

这是最好的解决方案吗?

【问题讨论】:

    标签: jqgrid


    【解决方案1】:

    我将来自the previous answer 的关于持久化jqGrid 列首选项的代码与来自another answer 的代码结合起来,其中我建议了实现行持久选择的代码。值得一提的是,在multiselect:true 的情况下,它将使用包含所有选定行的 ids 数组即使这些行在另一个页面上。它非常实用,实现非常简单。于是我发了对应的feature request,但一直到现在都没有回复。

    现在我可以展示两个演示:the first demo 使用 multiselect: truethe second demo,使用相同的代码,但只有一个选择。

    我使用的代码中最重要的部分将在下面找到。

    有一点非常重要:您应该在您使用的每个页面中修改myColumnStateName 的值。变量的值包含localStorage 中列状态的名称。因此,如果您不会更改名称,您将共享不同表的状态,这可能会产生非常奇怪的效果。您可以考虑使用从当前页面名称或其 URL 构造的名称作为 myColumnStateName 的值。

    var $grid = $("#list"),
        getColumnIndex = function (grid, columnIndex) {
            var cm = grid.jqGrid('getGridParam', 'colModel'), i, l = cm.length;
            for (i = 0; i < l; i++) {
                if ((cm[i].index || cm[i].name) === columnIndex) {
                    return i; // return the colModel index
                }
            }
            return -1;
        },
        refreshSerchingToolbar = function ($grid, myDefaultSearch) {
            var postData = $grid.jqGrid('getGridParam', 'postData'), filters, i, l,
                rules, rule, iCol, cm = $grid.jqGrid('getGridParam', 'colModel'),
                cmi, control, tagName;
    
            for (i = 0, l = cm.length; i < l; i++) {
                control = $("#gs_" + $.jgrid.jqID(cm[i].name));
                if (control.length > 0) {
                    tagName = control[0].tagName.toUpperCase();
                    if (tagName === "SELECT") { // && cmi.stype === "select"
                        control.find("option[value='']")
                            .attr('selected', 'selected');
                    } else if (tagName === "INPUT") {
                        control.val('');
                    }
                }
            }
    
            if (typeof (postData.filters) === "string" &&
                    typeof ($grid[0].ftoolbar) === "boolean" && $grid[0].ftoolbar) {
    
                filters = $.parseJSON(postData.filters);
                if (filters && filters.groupOp === "AND" && typeof (filters.groups) === "undefined") {
                    // only in case of advance searching without grouping we import filters in the
                    // searching toolbar
                    rules = filters.rules;
                    for (i = 0, l = rules.length; i < l; i++) {
                        rule = rules[i];
                        iCol = getColumnIndex($grid, rule.field);
                        if (iCol >= 0) {
                            cmi = cm[iCol];
                            control = $("#gs_" + $.jgrid.jqID(cmi.name));
                            if (control.length > 0 &&
                                    (((typeof (cmi.searchoptions) === "undefined" ||
                                    typeof (cmi.searchoptions.sopt) === "undefined")
                                    && rule.op === myDefaultSearch) ||
                                      (typeof (cmi.searchoptions) === "object" &&
                                          $.isArray(cmi.searchoptions.sopt) &&
                                          cmi.searchoptions.sopt.length > 0 &&
                                          cmi.searchoptions.sopt[0] === rule.op))) {
                                tagName = control[0].tagName.toUpperCase();
                                if (tagName === "SELECT") { // && cmi.stype === "select"
                                    control.find("option[value='" + $.jgrid.jqID(rule.data) + "']")
                                        .attr('selected', 'selected');
                                } else if (tagName === "INPUT") {
                                    control.val(rule.data);
                                }
                            }
                        }
                    }
                }
            }
        },
        saveObjectInLocalStorage = function (storageItemName, object) {
            if (typeof window.localStorage !== 'undefined') {
                window.localStorage.setItem(storageItemName, JSON.stringify(object));
            }
        },
        removeObjectFromLocalStorage = function (storageItemName) {
            if (typeof window.localStorage !== 'undefined') {
                window.localStorage.removeItem(storageItemName);
            }
        },
        getObjectFromLocalStorage = function (storageItemName) {
            if (typeof window.localStorage !== 'undefined') {
                return JSON.parse(window.localStorage.getItem(storageItemName));
            }
        },
        myColumnStateName = 'ColumnChooserAndLocalStorage2.colState',
        idsOfSelectedRows = [],
        saveColumnState = function (perm) {
            var colModel = this.jqGrid('getGridParam', 'colModel'), i, l = colModel.length, colItem, cmName,
                postData = this.jqGrid('getGridParam', 'postData'),
                columnsState = {
                    search: this.jqGrid('getGridParam', 'search'),
                    page: this.jqGrid('getGridParam', 'page'),
                    sortname: this.jqGrid('getGridParam', 'sortname'),
                    sortorder: this.jqGrid('getGridParam', 'sortorder'),
                    permutation: perm,
                    selectedRows: idsOfSelectedRows,
                    colStates: {}
                },
                colStates = columnsState.colStates;
    
            if (typeof (postData.filters) !== 'undefined') {
                columnsState.filters = postData.filters;
            }
    
            for (i = 0; i < l; i++) {
                colItem = colModel[i];
                cmName = colItem.name;
                if (cmName !== 'rn' && cmName !== 'cb' && cmName !== 'subgrid') {
                    colStates[cmName] = {
                        width: colItem.width,
                        hidden: colItem.hidden
                    };
                }
            }
            saveObjectInLocalStorage(myColumnStateName, columnsState);
        },
        myColumnsState,
        isColState,
        restoreColumnState = function (colModel) {
            var colItem, i, l = colModel.length, colStates, cmName,
                columnsState = getObjectFromLocalStorage(myColumnStateName);
    
            if (columnsState) {
                colStates = columnsState.colStates;
                for (i = 0; i < l; i++) {
                    colItem = colModel[i];
                    cmName = colItem.name;
                    if (cmName !== 'rn' && cmName !== 'cb' && cmName !== 'subgrid') {
                        colModel[i] = $.extend(true, {}, colModel[i], colStates[cmName]);
                    }
                }
            }
            return columnsState;
        },
        updateIdsOfSelectedRows = function (id, isSelected) {
            var index = idsOfSelectedRows.indexOf(id);
            if (!isSelected && index >= 0) {
                idsOfSelectedRows.splice(index, 1); // remove id from the list
            } else if (index < 0) {
                idsOfSelectedRows.push(id);
            }
        },
        firstLoad = true;
    
    myColumnsState = restoreColumnState(cm);
    isColState = typeof (myColumnsState) !== 'undefined' && myColumnsState !== null;
    idsOfSelectedRows = isColState && typeof (myColumnsState.selectedRows) !== "undefined" ? myColumnsState.selectedRows : [];
    
    $grid.jqGrid({
        // ... some options
        page: isColState ? myColumnsState.page : 1,
        search: isColState ? myColumnsState.search : false,
        postData: isColState ? { filters: myColumnsState.filters } : {},
        sortname: isColState ? myColumnsState.sortname : 'invdate',
        sortorder: isColState ? myColumnsState.sortorder : 'desc',
        onSelectRow: function (id, isSelected) {
            updateIdsOfSelectedRows(id, isSelected);
            saveColumnState.call($grid, $grid[0].p.remapColumns);
        },
        onSelectAll: function (aRowids, isSelected) {
            var i, count, id;
            for (i = 0, count = aRowids.length; i < count; i++) {
                id = aRowids[i];
                updateIdsOfSelectedRows(id, isSelected);
            }
            saveColumnState.call($grid, $grid[0].p.remapColumns);
        },
        loadComplete: function () {
            var $this = $(this), i, count;
    
            if (firstLoad) {
                firstLoad = false;
                if (isColState) {
                    $this.jqGrid("remapColumns", myColumnsState.permutation, true);
                }
                if (typeof (this.ftoolbar) !== "boolean" || !this.ftoolbar) {
                    // create toolbar if needed
                    $this.jqGrid('filterToolbar',
                        {stringResult: true, searchOnEnter: true, defaultSearch: myDefaultSearch});
                }
            }
            refreshSerchingToolbar($this, myDefaultSearch);
            for (i = 0, count = idsOfSelectedRows.length; i < count; i++) {
                $this.jqGrid('setSelection', idsOfSelectedRows[i], false);
            }
            saveColumnState.call($this, this.p.remapColumns);
        },
        resizeStop: function () {
            saveColumnState.call($grid, $grid[0].p.remapColumns);
        }
    });
    
    $grid.jqGrid('navGrid', '#pager', {edit: false, add: false, del: false});
    $grid.jqGrid('navButtonAdd', '#pager', {
        caption: "",
        buttonicon: "ui-icon-closethick",
        title: "clear saved grid's settings",
        onClickButton: function () {
            removeObjectFromLocalStorage(myColumnStateName);
            window.location.reload();
        }
    });
    

    更新:我忘了提到在 jqGrid 4.3 中使用 multiselect: true 选项时,使用此处描述的 the fix 非常重要。在第一个演示中,我使用了 jquery.jqGrid.src.js 中的 the modified version,其中包含错误修复。

    更新 2:为了方便生成用于保存网格状态的本地存储项的唯一名称,我对演示进行了一些修改。下一版the multiselect demothe single select demo使用myColumnStateName作为函数定义如下

    var myColumnStateName = function (grid) {
            return window.location.pathname + '#' + grid[0].id;
        }
    

    myColumnStateName的用法相应改变。此外,我扩展了列状态以保存 rowNum 值。

    更新 3:The answer 描述如何使用免费 jqGrid 的新可能性来保存网格状态。

    【讨论】:

    • 未应用来自trirand.com/blog/?page_id=393/bugs/… 的关键补丁。每次成功的远程删除都会导致异常。
    • @Andrus:在我发布的演示中,没有删除、添加或编辑操作。怎么试都不会抛出异常。
    • 这是一般性评论,抱歉。如何将此代码重新用于相同和不同页面中的多个网格? jqgrid 可以用这个代码或其他想法扩展或子类化吗?
    • @Andrus:为了减少对如何使用myColumnStateName 的误解,以防页面上有很多网格,我稍微修改了演示。此外,我扩展了列状态以保存 rowNum 值。
    • var cm = $grid.jqGrid('getGridParam', 'colModel')' 替换空检查并检查` && myColumnsState.permutation.length == cm.length` 似乎可以解决这个问题
    【解决方案2】:

    当您像下面这样刷新页面时,Oleg 的解决方案会产生错误。

    错误:未捕获的类型错误:无法读取未定义的属性“el”

    行:jquery.jqGrid.src.js 中的 1936

    var previousSelectedTh = ts.grid.headers[ts.p.lastsort].el, newSelectedTh = ts.grid.headers[idxcol].el;
    

    解决方案是保存 lastsort 网格参数并在加载完成时将其重置,如下所示。

    saveColumnState = function(perm) {
    ...
      columnsState = {
        search: this.jqGrid('getGridParam', 'search'),
        page: this.jqGrid('getGridParam', 'page'),
        sortname: this.jqGrid('getGridParam', 'sortname'),
        sortorder: this.jqGrid('getGridParam', 'sortorder'),
        lastsort: this.jqGrid('getGridParam', 'lastsort'),
        permutation: perm,
        colStates: { }
      },
    ...
    },
    
    loadComplete: function(data) {
    ...
      if (isColState) {
        $this.jqGrid("remapColumns", myColumnsState.permutation, true);
        if(myColumnsState.lastsort > -1)
          $this.jqGrid("setGridParam", { lastsort: myColumnsState.lastsort });
      }
    ...
    },
    

    【讨论】:

    • 刚刚遇到这个问题 - 感谢您为我节省了几个小时的调试时间 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 2018-05-13
    • 2023-03-12
    • 1970-01-01
    • 2019-07-13
    • 1970-01-01
    相关资源
    最近更新 更多