Last active
May 15, 2016 22:48
-
-
Save bhalash/61c8a90cd4b88f978051233c6a260c93 to your computer and use it in GitHub Desktop.
jQuery-based data binding directives
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($, document, window) { | |
/** | |
* Event subscribe/unsubscribe. | |
* | |
* @link https://davidwalsh.name/pubsub-javascript | |
* @link https://gist.github.com/cowboy/661855 | |
*/ | |
$.observer = $({}); | |
/** | |
* Break up arguments object into useful data. | |
* | |
* For each action fragment (see below), broadcast an action with that | |
* fragment's data: | |
* | |
* @param {object} args - Arguments object. | |
* @returns {array} actions - Mapped actions array. | |
* | |
*/ | |
$.observer.triggers = function(args) { | |
var args = Array.prototype.slice.apply(args), | |
triggers = args[0].split(':'), | |
data = {}; | |
data = $.observer.triggers.data(triggers, args); | |
triggers = $.observer.triggers.arr(triggers, args, data); | |
return triggers; | |
} | |
/** | |
* Construct data object for event. | |
* | |
* This hold information about the complete action (action, method and | |
* target). | |
* | |
* fullAction is so because a full action has three parameters. | |
* | |
* @param {array} triggers - Split array of action fragments. | |
* @param {array} args - Superset args object. | |
* @returns {object} triggers | |
*/ | |
$.observer.triggers.data = function(triggers, args) { | |
var target = null, | |
fullAction = 3; | |
if (triggers.length === fullAction) { | |
target = triggers[2]; | |
} else if (typeof(args[1]) === 'string') { | |
target = args[1]; | |
} | |
return { | |
action: triggers[0], | |
method: triggers[1], | |
target: target | |
}; | |
} | |
/** | |
* Construct complete trigger stack for action. | |
* | |
* 'modal:show:lightbox' = | |
* 'modal' | |
* 'modal:show' | |
* 'modal:show:lightbox' | |
* | |
* The last line is dense: jQuery's trigger takes an optional array of | |
* parameters to apply. The first array element is the trigger action | |
* detailed above. The second array element contains the data object | |
* followed by all of the other arguments passed to the trigger. | |
* | |
* return [event, [data, arg1, arg2, arg3]] | |
* | |
* $.observer.trigger(event, [data, arg1, arg2, arg3]) | |
* | |
* @link https://api.jquery.com/trigger/ | |
* @param {array} triggers - Split array of action fragments. | |
* @param {array} args - Superset args object. | |
* @param {object} data - Constructed action data object. | |
* @returns {array} triggers | |
* | |
*/ | |
$.observer.triggers.arr = function(triggers, args, data) { | |
var trigger = ''; | |
// See explanation above. | |
data = [data].concat(args.slice(1)); | |
return triggers.map(function(fragment, index) { | |
if (index) { | |
trigger = trigger.concat(':'); | |
} | |
trigger = trigger.concat(fragment); | |
return [trigger, data]; | |
}); | |
} | |
/** | |
* Subscribe and unsubscribe actions. | |
* | |
* @link https://gist.github.com/cowboy/661855 | |
* @param {string} name | |
* @param {string} action | |
*/ | |
$.each({ on: 'subscribe', off: 'unsubscribe' }, function(name, action) { | |
$[action] = function() { | |
$.observer[name].apply($.observer, arguments); | |
} | |
}); | |
/** | |
* Broadcast action. | |
* | |
* More complex than the subscribe and unsubscribe, because it splits up the | |
* triggering event into individual fragments to trigger individually: | |
* | |
* 'modal:show:lightbox' = | |
* 'modal' | |
* 'modal:show' | |
* 'modal:show:lightbox' | |
*/ | |
$.broadcast = function() { | |
$.observer.triggers(arguments).forEach(function(action) { | |
$.observer.trigger.apply($.observer, action); | |
}); | |
} | |
/** | |
* Click directive. | |
* | |
* Just an example, because that's all I need right now. | |
* | |
* @param {object} event - DOM event. | |
* @param {bool} false - Prevent normal click action from occurring. | |
*/ | |
$(document).on('click tap', '[data-click]', function(event) { | |
$.broadcast($(event.currentTarget).data('click'), event.currentTarget); | |
return false; | |
}); | |
})(jQuery, document, window); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<img | |
data-click="modal:show:lightbox" | |
src="https://ix.bhalash.com/13544806616/m/1_1600.jpg" | |
srcset="https://ix.bhalash.com/13544806616/m/1_1600.jpg 1600w, | |
https://ix.bhalash.com/13544806616/m/1_1280.jpg 1280w, | |
https://ix.bhalash.com/13544806616/m/1_1024.jpg 1024w, | |
https://ix.bhalash.com/13544806616/m/1_768.jpg 768w, | |
https://ix.bhalash.com/13544806616/m/1_640.jpg 640w, | |
https://ix.bhalash.com/13544806616/m/1_480.jpg 480w" | |
sizes="(min-width: 480) 100%" | |
alt="Friend and I"> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($, document, window) { | |
/** | |
* Broadcast to hide all modals when <Esc> is depressed. | |
* | |
* @param {object} event - DOM event. | |
*/ | |
$(document).on('keydown', function(event) { | |
switch (event.keyCode) { | |
case 27: $.broadcast('modal:hide'); break; | |
} | |
}); | |
/** | |
* Show specified modal. | |
* | |
* Show modal if data is set. | |
* | |
* @param {object} event - DOM event. | |
* @param {object} data - Binding event data. | |
*/ | |
$.subscribe('modal:show', function(event, data) { | |
if (data.target) { | |
$.broadcast('modal:hide'); | |
$('[data-modal="' + data.target + '"]').removeClass('hidden').show(); | |
} | |
}); | |
/** | |
* Hide specified/all modals. | |
* | |
* If there is no data set, hide all modals. | |
* | |
* @param {object} event - DOM event. | |
* @param {object} data - Binding event data. | |
*/ | |
$.subscribe('modal:hide', function(event, data) { | |
var modal = '[data-modal]'; | |
if (data.target) { | |
modal = '[data-modal="' + data.target + '"]'; | |
} | |
$(modal).hide(); | |
}); | |
/** | |
* Set lightbox image when the modal is shown. | |
* | |
* @param {object} event - DOM event. | |
* @param {object} data - Binding event data. | |
* @param {object} element - Event triggering element. | |
*/ | |
$.subscribe('modal:show:lightbox', function(event, data, element) { | |
data = { | |
src: $(element).data('src') || $(element).attr('src'), | |
alt: $(element).data('alt') || $(element).attr('alt') | |
}; | |
$('.lightbox__image').attr(data); | |
}); | |
/** | |
* Focus the modal search input after it is displayed. | |
*/ | |
$.subscribe('modal:show:search', function() { | |
$('.modal-search__input').focus(); | |
}); | |
})(jQuery, document, window); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment