Как заменить remapColums на remapColumnsByName в бесплатном jqgrid - javascript


1

Код из ответа в как сохранить текущую строку в jqgrid

используется для сохранения состояния jqgrid. Он сохраняет состояние столбца jqgrid с использованием номеров столбцов. Если jqgrid colmodel изменен на сервере, это вызывает ошибку JavaScript в браузере.

Столбец rownum в JQGrid комментарий и https://github.com/free-jqgrid/jqGrid/blob/master/README49.md описывает метод remapColumnsByName. Я надеялся, что использование этого исправляет issUe.

бесплатный jqgrid был загружен из сегодняшнего git мастера. В состоянии сохранения после изменения размеров столбцов или перемещения строки

saveColumnState.call($grid, $grid[0].p.remapColumns);

был изменен на

saveColumnState.call($grid, $grid[0].p.remapColumnsByName);

и в состоянии восстановления в loadComplete code

    if (isColState && myColumnsState.permutation.length > 0 &&
                      myColumnsState.permutation.length === cm.length) {
        $grid.jqGrid("remapColumns", myColumnsState.permutation, true);

    }

с

    if (isColState && myColumnsState.permutation.length > 0 &&
                      myColumnsState.permutation.length === cm.length) {
        $grid.jqGrid("remapColumnsByName", myColumnsState.permutation, true);
    }

Теперь строка

 if (isColState && myColumnsState.permutation.length > 0 &&

вызывает ошибку

Uncaught TypeError: Cannot read property length of undefined

Как исправить это, чтобы состояние столбца могло использоваться, если изменение столбца было изменено?

Методы определяются как

var 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),
            rowNum: this.jqGrid(getGridParam, rowNum),
            sortname: this.jqGrid(getGridParam, sortname),
            sortorder: this.jqGrid(getGridParam, sortorder),
            autoedit: autoedit,
            rownumbers: $grid.jqGrid(getGridParam, rownumbers) && !$grid[0].p.colModel[0].hidden,

            searchWindow: searchParams,
            editWindow: editParams,
            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);
};

var saveObjectInLocalStorage = function (storageItemName, object) {
    if (typeof window.localStorage !== undefined) {
        window.localStorage.setItem(storageItemName, JSON.stringify(object));
    }
};
  •  9
  •  1
  • 8 фев 2020 2020-02-08 08:05:22

1 ответ

2

Прежде всего, я хочу упомянуть, что код, описанный в старом ответе, работает не всегда правильно. Чтобы объяснить проблему, вы можете открыть отдельную демонстрационную серию и использовать перебор столбцов несколько раз до перезагрузки сетки, Например, вы можете сначала открыть редактор столбцов и изменить позицию столбца "Клиенты" после столбца "Налоговый". Вы увидите правильные результаты в сетке. Затем вы можете открыть редактор столбцов еще раз и переместить столбец "Дата" после столбца "Клиенты", например. Вы увидите столбцы в порядке "Сумма", "Налог", "Клиент", "Дата" ,... Теперь вы можете перезагрузить страницу. Вы увидите, что перезагруженная страница имеет неправильный порядок столбцов: "Клиент", "Сумма", "Налог", "Дата" ,... Причина проблемы: permutation, используемая выбором столбца или remapColumns использует целочисленное положение столбцов относительно текущего порядка столбцов. Это делает сохранение порядка столбцов более сложным. Нужно придерживаться порядка оригинального столбца и всегда пересчитывать значения из массива permutation для переупорядочения оригинала colModel.

В качестве альтернативы можно сохранить имена столбцов вместо массивов с измененной позицией столбца относительно исходной модели столбца. Другими словами, следует заменить permutation свойство columnsState на нечто вроде cmOrder с массивом имен столбцов в сетке, которое в последний раз выбрало пользователя.

Метод remapColumnsByName очень прост. Он работает как метод remapColumns, но его первым параметром является массив имен столбцов вместо массива целых индексов.

Демонстрация - это быстрое и грязное изменение демонстрации одной строки, чтобы использовать свойство cmOrder вместо свойства permutation в columnsState и дополнительно использовать метод remapColumnsByName. Если вы повторите тот же тест, как я описал в начале моего ответа, вы увидите, что в новой демонстрации нет ошибки, о которой я говорил ранее.

Самые важные части демо, которые отличаются от оригинальной демонстрации, вы найдете ниже:

var getColumnNamesFromColModel = function () {
        var colModel = this.jqGrid("getGridParam", "colModel");
        return $.map(colModel, function (cm, iCol) {
            // we remove "rn", "cb", "subgrid" columns to hold the column information 
            // independent from other jqGrid parameters
            return $.inArray(cm.name, ["rn", "cb", "subgrid"]) >= 0 ? null : cm.name;
        });
    },
    saveColumnState = function () {
        var p = this.jqGrid("getGridParam"), colModel = p.colModel, i, l = colModel.length, colItem, cmName,
            postData = p.postData,
            columnsState = {
                search: p.search,
                page: p.page,
                rowNum: p.rowNum,
                sortname: p.sortname,
                sortorder: p.sortorder,
                cmOrder: getColumnNamesFromColModel.call(this),
                selectedRows: idsOfSelectedRows,
                colStates: {}
            },
            colStates = columnsState.colStates;

        if (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(this), columnsState);
    },
    ...

кроме того, обратный вызов loadComplete, который восстанавливает порядок столбцов, следующий

loadComplete: function () {
    var $this = $(this), p = $this.jqGrid("getGridParam"), i, count;

    if (firstLoad) {
        firstLoad = false;
        if (isColState && myColumnsState.cmOrder != null && myColumnsState.cmOrder.length > 0) {
            // We compares the values from myColumnsState.cmOrder array
            // with the current names of colModel and remove wrong names. It could be
            // required if the column model are changed and the values from the saved stated
            // not corresponds to the 
            var fixedOrder = $.map(myColumnsState.cmOrder, function (name) {
                    return p.iColByName[name] === undefined ? null : name;
                });
            $this.jqGrid("remapColumnsByName", fixedOrder, 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);
},

Я хочу повторить, что код из новой демонстрации далеко не идеальный. Я просто использовал старый код и исправил его, чтобы он работал в бесплатном jqGrid и с помощью нового метода remapColumnsByName.

  • 8 фев 2020 2020-02-08 08:05:23