OctoberCMS. Массовые действия в List Controller
Кусочек кода из плагина Rainlab.User. Если предполагается набор действий для массового изменения состояния, то в интерфейсе их логично объединить в один пункт.
В контроллер необходимо добавить 2 метода. В index
просто добавляем js код плагин, а в onBulkActions
логика массовых изменений. Допускается только однозначные действия т.е. нет воможности показать модальное окно и уточнить действие у пользователя.
public function index()
{
$this->addJs('/plugins/[vendorname]/[pluginname]/assets/js/bulk-actions.js');
$this->asExtension('ListController')->index();
}
public function index_onBulkAction()
{
if (
($bulkAction = post('action')) &&
($checkedIds = post('checked')) &&
is_array($checkedIds) &&
count($checkedIds)
) {
foreach ($checkedIds as $userId) {
if (!$user = User::withTrashed()->find($userId)) {
continue;
}
switch ($bulkAction) {
case 'delete':
$user->forceDelete();
break;
case 'activate':
$user->attemptActivation($user->activation_code);
break;
case 'deactivate':
$user->delete();
break;
case 'restore':
$user->restore();
break;
case 'ban':
$user->ban();
break;
case 'unban':
$user->unban();
break;
}
}
Flash::success(Lang::get('rainlab.user::lang.users.'.$bulkAction.'_selected_success'));
}
else {
Flash::error(Lang::get('rainlab.user::lang.users.'.$bulkAction.'_selected_empty'));
}
return $this->listRefresh();
}
И в htm файл (стандартно это _list_toolbar.htm
) панели инструментов:
<div class="btn-group dropdown dropdown-fixed" data-control="bulk-actions">
<button
data-primary-button
type="button"
class="btn btn-default"
data-request="onBulkAction"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked"
data-request-success="$(this).prop('disabled', true).next().prop('disabled', true)"
data-stripe-load-indicator>
Массовые действия
</button>
<button
type="button"
class="btn btn-default dropdown-toggle"
data-trigger-action="enable"
data-trigger=".control-list input[type=checkbox]"
data-trigger-condition="checked"
data-toggle="dropdown">
<span class="caret"></span>
</button>
<ul class="dropdown-menu" data-dropdown-title="Массовые действия">
<li>
<a href="javascript:;" class="oc-icon-trash-o" data-action="delete" data-confirm="<?= e(trans('rainlab.user::lang.users.delete_selected_confirm')) ?>">
<?= e(trans('rainlab.user::lang.users.delete_selected')) ?>
</a>
</li>
<li role="separator" class="divider"></li>
<li>
<a href="javascript:;" class="oc-icon-user-plus" data-action="activate" data-confirm="<?= e(trans('rainlab.user::lang.users.activate_selected_confirm')) ?>">
<?= e(trans('rainlab.user::lang.users.activate_selected')) ?>
</a>
</li>
<li role="separator" class="divider"></li>
<li>
<a href="javascript:;" class="oc-icon-user-times" data-action="deactivate" data-confirm="<?= e(trans('rainlab.user::lang.users.deactivate_selected_confirm')) ?>">
<?= e(trans('rainlab.user::lang.users.deactivate_selected')) ?>
</a>
</li>
<li>
<a href="javascript:;" class="oc-icon-user-plus" data-action="restore" data-confirm="<?= e(trans('rainlab.user::lang.users.restore_selected_confirm')) ?>">
<?= e(trans('rainlab.user::lang.users.restore_selected')) ?>
</a>
</li>
<li role="separator" class="divider"></li>
<li>
<a href="javascript:;" class="oc-icon-ban" data-action="ban" data-confirm="<?= e(trans('rainlab.user::lang.users.ban_selected_confirm')) ?>">
<?= e(trans('rainlab.user::lang.users.ban_selected')) ?>
</a>
</li>
<li>
<a href="javascript:;" class="oc-icon-circle-o-notch" data-action="unban" data-confirm="<?= e(trans('rainlab.user::lang.users.unban_selected_confirm')) ?>">
<?= e(trans('rainlab.user::lang.users.unban_selected')) ?>
</a>
</li>
</ul>
</div>
В разрабатываемый плагин October CMS соответственно сам js плагин assets/js/bulk-actions.js
/*
* Bulk actions plugin
*
* Data attributes:
* - data-control="bulk-actions" - enables the plugin on an element
*
* JavaScript API:
* $('div').bulkActions()
*/
+function ($) { "use strict";
// BULK ACTIONS CLASS DEFINITION
// ============================
var BulkActions = function(element, options) {
this.options = options
this.$el = $(element)
// Init
this.init()
}
BulkActions.DEFAULTS = {}
BulkActions.prototype.init = function() {
this.activeAction = null
this.$primaryBtn = $('[data-primary-button]', this.$el)
this.$toggleBtn = $('.dropdown-toggle', this.$el)
this.$dropdownMenu = $('.dropdown-menu', this.$el)
this.baseCss = this.$primaryBtn.attr('class')
this.$primaryBtn.on('click', $.proxy(this.onClickPrimaryButton, this))
this.$dropdownMenu.on('click', 'li > a', $.proxy(this.onClickMenuItem, this))
this.setActiveItem($('li > a:first', this.$dropdownMenu))
}
BulkActions.prototype.onClickPrimaryButton = function() {
if (!this.activeAction) {
throw new Error('Bulk action not found')
}
this.$primaryBtn.data('request-data', {
checked: $('.control-list').listWidget('getChecked'),
action: this.activeAction
})
}
BulkActions.prototype.onClickMenuItem = function(ev) {
this.setActiveItem($(ev.target))
this.$primaryBtn.click()
}
BulkActions.prototype.setActiveItem = function($el) {
this.$toggleBtn.blur()
this.activeAction = $el.data('action')
this.$primaryBtn.text($el.text())
this.$primaryBtn.attr('class', this.baseCss)
this.$primaryBtn.addClass($el.attr('class'))
this.$primaryBtn.data('request-confirm', $el.data('confirm'))
}
// BULK ACTIONS PLUGIN DEFINITION
// ============================
var old = $.fn.bulkActions
$.fn.bulkActions = function (option) {
var args = Array.prototype.slice.call(arguments, 1), result
this.each(function () {
var $this = $(this)
var data = $this.data('oc.bulkactions')
var options = $.extend({}, BulkActions.DEFAULTS, $this.data(), typeof option == 'object' && option)
if (!data) $this.data('oc.bulkactions', (data = new BulkActions(this, options)))
if (typeof option == 'string') result = data[option].apply(data, args)
if (typeof result != 'undefined') return false
})
return result ? result : this
}
$.fn.bulkActions.Constructor = BulkActions
// BULK ACTIONS NO CONFLICT
// =================
$.fn.bulkActions.noConflict = function () {
$.fn.bulkActions = old
return this
}
// BULK ACTIONS DATA-API
// ===============
$(document).render(function() {
$('[data-control="bulk-actions"]').bulkActions()
});
}(window.jQuery);