GridView - выбор всех элементов (со всех страниц)

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Vasiliy Baukin
Сообщения: 102
Зарегистрирован: 2011.02.04, 12:47

GridView - выбор всех элементов (со всех страниц)

Сообщение Vasiliy Baukin »

День добрый!

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

С точки зрения UI задача более-менее понятна.

По технической реализации видятся варианты
1) Добавить выключение пагинации. Минус - если данных много, на клиенте будет работать плохо / вообще невозможно будет совершить операцию.
2) Сериализовать данные точно так же, как это сделано в gridview, скопировав метод applyFilter - плюс в том, что это довольно простая реализация. Минус - это не DRY, т.к. мне придется скопировать методы, или переопределить yii gridview js, чтобы методы сериализации фильтра были одинаковы. Дополнительный минус - если что-то накроется / сбой при повторной сериализации, ущерб от неверной групповой операции над документами может быть большим...
3) Более всего склоняюсь к этому методу. При каждом формировании страницы таблицы писать в БД критерии запроса, присвоить записи ключ. Этот ключ положить в data атрибут gridview страницы. При необходимости сделать выбор всех на всех страницах - просто отправить на сервер ключ, по которой восстановятся критерии выборки и код групповой операции.

Может есть еще вариант? Может есть красивая реализация варианта 2?

Заранее спасибо.
Nex-Otaku
Сообщения: 831
Зарегистрирован: 2016.07.09, 21:07

Re: GridView - выбор всех элементов (со всех страниц)

Сообщение Nex-Otaku »

1. Если нужно выполнить операции "над всеми элементами", то для этого достаточно сделать отдельные кнопки без того, чтобы что-то отмечать галочками и "сериализовывать". Пример - кнопка "отметить все темы как прочтённые" на этом форуме.

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

3. Если в отобранной по фильтру (см. п.2) группе нужно будет дополнительно выбирать вручную галочками, то это объём небольшой, соразмерный человеческим усилиям, следовательно, обработается нормально. Если же отбирать галочками не нужно, а действие сразу выполняется по всей группе - то делаем опять же отдельными кнопками (см. п.1).
wade_seo
Сообщения: 13
Зарегистрирован: 2010.08.03, 21:45

Re: GridView - выбор всех элементов (со всех страниц)

Сообщение wade_seo »

> Пример - кнопка "отметить все темы как прочтённые" на этом форуме.

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

> 2. Отключать страничную навигацию или кардинально переделывать GridView нет необходимости. Для обеспечения удобной работы с группой, нужно делать соответствующие режимы фильтрации данных.

Поясните.

Опять же - у меня нет режимов. Есть фильтры, по состоянию которых и выстраивается выборка.

> 3. Если в отобранной по фильтру (см. п.2) группе нужно будет дополнительно выбирать вручную галочками, то это объём небольшой, соразмерный человеческим усилиям, следовательно, обработается нормально. Если же отбирать галочками не нужно, а действие сразу выполняется по всей группе - то делаем опять же отдельными кнопками (см. п.1).

Мне кажется Вы не поняли задачу. Нужно выделять ВСЕ данные на всех страницах, а не только на выведенной. Как это сделано в gmail, например. Там можно выбрать все записи по результатам фильтрации, а не только те, что на текущей странице. Фильтрация при этом может быть довольно сложной, через управляющие команды в текстовом поле... Т.е. тут вряд ли можно говорить о "режимах" фильтрации.

Итого... если ID записей для групповой операции не передается, передаются данные фильтров. Вопрос как это лучше сделать.
Nex-Otaku
Сообщения: 831
Зарегистрирован: 2016.07.09, 21:07

Re: GridView - выбор всех элементов (со всех страниц)

Сообщение Nex-Otaku »

Постараюсь попроще объяснить.

1. Вот пользователь накомбинировал фильтры, отфильтровал по ним список.

2. Вот пользователю нужно применить какую-то операцию ко всем записям отфильтрованного списка.

3. Для выполнения этой операции, пользователю нужно лишь нажать кнопку "сделать X по всем отфильтрованным записям".

4. Пользователь мжякнул кнопку, на сервер отправилось:
а) комбинация текущих фильтров - она и так каждый раз передаётся, ничего сложного;
б) ID жмякнутой кнопки, чтобы определить, какое действие выполнить.

5. Сервер принял список фильтров и ID действия (кнопки), отфильтровал всё, получил список, абсолютно идентичный тому, что показывался пользователю, выполнил по этому списку действие X ко всем отфильтрованным записям, вернул результат пользователю.

Как видите, при этом подходе мы избавлены от необходимости отправлять на сервер списки ID записей. Размером списка мы не ограничены никак, страничную навигацию отключать не нужно.
andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: GridView - выбор всех элементов (со всех страниц)

Сообщение andku83 »

Код: Выделить всё

    public function actionIndex()
    {
        $searchModel = new ModelSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        if (Yii::$app->request->isPost && $action = Yii::$app->request->post('action')){
            $filterQuery = clone $dataProvider->query;   // при наличии редиректа клонировать необязательно
            $filterQuery->select('id');  //если нужно получить только ИД элементов которые нужно менять
            $this->doAction($action, $filterQuery);
            
            return $this->redirect('index');
        }
        
        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
        ]);
    }
Ответить