Сохранение настроек столбца jqGrid - PullRequest
27 голосов
/ 08 декабря 2011

В моем приложении ASP.NET MVC 3 есть несколько jqGrids с несколькими столбцами. Я добавил следующее в определения столбцов, чтобы некоторые столбцы по умолчанию были скрыты:

colModel: [
   { name: 'IceCreamID', hidden: true},
   { name: 'RecipeID', hidden: true }

и это прекрасно работает. Эти столбцы не отображаются в моей сетке.

Затем я добавил это для реализации средства выбора столбцов:

var grid = $('#icecreamGrid');
grid.jqGrid('navButtonAdd', '#icecreamPager',
{ caption: "Columns", buttonicon: "ui-icon-calculator",
  title: "Choose Columns",
  onClickButton: function() {
     grid.jqGrid('columnChooser');
  }
});

Отлично, теперь выбирает колонку. Затем я добавил следующее в столбцы, которые я никогда не хотел показывать в окне выбора столбцов:

colModel: [
   { name: 'IceCreamID', hidden: true, hidedlg: true},

Так что теперь я могу нормально скрывать / показывать столбцы. Теперь, как бы вы сохранили эту информацию? DB? Как печенье? Другой путь? Есть ли предпочтительный способ хранения информации такого рода, которая на самом деле является предпочтением пользователя, а не связана с самими данными?


Подробнее

Основываясь на комментариях Олега ниже, я хочу предоставить немного больше информации.

Дело в том, что у меня есть сетки с 10-15 столбцами, которые могут отображаться в зависимости от предпочтений пользователя. Для простого примера, одна из моих сеток имеет следующие 9 столбцов:

IceCream|ShortName|HasNuts|SugarAdded|LimitedRun|PromoItem|Facility|FirstRun|LastRun

Пользователи могут скрывать / отображать любые из этих 9 столбцов в зависимости от своих личных предпочтений.

То, что я хочу сделать, - это предоставить способ сохранить, какие столбцы хочет видеть конкретный пользователь, чтобы ему / ей не пришлось повторно выбирать эти столбцы для просмотра каждый раз, когда отображается страница с этой сеткой.

1 Ответ

41 голосов
/ 08 декабря 2011

Я нашел ваш вопрос очень интересным.Вопрос о сохранении пользовательского состояния сетки интересен во многих случаях.Есть несколько интересных ответов на такие проблемы, в которых используется cookie (см. здесь , например).

На мой взгляд, сохранение состояния сетки в базе данных на сервере или в localStorage - этолучший способ, как использование куки.Лучший способ зависит от требований проекта, в которых вы его используете.Например, использование хранилища базы данных на сервере позволяет реализовать роуминговое состояние сетки.Если вы используете localStorage вместо файлов cookie, пользовательские настройки будут потеряны, если пользователь перейдет на другой компьютер или просто будет использовать другой веб-браузер на том же компьютере.

Другая проблема с состоянием сеткиэто обслуживание.Информация о столбцах таблицы обычно хранится в файлах JavaScript или HTML, а не в базе данных.В случае, если оба источника могут быть не синхронными при изменениях сетки.Вы можете легко представить различные сценарии проблемы обновления.Тем не менее, преимущества пользовательских предпочтений настолько велики в некоторых сценариях, что проблемы с небольшими недостатками не так важны и могут быть решены относительно легко.

Поэтому я потрачу некоторое время на реализацию двух демонстраций, которые показывают, как это можно сделать.быть реализованным.Я использовал localStorage в своих демонстрациях по многим причинам.Оттуда я упомяну только два:

  1. Cookies - это способ отправки постоянно различной информации на сервер или с сервера, который на самом деле не требуется.Это увеличивает размер HTTP-заголовка и снижает производительность веб-сайта (см., Например, здесь ).
  2. Куки-файлы имеют очень жесткие ограничения.Соответствует разделу 6,3 rfc2109 или 6.1 rfc6265: не менее 4096 байт на файл cookie, не менее 50 файлов cookie на домен (20 в rfc2109), всего не менее 3000 файлов cookie (300в rfc2109).Таким образом, файлы cookie нельзя использовать для сохранения слишком большого количества информации.Например, если вы хотите сохранить состояние каждой сетки каждой веб-страницы, вы можете быстро достичь ограничений.

С другой стороны localStorage поддерживаются всеми современными браузерами и будут поддерживаться в Интернете.Проводник, начиная с IE8 (см. здесь ).localStorage будет автоматически сохранено для каждого источника (например, a1.example.com, a2.example.com, a3.example.com и т. Д.) И имеет произвольное ограничение в 5 МБ для каждого источника (см. здесь ).Поэтому, если вы будете осторожно использовать пространство, вы будете далеко от любых ограничений.

Поэтому я использовал в своих демонстрациях localStorage.Я должен также упомянуть, что есть некоторые плагины, такие как jStorage , которые используют localStorage, если это поддерживается браузером и используют другое хранилище, но тот же интерфейс для вас в случае старых браузеров, таких как IE6 / IE7.В случае, если у вас есть только меньший размер хранилища: 128 КБ вместо 5 МБ, но лучше, чем 4 КБ, который имеет для файлов cookie (см. здесь ).

Теперь о реализации.Я создаю две демонстрации: это и его расширенную версию: эта .

В первой демонстрации будут сохранены следующие состояния сетки иавтоматически восстанавливается при перезагрузке страницы ( F5 в большинстве веб-браузеров):

  • , какие столбцы скрыты
  • порядок столбцов
  • ширина каждого столбца
  • имя столбца, по которому будет сортироваться сетка, и направление сортировки
  • номер текущей страницы
  • текущий фильтр сетки ипризнак применения фильтра.Я использовал настройку multipleSearch: true в сетке.

Таким же образом можно расширить (или уменьшить) список опций, которые являются частью сохраненного состояния сетки.

Наиболее важные части кода из демонстрации вы найдете ниже:

var $grid = $("#list"),
    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 $.parseJSON(window.localStorage.getItem(storageItemName));
        }
    },
    myColumnStateName = 'ColumnChooserAndLocalStorage.colState',
    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,
                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;
    },
    firstLoad = true;

