/* --------------------------------------------------------------
group_check.js 2017-10-10
Gambio GmbH
http://www.gambio.de
Copyright (c) 2017 Gambio GmbH
Released under the GNU General Public License (Version 2)
[http://www.gnu.org/licenses/gpl-2.0.html]
--------------------------------------------------------------
*/
/**
* ## Group check widget
*
* The widget creates a panel with switcher fields for all customer groups. If the options "user" and "section" are
* provided, the user configuration service will be used to store the panels collapsed/expanded state.
*
* ### Options (Required)
*
* **User | `data-panel-user` | Integer | Optional**
*
* Customer id of user, used by user configuration service to store the collapsed state.
*
* **Section | `data-panel-section` | String | Optional**
*
* Panel section, used by user configuration service 'configuration_key'. The value get a "**'group_check_'**"-prefix.
*
* ### Options (Additional)
*
* **Selected | `data-group_check-selected` | String | Additional**
*
* Comma separated list of customer status ids. If an switcher value is equal to one of the customer ids, the
* switcher state is active. Alternatively you can set the value "all" to set all switchers to an active state.
*
* **Name | `data-group_check-name` | String | Additional**
*
* Name attribute of switchers hidden input:checkbox field. If no value is provided, it defaults to **'group_check'**
*
* ### Example
*
* * ```html
* <div data-gx-widget="group_check"
* data-group_check-user="{$smarty.session.customer_id}"
* data-group_check-section="group-check-sample-section"
* data-group_check-active="[1,2,3]|[all]"
* data-group_check-name="custom-switcher-name"></div>
* ```
*
* @module Admin/Widgets/group_check
*/
gx.widgets.module(
'group_check',
['xhr'],
/** @lends module:Widgets/group_check */
function (data) {
'use strict';
// ------------------------------------------------------------------------
// VARIABLE DEFINITION
// ------------------------------------------------------------------------
/**
* Widget Reference
*
* @type {object}
*/
const $this = $(this);
/**
* Default Widget Options
*
* @type {object}
*/
const defaults = {
name: 'group_check'
};
/**
* Final Widget Options
*
* @type {object}
*/
const options = $.extend(true, {}, defaults, data);
/**
* Module Object
*
* @type {object}
*/
const module = {};
/**
* Required options.
*
* @type {String[]}
*/
const requiredOptions = ['user', 'section'];
/**
* Element for whether selecting or deselecting all other switcher.
*/
let $allSwitcher;
/**
* Renders the group check box.
*
* @private
*/
const _renderGroupCheck = () => {
jse.libs.xhr.get({
url: './admin.php?do=JSWidgetsAjax/isGroupCheckEnabled'
}).done(r => {
if (r.status) {
const $container = $('<div/>', {
'data-gx-widget': 'panel switcher',
'data-panel-title': jse.core.lang.translate('HEADING_GROUP_CHECK', 'content_manager'),
'data-panel-user': options.user,
'data-panel-section': 'group_check_' + options.section,
'data-panel-container_class': 'group-check'
});
$container.append(_renderBody(r.customerGroups)).appendTo($this);
gx.widgets.init($container).then(() => {
_setEventListener();
_setSwitcherDefaultStates();
});
}
});
};
/**
* Sets default state of switcher elements.
* The "selected" option is used to determine the default state.
*
* @private
*/
const _setSwitcherDefaultStates = () => {
// just continue if option is not set
if (undefined === options.selected || options.selected === '') {
return;
}
// use bulk switcher action if option value is set to "all"
if (options.selected === 'all') {
$allSwitcher.find('input:checkbox').switcher('checked', true);
_bulkSwitcherAction(true);
return;
}
// activate switcher programmatically
let preselection;
if (Number.isInteger(options.selected)) {
preselection = [options.selected];
} else {
preselection = options.selected.split(',').map(Number);
}
const switcher = $this.find('input:checkbox');
let i = 0;
for (; i < switcher.length; i++) {
if (switcher[i].value !== 'all') {
if (preselection.indexOf(parseInt(switcher[i].value, 10)) !== -1) {
$(switcher[i]).switcher('checked', true);
}
}
}
_tryActiveAllSwitcher();
};
/**
* Renders the panel body.
* @param {Object} customerGroups Serialized customer group collection, provided by ajax request.
* @returns {jQuery} Panel body html.
* @private
*/
const _renderBody = customerGroups => {
const $gxContainer = $('<div/>', {
'class': 'gx-container'
});
const $fieldSet = $('<fieldset/>');
$allSwitcher = _renderFormGroup(jse.core.lang.translate('LABLE_GROUPCHECK_ALL', 'content_manager'), 'all');
$fieldSet.append($allSwitcher);
let i = 0;
for (; i < customerGroups.length; i++) {
$fieldSet.append(_renderFormGroup(customerGroups[i].names[jse.core.config.get('languageCode')
.toUpperCase()], customerGroups[i].id));
}
$gxContainer.append($fieldSet);
return $gxContainer;
};
/**
* Renders the form group elements of the group check.
*
* @param {string} label Label name.
* @param {string} value Switchers value attribute.
* @returns {jQuery} Form group html.
* @private
*/
const _renderFormGroup = (label, value) => {
const $formGroup = $('<div/>', {'class': 'form-group'});
const $label = $('<label/>', {
'for': 'customer-groups-' + label.toLowerCase(),
'class': 'col-md-4',
'text': label
});
const $inputContainer = $('<div/>', {
'class': 'col-md-6'
});
const $input = $('<input/>', {
'type': 'checkbox',
'id': 'customer-groups-' + label.toLowerCase(),
'name': options.name + '[]',
'value': value,
'checked': options.all_checked
});
$inputContainer.append($input);
return $formGroup.append($label).append($inputContainer);
};
/**
* Checks if all required options are passed.
*
* @private
*/
const _checkRequiredOptions = () => {
let i = 0;
for (; i < requiredOptions.length; i++) {
if (undefined === options[requiredOptions[i]]) {
throw new Error('Required widget option "' + requiredOptions[i] + '" is no set!');
}
}
};
/**
* Sets the event listener for the group check widget.
*
* @private
*/
const _setEventListener = () => {
const switcher = $this.find('input:checkbox');
// check all switcher if the "all" switcher is clicked
$allSwitcher.on('change', () => {
if ($allSwitcher.find('input:checkbox').prop('checked')) {
_bulkSwitcherAction(true);
} else {
_bulkSwitcherAction(false);
}
});
switcher.on('change', e => {
if (!$allSwitcher.find('input:checkbox').is(e.currentTarget)) {
// remove checked attribute from "all" switcher if one is deselected
if (!$(e.currentTarget).prop('checked')) {
$allSwitcher.find('input:checkbox').switcher('checked', false);
}
_tryActiveAllSwitcher();
}
});
};
/**
* This method checks if all other switcher fields instead of "all" are active.
* If so, the "all" switcher will be activated.
*
* @private
*/
const _tryActiveAllSwitcher = () => {
const switcher = $this.find('input:checkbox');
let allChecked = true;
let i = 0;
for (; i < switcher.length; i++) {
if (!$allSwitcher.find('input:checkbox').is($(switcher[i]))) {
allChecked = allChecked && $(switcher[i]).prop('checked');
}
}
if (allChecked) {
$allSwitcher.find('input:checkbox').switcher('checked', true);
}
}
/**
* Bulk action for whether selecting or deselecting all switcher elements.
*
* @param {boolean} checked Status of "checked" property.
* @private
*/
const _bulkSwitcherAction = checked => {
const switcher = $this.find('input:checkbox');
let i = 0;
for (; i < switcher.length; i++) {
if (!$allSwitcher.find('input:checkbox').is($(switcher[i]))) {
$(switcher[i]).switcher('checked', checked);
}
}
};
// ------------------------------------------------------------------------
// INITIALIZATION
// ------------------------------------------------------------------------
/**
* Initialize method of the widget, called by the engine.
*/
module.init = done => {
_checkRequiredOptions();
_renderGroupCheck();
done();
};
return module;
});