/* --------------------------------------------------------------
button_dropdown.js 2016-02-23
Gambio GmbH
http://www.gambio.de
Copyright (c) 2016 Gambio GmbH
Released under the GNU General Public License (Version 2)
[http://www.gnu.org/licenses/gpl-2.0.html]
--------------------------------------------------------------
*/
jse.libs.button_dropdown = jse.libs.button_dropdown || {};
/**
* ## Button Dropdown Library
*
* This library contains helper functions that make the manipulation of a button dropdown
* widget easier.
*
* You will need to provide the full URL in order to load this library as a dependency to a module:
*
* ```javascript
* gx.controller.module(
* 'my_custom_page',
*
* [
* jse.core.config.get('shopUrl') + '/admin/html/assets/javascript/engine/libs/button_dropdown'
* ],
*
* function(data) {
* // Module code ...
* });
*```
*
* ### Example
*
* ```javascript
* var $buttonDropdown = $('#my.js-button-dropdown');
*
* // Map an action to a dropdown item.
* jse.libs.button_dropdown.mapAction($buttonDropdown, action, section, callback, $targetRecentButton);
*
* // Change recent button.
* jse.libs.button_dropdown.changeDefualtButton($buttonDropdown, text, callback, $targetRecentButton);
*
* // Add a separator in a dropdown list.
* jse.libs.button_dropdown.addDropdownSeperator($buttonDropdown);
* ```
*
* @todo Further improve the code and the comments of this library.
*
* @module Admin/Libs/button_dropdown
* @exports jse.libs.button_dropdown
*/
(function(exports) {
'use strict';
// ------------------------------------------------------------------------
// PRIVATE METHODS
// ------------------------------------------------------------------------
/**
* Triggers a specific event from an element.
*
* Some situations require a different approach than just using the "trigger" method.
*
* @param {object} $element Destination element to be triggered.
* @param {object} event Event options can be used for creating new conditions.
*
* @private
*/
var _triggerEvent = function($element, event) {
if ($element.prop('tagName') === 'A' && event.type === 'click') {
$element.get(0).click();
} else {
$element.trigger(event.type);
}
};
/**
* Binds the event to a new dropdown action item.
*
* @param {object} options See bind documentation.
*
* @private
*/
var _bindEvent = function(options) {
var $dropdown = options.$dropdown,
action = options.action,
$target = options.$target,
eventName = options.event,
callback = options.callback || false,
title = options.title || (options.$target.length ? options.$target.text() : '<No Action Title Provided>'),
$li = $('<li></li>');
$li.html('<span data-value="' + action + '">' + title + '</span>');
$dropdown.find('ul').append($li);
$li.find('span').on(eventName, function(event) {
if (callback !== false) {
//event.preventDefault();
//event.stopPropagation();
callback.call($li.find('span'), event);
} else {
_triggerEvent($target, event);
}
});
};
/**
* Initializes the default button.
*
* @param {object} $dropdown The affected button dropdown selector.
* @param {object} configValue Configuration value that comes from the UserConfigurationService.
* @param {object} title The caption of the default action button.
* @param {object} callback (optional) Callback function for the new action.
* @param {object} $targetDefaultButton (optional) Selector for the default button.
*
* @private
*/
var _initDefaultAction = function($dropdown, configValue, title, callback, $targetDefaultButton) {
var interval = setInterval(function() {
if (typeof $dropdown.attr('data-configuration_value') !== 'undefined') {
// Sets the recent action button loaded from database.
if ($dropdown.attr('data-configuration_value') === configValue) {
exports.changeDefaultAction($dropdown, title, callback, $targetDefaultButton);
}
clearInterval(interval);
}
}, 300);
};
// ------------------------------------------------------------------------
// PUBLIC METHODS
// ------------------------------------------------------------------------
/**
* Adds a new item to the dropdown.
*
* @param {string} translationPhrase Translation phrase key.
* @param {string} translationSection Translation section of the phrase.
* @param {function} customCallback Define a custom callback.
* @param {object} $targetDefaultButton (optional) A custom selector which dropdown buttons should be changed.
*/
exports.mapAction =
function($dropdown, translationPhrase, translationSection, customCallback, $targetDefaultButton) {
var $target = $targetDefaultButton || $dropdown,
title = (translationSection !== '')
? jse.core.lang.translate(translationPhrase, translationSection)
: translationPhrase;
// Sets the first action as recent action button, if no recent action has benn set so far.
if (!$dropdown.find('ul li').length && $dropdown.find('button:first').text().trim() === '') {
exports.changeDefaultAction($dropdown, title, customCallback, $target);
}
_initDefaultAction($dropdown, translationPhrase, title, customCallback, $target);
var options = {
action: translationPhrase,
$dropdown: $dropdown,
title: title,
event: 'perform:action',
callback: function(event) {
customCallback(event);
exports.changeDefaultAction($(this), title, customCallback, $target);
}
};
_bindEvent(options);
};
/**
* Adds a separator to the dropdown list.
*
* The separator will be added at the end of the list.
*
* @param {object} $dropdown
*/
exports.addSeparator = function($dropdown) {
$dropdown
.find('ul')
.append('<li><hr></li>');
};
/**
* Changes the default action of the button.
*
* @param {object} $button The affected button dropdown widget.
* @param {string} title Text of the new button.
* @param {string} callback The callback
* @param {object} $targetDefaultButton A custom element for which button should be changed.
*/
exports.changeDefaultAction = function($dropdown, title, callback, $targetDefaultButton) {
var $target = $targetDefaultButton || $dropdown,
icon = $target.data('icon');
if (title.length) {
$target
.find('button:first')
.off('perform:action')
.on('perform:action', callback);
}
$target
.find('button:first')
.text(title);
$target
.find('button:first')
.prop('title', title.trim());
if (typeof icon !== 'undefined') {
$target
.find('button:first')
.prepend($('<i class="fa fa-' + icon + ' btn-icon"></i>'));
}
};
})(jse.libs.button_dropdown);