myColumnsState = restoreColumnState(cm);
isColState = typeof (myColumnsState) !== 'undefined' && myColumnsState !== null;

$grid.jqGrid({
    // ... other 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',
    loadComplete: function () {
        if (firstLoad) {
            firstLoad = false;
            if (isColState) {
                $(this).jqGrid("remapColumns", myColumnsState.permutation, true);
            }
        }
        saveColumnState.call($(this), this.p.remapColumns);
    }
});
$grid.jqGrid('navButtonAdd', '#pager', {
    caption: "",
    buttonicon: "ui-icon-calculator",
    title: "choose columns",
    onClickButton: function () {
        $(this).jqGrid('columnChooser', {
            done: function (perm) {
                if (perm) {
                    this.jqGrid("remapColumns", perm, true);
                    saveColumnState.call(this, perm);
                }
            }
        });
    }
});
$grid.jqGrid('navButtonAdd', '#pager', {
    caption: "",
    buttonicon: "ui-icon-closethick",
    title: "clear saved grid's settings",
    onClickButton: function () {
        removeObjectFromLocalStorage(myColumnStateName);
    }
});

Будьте осторожны, чтобы определить myColumnStateName (значение `'ColumnChooserAndLocalStorage.colState'``) в различных демо)на разных страницах.

Второе демо является продолжением первого, используя технику из моего старого ответа на ваш другой вопрос. Демонстрация использует панель инструментов поиска и дополнительно синхронизирует информацию между формой расширенного поиска и панелью инструментов поиска.

ОБНОВЛЕНО : следующий ответ содержит расширенную версию кода, включенного выше. Он показывает, как сохранить выбранные строки (или строки) дополнительно. Другой ответ показывает, как сохранить список развернутых узлов древовидной сетки и развернуть узлы при повторном кодировании страницы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...