Source: admin/javascript/engine/libs/action_mapper.js

/* --------------------------------------------------------------
 action_mapper.js 2016-02-22
 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.action_mapper = jse.libs.action_mapper || {};

/**
 * ## Action Mapper Library
 *
 * Maps a dropdown button action item event to another page element ($button). This library
 * must be used to quickly redirect user actions to existing but hidden UI elements like table row
 * actions. When a callback function is passed as an argument the action item will override the default
 * behaviour.
 *
 * 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/action_mapper'   
 *   ],
 *   
 *   function(data) {
 *      // Module code ... 
 *   }); 
 *```
 * ### Example
 *
 * The HTML for the target button: 
 * 
 * ```html
 * <button id="button1">Button 1</button>
 * ```
 *
 * The JavaScript code that will map an action to to a button dropdown widget for the target button:
 * 
 * ```javascript
 * // Define a custom callback function.
 * function customCallbackFunc(event) {
 *     console.log('Function called!');
 * };
 *
 * // Map an event to a new dropdown action item.
 * var options = {
 *   // A new action item will be created in this widget.
 *   $dropdown: $('#button-dropdown'), 
 *
 *   // Target element will be triggered when the user clicks the dropdown action item.  
 *   $target: $('#target-button'), 
 *   
 *   // Target event name to be triggered.
 *   event: 'click',   
 *   
 *   // (optional) Provide a function to override the default event handler.
 *   callback: customCallbackFunc, 
 *   
 *   // (optional) Add a custom action title for the dropdown button.
 *   title: 'Action Title' 
 * }
 * 
 * jse.libs.action_mapper.bind(options);
 * ```
 *
 * By clicking on the "Button 1" you will receive a "Function called!" in the console!
 *
 * @module Admin/Libs/action_mapper
 * @exports jse.libs.action_mapper
 */
(function(exports) {
	
	'use strict';
	
	/**
	 * 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 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);
			}
		});
	};
	
	/**
	 * Binds the event
	 *
	 * This method is the initializing point for all event bindings.
	 *
	 * @param {object} options Contains all elements, function and event description
	 * @param {string} options.$dropdown Selector for the button dropdown element (div).
	 * @param {string} [options.$target] (optional) Selector for the target element of the mapping.
	 * @param {string} options.event The name of the event. The event will be triggered on source and
	 * destination element (e.g. "click", "mouseleave").
	 * @param {function} [options.callback] (optional) Function that will be called when the event of the
	 * destination element is triggered. OVERWRITES THE ACTUAL EVENT FOR THE  DESTINATION ELEMENT.
	 * @param {string} title (optional) Provide an action title for the dropdown if no $target was defined.
	 */
	exports.bind = function(options) {
		_bindEvent(options);
	};
	
})(jse.libs.action_mapper);