(function($) {
var o = $({});
var calledEvents = {};
$.subscribe = function() {
o.on.apply(o, arguments);
if (arguments[0] in calledEvents)
{
var eventName = arguments[0];
var callback = arguments[1];
var clbArgs = [
{type: eventName}, // event
].concat(calledEvents[eventName][0]);
callback.apply(o, clbArgs);
}
};
$.unsubscribe = function() {
o.off.apply(o, arguments);
};
$.publish = function() {
o.trigger.apply(o, arguments);
var eventName = arguments[0];
var args = Array.prototype.slice.call(arguments, 1);
calledEvents[eventName] = args;
};
}(jQuery));
// USAGE
$.subscribe('document/kunda', function(e, a, b) {
console.log('A');
});
$.publish('document/kunda', ['AA', 'BBB']);
$.subscribe('document/kunda', function(e, a, b) {
console.log('B');
});
// Utility
if ( typeof Object.create !== 'function' ) {
Object.create = function( obj ) {
function F() {};
F.prototype = obj;
return new F();
};
}
(function( $, window, document, undefined ) {
var Twitter = {
init: function( options, elem ) {
var self = this;
self.elem = elem;
self.$elem = $( elem );
self.url = 'https://api.twitter.com/1.1/search/tweets.json';
self.search = ( typeof options === 'string' )
? options
: options.search;
self.options = $.extend( {}, $.fn.queryTwitter.options, options );
self.refresh( 1 );
},
refresh: function( length ) {
var self = this;
setTimeout(function() {
self.fetch().done(function( results ) {
results = self.limit( results.results, self.options.limit );
self.buildFrag( results );
self.display();
if ( typeof self.options.onComplete === 'function' ) {
self.options.onComplete.apply( self.elem, arguments );
}
if ( self.options.refresh ) {
self.refresh();
}
});
}, length || self.options.refresh );
},
fetch: function() {
return $.ajax({
url: this.url,
data: { q: this.search },
dataType: 'jsonp'
});
},
buildFrag: function( results ) {
var self = this;
self.tweets = $.map( results, function( obj, i) {
return $( self.options.wrapEachWith ).append ( obj.text )[0];
});
},
display: function() {
var self = this;
if ( self.options.transition === 'none' || !self.options.transition ) {
self.$elem.html( self.tweets ); // that's available??
} else {
self.$elem[ self.options.transition ]( 500, function() {
$(this).html( self.tweets )[ self.options.transition ]( 500 );
});
}
},
limit: function( obj, count ) {
return obj.slice( 0, count );
}
};
$.fn.queryTwitter = function( options ) {
return this.each(function() {
var twitter = Object.create( Twitter );
twitter.init( options, this );
$.data( this, 'queryTwitter', twitter );
});
};
$.fn.queryTwitter.options = {
search: '@tutspremium',
wrapEachWith: '<li></li>',
limit: 10,
refresh: null,
onComplete: null,
transition: 'fadeToggle'
};
})( jQuery, window, document );
/// USAGE ///
$('div.tweets').queryTwitter({
search: 'your',
limit: 10,
// onComplete: function() {
// console.log(arguments);
// },
refresh: 4000,
transition: 'slideToggle'
});
/*
* jQuery Autocomplete plugin 1.2.3
*
* Copyright (c) 2009 Jörn Zaefferer
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* With small modifications by Alfonso Gómez-Arzola.
* See changelog for details.
*
*/
;(function($) {
$.fn.extend({
autocomplete: function(urlOrData, options) {
var isUrl = typeof urlOrData == "string";
options = $.extend({}, $.Autocompleter.defaults, {
url: isUrl ? urlOrData : null,
data: isUrl ? null : urlOrData,
delay: isUrl ? $.Autocompleter.defaults.delay : 10,
max: options && !options.scroll ? 10 : 150,
noRecord: "No Records."
}, options);
// if highlight is set to false, replace it with a do-nothing function
options.highlight = options.highlight || function(value) { return value; };
// if the formatMatch option is not specified, then use formatItem for backwards compatibility
options.formatMatch = options.formatMatch || options.formatItem;
return this.each(function() {
new $.Autocompleter(this, options);
});
},
result: function(handler) {
return this.bind("result", handler);
},
search: function(handler) {
return this.trigger("search", [handler]);
},
flushCache: function() {
return this.trigger("flushCache");
},
setOptions: function(options){
return this.trigger("setOptions", [options]);
},
unautocomplete: function() {
return this.trigger("unautocomplete");
}
});
$.Autocompleter = function(input, options) {
var KEY = {
UP: 38,
DOWN: 40,
DEL: 46,
TAB: 9,
RETURN: 13,
ESC: 27,
COMMA: 188,
PAGEUP: 33,
PAGEDOWN: 34,
BACKSPACE: 8
};
var globalFailure = null;
if(options.failure != null && typeof options.failure == "function") {
globalFailure = options.failure;
}
// Create $ object for input element
var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);
var timeout;
var previousValue = "";
var cache = $.Autocompleter.Cache(options);
var hasFocus = 0;
var lastKeyPressCode;
var config = {
mouseDownOnSelect: false
};
var select = $.Autocompleter.Select(options, input, selectCurrent, config);
var blockSubmit;
// prevent form submit in opera when selecting with return key
navigator.userAgent.indexOf("Opera") != -1 && $(input.form).bind("submit.autocomplete", function() {
if (blockSubmit) {
blockSubmit = false;
return false;
}
});
// older versions of opera don't trigger keydown multiple times while pressed, others don't work with keypress at all
$input.bind((navigator.userAgent.indexOf("Opera") != -1 && !'KeyboardEvent' in window ? "keypress" : "keydown") + ".autocomplete", function(event) {
// a keypress means the input has focus
// avoids issue where input had focus before the autocomplete was applied
hasFocus = 1;
// track last key pressed
lastKeyPressCode = event.keyCode;
switch(event.keyCode) {
case KEY.UP:
if ( select.visible() ) {
event.preventDefault();
select.prev();
} else {
onChange(0, true);
}
break;
case KEY.DOWN:
if ( select.visible() ) {
event.preventDefault();
select.next();
} else {
onChange(0, true);
}
break;
case KEY.PAGEUP:
if ( select.visible() ) {
event.preventDefault();
select.pageUp();
} else {
onChange(0, true);
}
break;
case KEY.PAGEDOWN:
if ( select.visible() ) {
event.preventDefault();
select.pageDown();
} else {
onChange(0, true);
}
break;
// matches also semicolon
case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
case KEY.TAB:
case KEY.RETURN:
if( selectCurrent() ) {
// stop default to prevent a form submit, Opera needs special handling
event.preventDefault();
blockSubmit = true;
return false;
}
break;
case KEY.ESC:
select.hide();
break;
default:
clearTimeout(timeout);
timeout = setTimeout(onChange, options.delay);
break;
}
}).focus(function(){
// track whether the field has focus, we shouldn't process any
// results if the field no longer has focus
hasFocus++;
}).blur(function() {
hasFocus = 0;
if (!config.mouseDownOnSelect) {
hideResults();
}
}).click(function() {
// show select when clicking in a focused field
// but if clickFire is true, don't require field
// to be focused to begin with; just show select
if( options.clickFire ) {
if ( !select.visible() ) {
onChange(0, true);
}
} else {
if ( hasFocus++ > 1 && !select.visible() ) {
onChange(0, true);
}
}
}).bind("search", function() {
// TODO why not just specifying both arguments?
var fn = (arguments.length > 1) ? arguments[1] : null;
function findValueCallback(q, data) {
var result;
if( data && data.length ) {
for (var i=0; i < data.length; i++) {
if( data[i].result.toLowerCase() == q.toLowerCase() ) {
result = data[i];
break;
}
}
}
if( typeof fn == "function" ) fn(result);
else $input.trigger("result", result && [result.data, result.value]);
}
$.each(trimWords($input.val()), function(i, value) {
request(value, findValueCallback, findValueCallback);
});
}).bind("flushCache", function() {
cache.flush();
}).bind("setOptions", function() {
$.extend(true, options, arguments[1]);
// if we've updated the data, repopulate
if ( "data" in arguments[1] )
cache.populate();
}).bind("unautocomplete", function() {
select.unbind();
$input.unbind();
$(input.form).unbind(".autocomplete");
});
function selectCurrent() {
var selected = select.selected();
if( !selected )
return false;
var v = selected.result;
previousValue = v;
if ( options.multiple ) {
var words = trimWords($input.val());
if ( words.length > 1 ) {
var seperator = options.multipleSeparator.length;
var cursorAt = $(input).selection().start;
var wordAt, progress = 0;
$.each(words, function(i, word) {
progress += word.length;
if (cursorAt <= progress) {
wordAt = i;
return false;
}
progress += seperator;
});
words[wordAt] = v;
// TODO this should set the cursor to the right position, but it gets overriden somewhere
//$.Autocompleter.Selection(input, progress + seperator, progress + seperator);
v = words.join( options.multipleSeparator );
}
v += options.multipleSeparator;
}
$input.val(v);
hideResultsNow();
$input.trigger("result", [selected.data, selected.value]);
return true;
}
function onChange(crap, skipPrevCheck) {
if( lastKeyPressCode == KEY.DEL ) {
select.hide();
return;
}
var currentValue = $input.val();
if ( !skipPrevCheck && currentValue == previousValue )
return;
previousValue = currentValue;
currentValue = lastWord(currentValue);
if ( currentValue.length >= options.minChars) {
$input.addClass(options.loadingClass);
if (!options.matchCase)
currentValue = currentValue.toLowerCase();
request(currentValue, receiveData, hideResultsNow);
} else {
stopLoading();
select.hide();
}
};
function trimWords(value) {
if (!value)
return [""];
if (!options.multiple)
return [$.trim(value)];
return $.map(value.split(options.multipleSeparator), function(word) {
return $.trim(value).length ? $.trim(word) : null;
});
}
function lastWord(value) {
if ( !options.multiple )
return value;
var words = trimWords(value);
if (words.length == 1)
return words[0];
var cursorAt = $(input).selection().start;
if (cursorAt == value.length) {
words = trimWords(value)
} else {
words = trimWords(value.replace(value.substring(cursorAt), ""));
}
return words[words.length - 1];
}
// fills in the input box w/the first match (assumed to be the best match)
// q: the term entered
// sValue: the first matching result
function autoFill(q, sValue){
// autofill in the complete box w/the first match as long as the user hasn't entered in more data
// if the last user key pressed was backspace, don't autofill
if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
// fill in the value (keep the case the user has typed)
$input.val($input.val() + sValue.substring(lastWord(previousValue).length));
// select the portion of the value not typed by the user (so the next character will erase)
$(input).selection(previousValue.length, previousValue.length + sValue.length);
}
};
function hideResults() {
clearTimeout(timeout);
timeout = setTimeout(hideResultsNow, 200);
};
function hideResultsNow() {
var wasVisible = select.visible();
select.hide();
clearTimeout(timeout);
stopLoading();
if (options.mustMatch) {
// call search and run callback
$input.search(
function (result){
// if no value found, clear the input box
if( !result ) {
if (options.multiple) {
var words = trimWords($input.val()).slice(0, -1);
$input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
}
else {
$input.val( "" );
$input.trigger("result", null);
}
}
}
);
}
};
function receiveData(q, data) {
if ( data && data.length && hasFocus ) {
stopLoading();
select.display(data, q);
autoFill(q, data[0].value);
select.show();
} else {
hideResultsNow();
}
};
function request(term, success, failure) {
if (!options.matchCase)
term = term.toLowerCase();
var data = cache.load(term);
// recieve the cached data
if (data) {
if(data.length) {
success(term, data);
}
else{
var parsed = options.parse && options.parse(options.noRecord) || parse(options.noRecord);
success(term,parsed);
}
// if an AJAX url has been supplied, try loading the data now
} else if( (typeof options.url == "string") && (options.url.length > 0) ){
var extraParams = {
timestamp: +new Date()
};
$.each(options.extraParams, function(key, param) {
extraParams[key] = typeof param == "function" ? param() : param;
});
$.ajax({
// try to leverage ajaxQueue plugin to abort previous requests
mode: "abort",
// limit abortion to this input
port: "autocomplete" + input.name,
dataType: options.dataType,
url: options.url,
data: $.extend({
q: lastWord(term),
limit: options.max
}, extraParams),
success: function(data) {
var parsed = options.parse && options.parse(data) || parse(data);
cache.add(term, parsed);
success(term, parsed);
}
});
} else {
// if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
select.emptyList();
if(globalFailure != null) {
globalFailure();
}
else {
failure(term);
}
}
};
function parse(data) {
var parsed = [];
var rows = data.split("\n");
for (var i=0; i < rows.length; i++) {
var row = $.trim(rows[i]);
if (row) {
row = row.split("|");
parsed[parsed.length] = {
data: row,
value: row[0],
result: options.formatResult && options.formatResult(row, row[0]) || row[0]
};
}
}
return parsed;
};
function stopLoading() {
$input.removeClass(options.loadingClass);
};
};
$.Autocompleter.defaults = {
inputClass: "ac_input",
resultsClass: "ac_results",
loadingClass: "ac_loading",
minChars: 1,
delay: 400,
matchCase: false,
matchSubset: true,
matchContains: false,
cacheLength: 100,
max: 1000,
mustMatch: false,
extraParams: {},
selectFirst: true,
formatItem: function(row) { return row[0]; },
formatMatch: null,
autoFill: false,
width: 0,
multiple: false,
multipleSeparator: " ",
inputFocus: true,
clickFire: false,
highlight: function(value, term) {
return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
},
scroll: true,
scrollHeight: 180,
scrollJumpPosition: true
};
$.Autocompleter.Cache = function(options) {
var data = {};
var length = 0;
function matchSubset(s, sub) {
if (!options.matchCase)
s = s.toLowerCase();
var i = s.indexOf(sub);
if (options.matchContains == "word"){
i = s.toLowerCase().search("\\b" + sub.toLowerCase());
}
if (i == -1) return false;
return i == 0 || options.matchContains;
};
function add(q, value) {
if (length > options.cacheLength){
flush();
}
if (!data[q]){
length++;
}
data[q] = value;
}
function populate(){
if( !options.data ) return false;
// track the matches
var stMatchSets = {},
nullData = 0;
// no url was specified, we need to adjust the cache length to make sure it fits the local data store
if( !options.url ) options.cacheLength = 1;
// track all options for minChars = 0
stMatchSets[""] = [];
// loop through the array and create a lookup structure
for ( var i = 0, ol = options.data.length; i < ol; i++ ) {
var rawValue = options.data[i];
// if rawValue is a string, make an array otherwise just reference the array
rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;
var value = options.formatMatch(rawValue, i+1, options.data.length);
if ( typeof(value) === 'undefined' || value === false )
continue;
var firstChar = value.charAt(0).toLowerCase();
// if no lookup array for this character exists, look it up now
if( !stMatchSets[firstChar] )
stMatchSets[firstChar] = [];
// if the match is a string
var row = {
value: value,
data: rawValue,
result: options.formatResult && options.formatResult(rawValue) || value
};
// push the current match into the set list
stMatchSets[firstChar].push(row);
// keep track of minChars zero items
if ( nullData++ < options.max ) {
stMatchSets[""].push(row);
}
};
// add the data items to the cache
$.each(stMatchSets, function(i, value) {
// increase the cache size
options.cacheLength++;
// add to the cache
add(i, value);
});
}
// populate any existing data
setTimeout(populate, 25);
function flush(){
data = {};
length = 0;
}
return {
flush: flush,
add: add,
populate: populate,
load: function(q) {
if (!options.cacheLength || !length)
return null;
/*
* if dealing w/local data and matchContains than we must make sure
* to loop through all the data collections looking for matches
*/
if( !options.url && options.matchContains ){
// track all matches
var csub = [];
// loop through all the data grids for matches
for( var k in data ){
// don't search through the stMatchSets[""] (minChars: 0) cache
// this prevents duplicates
if( k.length > 0 ){
var c = data[k];
$.each(c, function(i, x) {
// if we've got a match, add it to the array
if (matchSubset(x.value, q)) {
csub.push(x);
}
});
}
}
return csub;
} else
// if the exact item exists, use it
if (data[q]){
return data[q];
} else
if (options.matchSubset) {
for (var i = q.length - 1; i >= options.minChars; i--) {
var c = data[q.substr(0, i)];
if (c) {
var csub = [];
$.each(c, function(i, x) {
if (matchSubset(x.value, q)) {
csub[csub.length] = x;
}
});
return csub;
}
}
}
return null;
}
};
};
$.Autocompleter.Select = function (options, input, select, config) {
var CLASSES = {
ACTIVE: "ac_over"
};
var listItems,
active = -1,
data,
term = "",
needsInit = true,
element,
list;
// Create results
function init() {
if (!needsInit)
return;
element = $("<div/>")
.hide()
.addClass(options.resultsClass)
.css("position", "absolute")
.appendTo(document.body)
.hover(function(event) {
// Browsers except FF do not fire mouseup event on scrollbars, resulting in mouseDownOnSelect remaining true, and results list not always hiding.
if($(this).is(":visible")) {
input.focus();
}
config.mouseDownOnSelect = false;
});
list = $("<ul/>").appendTo(element).mouseover( function(event) {
if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
$(target(event)).addClass(CLASSES.ACTIVE);
}
}).click(function(event) {
$(target(event)).addClass(CLASSES.ACTIVE);
select();
if( options.inputFocus )
input.focus();
return false;
}).mousedown(function() {
config.mouseDownOnSelect = true;
}).mouseup(function() {
config.mouseDownOnSelect = false;
});
if( options.width > 0 )
element.css("width", options.width);
needsInit = false;
}
function target(event) {
var element = event.target;
while(element && element.tagName != "LI")
element = element.parentNode;
// more fun with IE, sometimes event.target is empty, just ignore it then
if(!element)
return [];
return element;
}
function moveSelect(step) {
listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
movePosition(step);
var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
if(options.scroll) {
var offset = 0;
listItems.slice(0, active).each(function() {
offset += this.offsetHeight;
});
if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
} else if(offset < list.scrollTop()) {
list.scrollTop(offset);
}
}
};
function movePosition(step) {
if (options.scrollJumpPosition || (!options.scrollJumpPosition && !((step < 0 && active == 0) || (step > 0 && active == listItems.size() - 1)) )) {
active += step;
if (active < 0) {
active = listItems.size() - 1;
} else if (active >= listItems.size()) {
active = 0;
}
}
}
function limitNumberOfItems(available) {
return options.max && options.max < available
? options.max
: available;
}
function fillList() {
list.empty();
var max = limitNumberOfItems(data.length);
for (var i=0; i < max; i++) {
if (!data[i])
continue;
var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
if ( formatted === false )
continue;
var li = $("<li/>").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
$.data(li, "ac_data", data[i]);
}
listItems = list.find("li");
if ( options.selectFirst ) {
listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
active = 0;
}
// apply bgiframe if available
if ( $.fn.bgiframe )
list.bgiframe();
}
return {
display: function(d, q) {
init();
data = d;
term = q;
fillList();
},
next: function() {
moveSelect(1);
},
prev: function() {
moveSelect(-1);
},
pageUp: function() {
if (active != 0 && active - 8 < 0) {
moveSelect( -active );
} else {
moveSelect(-8);
}
},
pageDown: function() {
if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
moveSelect( listItems.size() - 1 - active );
} else {
moveSelect(8);
}
},
hide: function() {
element && element.hide();
listItems && listItems.removeClass(CLASSES.ACTIVE);
active = -1;
},
visible : function() {
return element && element.is(":visible");
},
current: function() {
return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
},
show: function() {
var offset = $(input).offset();
element.css({
width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
top: offset.top + input.offsetHeight,
left: offset.left - 9
}).show();
if(options.scroll) {
list.scrollTop(0);
list.css({
maxHeight: options.scrollHeight,
overflow: 'auto'
});
if(navigator.userAgent.indexOf("MSIE") != -1 && typeof document.body.style.maxHeight === "undefined") {
var listHeight = 0;
listItems.each(function() {
listHeight += this.offsetHeight;
});
var scrollbarsVisible = listHeight > options.scrollHeight;
list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
if (!scrollbarsVisible) {
// IE doesn't recalculate width when scrollbar disappears
listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );
}
}
}
},
selected: function() {
var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
return selected && selected.length && $.data(selected[0], "ac_data");
},
emptyList: function (){
list && list.empty();
},
unbind: function() {
element && element.remove();
}
};
};
$.fn.selection = function(start, end) {
if (start !== undefined) {
return this.each(function() {
if( this.createTextRange ){
var selRange = this.createTextRange();
if (end === undefined || start == end) {
selRange.move("character", start);
selRange.select();
} else {
selRange.collapse(true);
selRange.moveStart("character", start);
selRange.moveEnd("character", end);
selRange.select();
}
} else if( this.setSelectionRange ){
this.setSelectionRange(start, end);
} else if( this.selectionStart ){
this.selectionStart = start;
this.selectionEnd = end;
}
});
}
var field = this[0];
if ( field.createTextRange ) {
var range = document.selection.createRange(),
orig = field.value,
teststring = "<->",
textLength = range.text.length;
range.text = teststring;
var caretAt = field.value.indexOf(teststring);
field.value = orig;
this.selection(caretAt, caretAt + textLength);
return {
start: caretAt,
end: caretAt + textLength
}
} else if( field.selectionStart !== undefined ){
return {
start: field.selectionStart,
end: field.selectionEnd
}
}
};
})(jQuery);
$.fn.showWhenScrolled=function(){
var self = this;
this.init = function(){
self.each(function(){
var self_top = $(this).offset().top;
var scroll_top = $(window).scrollTop();
var win_height = $(window).height();
var frame = $(this).find('iframe');
if(scroll_top > (self_top - win_height)){
if(!frame.attr('src')){
frame.attr({src:frame.attr('title')});
}
}
});
};
$(window).scroll(function(){
self.init();
}).resize(function(){
self.init();
});
self.init();
};
$('.youtube-container').showWhenScrolled();
// jQuery
$(document).ready(function() {
// code
})
// Vanilla
document.addEventListener('DOMContentLoaded', function() {
// code
})
// jQuery
$('a').click(function() {
// code…
})
// Vanilla
[].forEach.call(document.querySelectorAll('a'), function(el) {
el.addEventListener('click', function() {
// code…
})
})
// jQuery
var divs = $('div')
// Vanilla
var divs = document.querySelectorAll('div')
// jQuery
var newDiv = $('<div/>')
// Vanilla
var newDiv = document.createElement('div')
// jQuery
$('img').filter(':first').attr('alt', 'My image')
// Vanilla
document.querySelector('img').setAttribute('alt', 'My image')
// jQuery
newDiv.addClass('foo')
// Vanilla
newDiv.classList.add('foo')
// jQuery
newDiv.toggleClass('foo')
// Vanilla
newDiv.classList.toggle('foo')
// jQuery
$('body').append($('<p/>'))
// Vanilla
document.body.appendChild(document.createElement('p'))
// jQuery
var clonedElement = $('#about').clone()
// Vanilla
var clonedElement = document.getElementById('about').cloneNode(true)
// jQuery
$('#wrap').empty()
// Vanilla
var wrap = document.getElementById('wrap')
while(wrap.firstChild) wrap.removeChild(wrap.firstChild)
// jQuery
var parent = $('#about').parent()
// Vanilla
var parent = document.getElementById('about').parentNode
// jQuery
if($('#wrap').is(':empty'))
// Vanilla
if(!document.getElementById('wrap').hasChildNodes())
// jQuery
var nextElement = $('#wrap').next()
// Vanilla
var nextElement = document.getElementById('wrap').nextSibling
// jQuery
$.get('//example.com', function (data) {
// code
})
// Vanilla
var httpRequest = new XMLHttpRequest()
httpRequest.onreadystatechange = function (data) {
// code
}
httpRequest.open('GET', url)
httpRequest.send()
// jQuery
$.post('//example.com', { username: username }, function (data) {
// code
})
// Vanilla
var httpRequest = new XMLHttpRequest()
httpRequest.onreadystatechange = function (data) {
// code
}
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
httpRequest.open('POST', url)
httpRequest.send('username=' + encodeURIComponent(username))
// jQuery
$.getJSON('//openexchangerates.org/latest.json?callback=?', function (data) {
// code
})
// Vanilla
function success(data) {
// code
}
var scr = document.createElement('script')
scr.src = '//openexchangerates.org/latest.json?callback=formatCurrency'
document.body.appendChild(scr)
Here are a few additional references demonstrating vanilla javascript equivalents of jquery methods:
Also, see the two part series showing equivalents for ...
[Events, Ajax and Utilities](http://www.sitepoint.com/jquery-vs-raw- javascript-3-events-ajax/)
/**
* Easy slider plug-in pro jQuery
*
* (c) 2012 Drahomír Hanák
*/
(function( $ ) {
var inited = false;
// Volatelné funkce
var methods = {
// Funkce nastaví aktivní slide (Index od 0 do počtu obrázků v galerii) -
active: function( index, direction ) {
// Nastavíme rychlost
speed = $(this).data('speed') || 800;
// Nastavíme směry efektů
directionHide = direction || 'left';
directionShow = directionHide == 'left' ? 'right' : 'left';
// Skryjeme aktivní položku
$(this).find('li.active').hide('slide', { direction: directionHide }, speed);
// Všem položkám odstraníme třídu .active
$(this).find('li').removeClass('active');
// Načteme activní slide
var slide = $(this).find('li').get(index) || false;
// Zobrazíme ho
$(slide).addClass('active').show('slide', { direction: directionShow }, speed);
// Vrátíme aktivní element
return $(this).find('li').get(index) || false;
},
// Přesune se na další slide
next: function() {
// Najdeme další element a zjistíme jeho index, ke kterému přičteme +1
var index = ($(this).find('li.active').index()+1);
// nebo = imho cistci zpusob
//methods.active.call(this, $(this).find('li').get(index) ? index : 0);
// zpusob autora viz nizie ani ten return tam byt nemusi ...
//$(this).easySlider("active", ($(this).find('li').get(index) ? index : 0));
// Aktivujeme tento slide, pokud existuje. Pokud ne, automaticky se přesuneme na první (nultý)
return $(this).easySlider("active", ($(this).find('li').get(index) ? index : 0));
},
// Přesune se na předchozí slide
prev: function() {
var index = $(this).find('li.active').index()-1 < 0 ? $(this).find('li').length-1 : $(this).find('li.active').index()-1;
// Aktivujeme slide s títo indexem
return $(this).easySlider("active", index, 'right');
},
// Vstupní funkce plug-inu
init: function( o ) {
// Získáme nastavené volby plug-inu
o = $.extend({}, $.fn.easySlider.defaults, o);
// Uložíme si aktuální kontext funkce (element plug-inu)
var $that = $(this);
// Pokud už jsme jednou inicializovali element, nebudeme to přece dělat znova
if ( inited ) return false;
// Funkce po kliknutí na šipky
var left_click = function( e ) {
e = $.event.fix(e);
e.preventDefault();
$that.easySlider("prev");
}, right_click = function( e ) {
e = $.event.fix(e);
e.preventDefault();
$that.easySlider("next");
};
// Projdeme a vrátíme všechny elementy, kterým bylo předáno zpracování plug-inu
return this.each(function() {
// Najdeme všechny obrázky ve slideru
var $items = $(this).find('li'),
count = $items.length,
$self = $(this);
// Všechny je skryjeme a pozicujeme absolutně
$items.css({ display: 'none', position: 'absolute' });
// Vložíme seznamu třídu pro přístupnější manipulování v CSS
$self.addClass('easySlider-content').data('speed', o.speed);
// Aktivujeme první element
$($items.get(o.active)).addClass("active");
// Vytvoříme si postraní šipky pro posun slideru
var $arrowLeft = $('<a />').attr('href', '#left').addClass('arrowLeft');
var $arrowRight = $('<a />').attr('href', '#right').addClass('arrowRight');
// Nastavíme callback na kliknutí
$arrowLeft.bind('click', left_click);
$arrowRight.bind('click', right_click);
// Vložíme je před seznam slidů
$self.before( $arrowRight );
$self.before( $arrowLeft );
});
}
};
// Vstupní funkce plug-inu
$.fn.easySlider = function( method ) {
// Pokud máme jméno funkce, kterou chceme zavolat
if ( methods[method] ) {
// Zavoláme danou funkci se všemi ostatními předanými argumenty plug-inu
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if ( typeof method == 'object' || !method ) {
// Pokud ne, zavoláme inicializační metodu
return methods.init.apply(this, arguments);
} else {
// Pokud metoda neexistuje, vypíšeme chybu
$.error('Metoda ' + method + ' neexistuje v plug-inu jQuery.easySlider');
}
};
// Defaultní nastavení
$.fn.easySlider.defaults = {
// Index prvního aktivního prvku slideru
active: 1,
// Rychlost přechodu v milisekundách
speed: 500
};
})( jQuery );
/*
* jQuery Plugin: Tokenizing Autocomplete Text Entry
* Version 1.6.2
*
* Copyright (c) 2009 James Smith (http://loopj.com)
* Licensed jointly under the GPL and MIT licenses,
* choose which one suits your project best!
*
*/
;(function ($) {
var DEFAULT_SETTINGS = {
// Search settings
method: "GET",
queryParam: "q",
searchDelay: 300,
minChars: 1,
propertyToSearch: "name",
jsonContainer: null,
contentType: "json",
excludeCurrent: false,
excludeCurrentParameter: "x",
// Prepopulation settings
prePopulate: null,
processPrePopulate: false,
// Display settings
hintText: "Type in a search term",
noResultsText: "No results",
searchingText: "Searching...",
deleteText: "×",
animateDropdown: true,
placeholder: null,
theme: null,
zindex: 999,
resultsLimit: null,
enableHTML: false,
resultsFormatter: function(item) {
var string = item[this.propertyToSearch];
return "<li>" + (this.enableHTML ? string : _escapeHTML(string)) + "</li>";
},
tokenFormatter: function(item) {
var string = item[this.propertyToSearch];
return "<li><p>" + (this.enableHTML ? string : _escapeHTML(string)) + "</p></li>";
},
// Tokenization settings
tokenLimit: null,
tokenDelimiter: ",",
preventDuplicates: false,
tokenValue: "id",
// Behavioral settings
allowFreeTagging: false,
allowTabOut: false,
autoSelectFirstResult: false,
// Callbacks
onResult: null,
onCachedResult: null,
onAdd: null,
onFreeTaggingAdd: null,
onDelete: null,
onReady: null,
// Other settings
idPrefix: "token-input-",
// Keep track if the input is currently in disabled mode
disabled: false
};
// Default classes to use when theming
var DEFAULT_CLASSES = {
tokenList : "token-input-list",
token : "token-input-token",
tokenReadOnly : "token-input-token-readonly",
tokenDelete : "token-input-delete-token",
selectedToken : "token-input-selected-token",
highlightedToken : "token-input-highlighted-token",
dropdown : "token-input-dropdown",
dropdownItem : "token-input-dropdown-item",
dropdownItem2 : "token-input-dropdown-item2",
selectedDropdownItem : "token-input-selected-dropdown-item",
inputToken : "token-input-input-token",
focused : "token-input-focused",
disabled : "token-input-disabled"
};
// Input box position "enum"
var POSITION = {
BEFORE : 0,
AFTER : 1,
END : 2
};
// Keys "enum"
var KEY = {
BACKSPACE : 8,
TAB : 9,
ENTER : 13,
ESCAPE : 27,
SPACE : 32,
PAGE_UP : 33,
PAGE_DOWN : 34,
END : 35,
HOME : 36,
LEFT : 37,
UP : 38,
RIGHT : 39,
DOWN : 40,
NUMPAD_ENTER : 108,
COMMA : 188
};
var HTML_ESCAPES = {
'&' : '&',
'<' : '<',
'>' : '>',
'"' : '"',
"'" : ''',
'/' : '/'
};
var HTML_ESCAPE_CHARS = /[&<>"'\/]/g;
function coerceToString(val) {
return String((val === null || val === undefined) ? '' : val);
}
function _escapeHTML(text) {
return coerceToString(text).replace(HTML_ESCAPE_CHARS, function(match) {
return HTML_ESCAPES[match];
});
}
// Additional public (exposed) methods
var methods = {
init: function(url_or_data_or_function, options) {
var settings = $.extend({}, DEFAULT_SETTINGS, options || {});
return this.each(function () {
$(this).data("settings", settings);
$(this).data("tokenInputObject", new $.TokenList(this, url_or_data_or_function, settings));
});
},
clear: function() {
this.data("tokenInputObject").clear();
return this;
},
add: function(item) {
this.data("tokenInputObject").add(item);
return this;
},
remove: function(item) {
this.data("tokenInputObject").remove(item);
return this;
},
get: function() {
return this.data("tokenInputObject").getTokens();
},
toggleDisabled: function(disable) {
this.data("tokenInputObject").toggleDisabled(disable);
return this;
},
setOptions: function(options){
$(this).data("settings", $.extend({}, $(this).data("settings"), options || {}));
return this;
},
destroy: function () {
if (this.data("tokenInputObject")) {
this.data("tokenInputObject").clear();
var tmpInput = this;
var closest = this.parent();
closest.empty();
tmpInput.show();
closest.append(tmpInput);
return tmpInput;
}
}
};
// Expose the .tokenInput function to jQuery as a plugin
$.fn.tokenInput = function (method) {
// Method calling and initialization logic
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else {
return methods.init.apply(this, arguments);
}
};
// TokenList class for each input
$.TokenList = function (input, url_or_data, settings) {
//
// Initialization
//
// Configure the data source
if (typeof(url_or_data) === "string" || typeof(url_or_data) === "function") {
// Set the url to query against
$(input).data("settings").url = url_or_data;
// If the URL is a function, evaluate it here to do our initalization work
var url = computeURL();
// Make a smart guess about cross-domain if it wasn't explicitly specified
if ($(input).data("settings").crossDomain === undefined && typeof url === "string") {
if(url.indexOf("://") === -1) {
$(input).data("settings").crossDomain = false;
} else {
$(input).data("settings").crossDomain = (location.href.split(/\/+/g)[1] !== url.split(/\/+/g)[1]);
}
}
} else if (typeof(url_or_data) === "object") {
// Set the local data to search through
$(input).data("settings").local_data = url_or_data;
}
// Build class names
if($(input).data("settings").classes) {
// Use custom class names
$(input).data("settings").classes = $.extend({}, DEFAULT_CLASSES, $(input).data("settings").classes);
} else if($(input).data("settings").theme) {
// Use theme-suffixed default class names
$(input).data("settings").classes = {};
$.each(DEFAULT_CLASSES, function(key, value) {
$(input).data("settings").classes[key] = value + "-" + $(input).data("settings").theme;
});
} else {
$(input).data("settings").classes = DEFAULT_CLASSES;
}
// Save the tokens
var saved_tokens = [];
// Keep track of the number of tokens in the list
var token_count = 0;
// Basic cache to save on db hits
var cache = new $.TokenList.Cache();
// Keep track of the timeout, old vals
var timeout;
var input_val;
// Create a new text input an attach keyup events
var input_box = $("<input type=\"text\" autocomplete=\"off\" autocapitalize=\"off\"/>")
.css({
outline: "none"
})
.attr("id", $(input).data("settings").idPrefix + input.id)
.focus(function () {
if ($(input).data("settings").disabled) {
return false;
} else
if ($(input).data("settings").tokenLimit === null || $(input).data("settings").tokenLimit !== token_count) {
show_dropdown_hint();
}
token_list.addClass($(input).data("settings").classes.focused);
})
.blur(function () {
hide_dropdown();
if ($(input).data("settings").allowFreeTagging) {
add_freetagging_tokens();
}
$(this).val("");
token_list.removeClass($(input).data("settings").classes.focused);
})
.bind("keyup keydown blur update", resize_input)
.keydown(function (event) {
var previous_token;
var next_token;
switch(event.keyCode) {
case KEY.LEFT:
case KEY.RIGHT:
case KEY.UP:
case KEY.DOWN:
if(this.value.length === 0) {
previous_token = input_token.prev();
next_token = input_token.next();
if((previous_token.length && previous_token.get(0) === selected_token) ||
(next_token.length && next_token.get(0) === selected_token)) {
// Check if there is a previous/next token and it is selected
if(event.keyCode === KEY.LEFT || event.keyCode === KEY.UP) {
deselect_token($(selected_token), POSITION.BEFORE);
} else {
deselect_token($(selected_token), POSITION.AFTER);
}
} else if((event.keyCode === KEY.LEFT || event.keyCode === KEY.UP) && previous_token.length) {
// We are moving left, select the previous token if it exists
select_token($(previous_token.get(0)));
} else if((event.keyCode === KEY.RIGHT || event.keyCode === KEY.DOWN) && next_token.length) {
// We are moving right, select the next token if it exists
select_token($(next_token.get(0)));
}
} else {
var dropdown_item = null;
if (event.keyCode === KEY.DOWN || event.keyCode === KEY.RIGHT) {
dropdown_item = $(dropdown).find('li').first();
if (selected_dropdown_item) {
dropdown_item = $(selected_dropdown_item).next();
}
} else {
dropdown_item = $(dropdown).find('li').last();
if (selected_dropdown_item) {
dropdown_item = $(selected_dropdown_item).prev();
}
}
select_dropdown_item(dropdown_item);
}
break;
case KEY.BACKSPACE:
previous_token = input_token.prev();
if (this.value.length === 0) {
if (selected_token) {
delete_token($(selected_token));
hiddenInput.change();
} else if(previous_token.length) {
select_token($(previous_token.get(0)));
}
return false;
} else if($(this).val().length === 1) {
hide_dropdown();
} else {
// set a timeout just long enough to let this function finish.
setTimeout(function(){ do_search(); }, 5);
}
break;
case KEY.TAB:
case KEY.ENTER:
case KEY.NUMPAD_ENTER:
case KEY.COMMA:
if(selected_dropdown_item) {
add_token($(selected_dropdown_item).data("tokeninput"));
hiddenInput.change();
} else {
if ($(input).data("settings").allowFreeTagging) {
if($(input).data("settings").allowTabOut && $(this).val() === "") {
return true;
} else {
add_freetagging_tokens();
}
} else {
$(this).val("");
if($(input).data("settings").allowTabOut) {
return true;
}
}
event.stopPropagation();
event.preventDefault();
}
return false;
case KEY.ESCAPE:
hide_dropdown();
return true;
default:
if (String.fromCharCode(event.which)) {
// set a timeout just long enough to let this function finish.
setTimeout(function(){ do_search(); }, 5);
}
break;
}
});
// Keep reference for placeholder
if (settings.placeholder) {
input_box.attr("placeholder", settings.placeholder);
}
// Keep a reference to the original input box
var hiddenInput = $(input)
.hide()
.val("")
.focus(function () {
focusWithTimeout(input_box);
})
.blur(function () {
input_box.blur();
//return the object to this can be referenced in the callback functions.
return hiddenInput;
})
;
// Keep a reference to the selected token and dropdown item
var selected_token = null;
var selected_token_index = 0;
var selected_dropdown_item = null;
// The list to store the token items in
var token_list = $("<ul />")
.addClass($(input).data("settings").classes.tokenList)
.click(function (event) {
var li = $(event.target).closest("li");
if(li && li.get(0) && $.data(li.get(0), "tokeninput")) {
toggle_select_token(li);
} else {
// Deselect selected token
if(selected_token) {
deselect_token($(selected_token), POSITION.END);
}
// Focus input box
focusWithTimeout(input_box);
}
})
.mouseover(function (event) {
var li = $(event.target).closest("li");
if(li && selected_token !== this) {
li.addClass($(input).data("settings").classes.highlightedToken);
}
})
.mouseout(function (event) {
var li = $(event.target).closest("li");
if(li && selected_token !== this) {
li.removeClass($(input).data("settings").classes.highlightedToken);
}
})
.insertBefore(hiddenInput);
// The token holding the input box
var input_token = $("<li />")
.addClass($(input).data("settings").classes.inputToken)
.appendTo(token_list)
.append(input_box);
// The list to store the dropdown items in
var dropdown = $("<div/>")
.addClass($(input).data("settings").classes.dropdown)
.appendTo("body")
.hide();
// Magic element to help us resize the text input
var input_resizer = $("<tester/>")
.insertAfter(input_box)
.css({
position: "absolute",
top: -9999,
left: -9999,
width: "auto",
fontSize: input_box.css("fontSize"),
fontFamily: input_box.css("fontFamily"),
fontWeight: input_box.css("fontWeight"),
letterSpacing: input_box.css("letterSpacing"),
whiteSpace: "nowrap"
});
// Pre-populate list if items exist
hiddenInput.val("");
var li_data = $(input).data("settings").prePopulate || hiddenInput.data("pre");
if ($(input).data("settings").processPrePopulate && $.isFunction($(input).data("settings").onResult)) {
li_data = $(input).data("settings").onResult.call(hiddenInput, li_data);
}
if (li_data && li_data.length) {
$.each(li_data, function (index, value) {
insert_token(value);
checkTokenLimit();
input_box.attr("placeholder", null)
});
}
// Check if widget should initialize as disabled
if ($(input).data("settings").disabled) {
toggleDisabled(true);
}
// Initialization is done
if (typeof($(input).data("settings").onReady) === "function") {
$(input).data("settings").onReady.call();
}
//
// Public functions
//
this.clear = function() {
token_list.children("li").each(function() {
if ($(this).children("input").length === 0) {
delete_token($(this));
}
});
};
this.add = function(item) {
add_token(item);
};
this.remove = function(item) {
token_list.children("li").each(function() {
if ($(this).children("input").length === 0) {
var currToken = $(this).data("tokeninput");
var match = true;
for (var prop in item) {
if (item[prop] !== currToken[prop]) {
match = false;
break;
}
}
if (match) {
delete_token($(this));
}
}
});
};
this.getTokens = function() {
return saved_tokens;
};
this.toggleDisabled = function(disable) {
toggleDisabled(disable);
};
// Resize input to maximum width so the placeholder can be seen
resize_input();
//
// Private functions
//
function escapeHTML(text) {
return $(input).data("settings").enableHTML ? text : _escapeHTML(text);
}
// Toggles the widget between enabled and disabled state, or according
// to the [disable] parameter.
function toggleDisabled(disable) {
if (typeof disable === 'boolean') {
$(input).data("settings").disabled = disable
} else {
$(input).data("settings").disabled = !$(input).data("settings").disabled;
}
input_box.attr('disabled', $(input).data("settings").disabled);
token_list.toggleClass($(input).data("settings").classes.disabled, $(input).data("settings").disabled);
// if there is any token selected we deselect it
if(selected_token) {
deselect_token($(selected_token), POSITION.END);
}
hiddenInput.attr('disabled', $(input).data("settings").disabled);
}
function checkTokenLimit() {
if($(input).data("settings").tokenLimit !== null && token_count >= $(input).data("settings").tokenLimit) {
input_box.hide();
hide_dropdown();
return;
}
}
function resize_input() {
if(input_val === (input_val = input_box.val())) {return;}
// Get width left on the current line
var width_left = token_list.width() - input_box.offset().left - token_list.offset().left;
// Enter new content into resizer and resize input accordingly
input_resizer.html(_escapeHTML(input_val) || _escapeHTML(settings.placeholder));
// Get maximum width, minimum the size of input and maximum the widget's width
input_box.width(Math.min(token_list.width(),
Math.max(width_left, input_resizer.width() + 30)));
}
function add_freetagging_tokens() {
var value = $.trim(input_box.val());
var tokens = value.split($(input).data("settings").tokenDelimiter);
$.each(tokens, function(i, token) {
if (!token) {
return;
}
if ($.isFunction($(input).data("settings").onFreeTaggingAdd)) {
token = $(input).data("settings").onFreeTaggingAdd.call(hiddenInput, token);
}
var object = {};
object[$(input).data("settings").tokenValue] = object[$(input).data("settings").propertyToSearch] = token;
add_token(object);
});
}
// Inner function to a token to the list
function insert_token(item) {
var $this_token = $($(input).data("settings").tokenFormatter(item));
var readonly = item.readonly === true;
if(readonly) $this_token.addClass($(input).data("settings").classes.tokenReadOnly);
$this_token.addClass($(input).data("settings").classes.token).insertBefore(input_token);
// The 'delete token' button
if(!readonly) {
$("<span>" + $(input).data("settings").deleteText + "</span>")
.addClass($(input).data("settings").classes.tokenDelete)
.appendTo($this_token)
.click(function () {
if (!$(input).data("settings").disabled) {
delete_token($(this).parent());
hiddenInput.change();
return false;
}
});
}
// Store data on the token
var token_data = item;
$.data($this_token.get(0), "tokeninput", item);
// Save this token for duplicate checking
saved_tokens = saved_tokens.slice(0,selected_token_index).concat([token_data]).concat(saved_tokens.slice(selected_token_index));
selected_token_index++;
// Update the hidden input
update_hiddenInput(saved_tokens, hiddenInput);
token_count += 1;
// Check the token limit
if($(input).data("settings").tokenLimit !== null && token_count >= $(input).data("settings").tokenLimit) {
input_box.hide();
hide_dropdown();
}
return $this_token;
}
// Add a token to the token list based on user input
function add_token (item) {
var callback = $(input).data("settings").onAdd;
// See if the token already exists and select it if we don't want duplicates
if(token_count > 0 && $(input).data("settings").preventDuplicates) {
var found_existing_token = null;
token_list.children().each(function () {
var existing_token = $(this);
var existing_data = $.data(existing_token.get(0), "tokeninput");
if(existing_data && existing_data[settings.tokenValue] === item[settings.tokenValue]) {
found_existing_token = existing_token;
return false;
}
});
if(found_existing_token) {
select_token(found_existing_token);
input_token.insertAfter(found_existing_token);
focusWithTimeout(input_box);
return;
}
}
// Squeeze input_box so we force no unnecessary line break
input_box.width(1);
// Insert the new tokens
if($(input).data("settings").tokenLimit == null || token_count < $(input).data("settings").tokenLimit) {
insert_token(item);
// Remove the placeholder so it's not seen after you've added a token
input_box.attr("placeholder", null);
checkTokenLimit();
}
// Clear input box
input_box.val("");
// Don't show the help dropdown, they've got the idea
hide_dropdown();
// Execute the onAdd callback if defined
if($.isFunction(callback)) {
callback.call(hiddenInput,item);
}
}
// Select a token in the token list
function select_token (token) {
if (!$(input).data("settings").disabled) {
token.addClass($(input).data("settings").classes.selectedToken);
selected_token = token.get(0);
// Hide input box
input_box.val("");
// Hide dropdown if it is visible (eg if we clicked to select token)
hide_dropdown();
}
}
// Deselect a token in the token list
function deselect_token (token, position) {
token.removeClass($(input).data("settings").classes.selectedToken);
selected_token = null;
if(position === POSITION.BEFORE) {
input_token.insertBefore(token);
selected_token_index--;
} else if(position === POSITION.AFTER) {
input_token.insertAfter(token);
selected_token_index++;
} else {
input_token.appendTo(token_list);
selected_token_index = token_count;
}
// Show the input box and give it focus again
focusWithTimeout(input_box);
}
// Toggle selection of a token in the token list
function toggle_select_token(token) {
var previous_selected_token = selected_token;
if(selected_token) {
deselect_token($(selected_token), POSITION.END);
}
if(previous_selected_token === token.get(0)) {
deselect_token(token, POSITION.END);
} else {
select_token(token);
}
}
// Delete a token from the token list
function delete_token (token) {
// Remove the id from the saved list
var token_data = $.data(token.get(0), "tokeninput");
var callback = $(input).data("settings").onDelete;
var index = token.prevAll().length;
if(index > selected_token_index) index--;
// Delete the token
token.remove();
selected_token = null;
// Show the input box and give it focus again
focusWithTimeout(input_box);
// Remove this token from the saved list
saved_tokens = saved_tokens.slice(0,index).concat(saved_tokens.slice(index+1));
if (saved_tokens.length == 0) {
input_box.attr("placeholder", settings.placeholder)
}
if(index < selected_token_index) selected_token_index--;
// Update the hidden input
update_hiddenInput(saved_tokens, hiddenInput);
token_count -= 1;
if($(input).data("settings").tokenLimit !== null) {
input_box
.show()
.val("");
focusWithTimeout(input_box);
}
// Execute the onDelete callback if defined
if($.isFunction(callback)) {
callback.call(hiddenInput,token_data);
}
}
// Update the hidden input box value
function update_hiddenInput(saved_tokens, hiddenInput) {
var token_values = $.map(saved_tokens, function (el) {
if(typeof $(input).data("settings").tokenValue == 'function')
return $(input).data("settings").tokenValue.call(this, el);
return el[$(input).data("settings").tokenValue];
});
hiddenInput.val(token_values.join($(input).data("settings").tokenDelimiter));
}
// Hide and clear the results dropdown
function hide_dropdown () {
dropdown.hide().empty();
selected_dropdown_item = null;
}
function show_dropdown() {
dropdown
.css({
position: "absolute",
top: token_list.offset().top + token_list.outerHeight(true),
left: token_list.offset().left,
width: token_list.width(),
'z-index': $(input).data("settings").zindex
})
.show();
}
function show_dropdown_searching () {
if($(input).data("settings").searchingText) {
dropdown.html("<p>" + escapeHTML($(input).data("settings").searchingText) + "</p>");
show_dropdown();
}
}
function show_dropdown_hint () {
if($(input).data("settings").hintText) {
dropdown.html("<p>" + escapeHTML($(input).data("settings").hintText) + "</p>");
show_dropdown();
}
}
var regexp_special_chars = new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\-]', 'g');
function regexp_escape(term) {
return term.replace(regexp_special_chars, '\\$&');
}
// Highlight the query part of the search term
function highlight_term(value, term) {
return value.replace(
new RegExp(
"(?![^&;]+;)(?!<[^<>]*)(" + regexp_escape(term) + ")(?![^<>]*>)(?![^&;]+;)",
"gi"
), function(match, p1) {
return "<b>" + escapeHTML(p1) + "</b>";
}
);
}
function find_value_and_highlight_term(template, value, term) {
return template.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + regexp_escape(value) + ")(?![^<>]*>)(?![^&;]+;)", "g"), highlight_term(value, term));
}
// exclude existing tokens from dropdown, so the list is clearer
function excludeCurrent(results) {
if ($(input).data("settings").excludeCurrent) {
var currentTokens = $(input).data("tokenInputObject").getTokens(),
trimmedList = [];
if (currentTokens.length) {
$.each(results, function(index, value) {
var notFound = true;
$.each(currentTokens, function(cIndex, cValue) {
if (value[$(input).data("settings").propertyToSearch] == cValue[$(input).data("settings").propertyToSearch]) {
notFound = false;
return false;
}
});
if (notFound) {
trimmedList.push(value);
}
});
results = trimmedList;
}
}
return results;
}
// Populate the results dropdown with some results
function populateDropdown (query, results) {
// exclude current tokens if configured
results = excludeCurrent(results);
if(results && results.length) {
dropdown.empty();
var dropdown_ul = $("<ul/>")
.appendTo(dropdown)
.mouseover(function (event) {
select_dropdown_item($(event.target).closest("li"));
})
.mousedown(function (event) {
add_token($(event.target).closest("li").data("tokeninput"));
hiddenInput.change();
return false;
})
.hide();
if ($(input).data("settings").resultsLimit && results.length > $(input).data("settings").resultsLimit) {
results = results.slice(0, $(input).data("settings").resultsLimit);
}
$.each(results, function(index, value) {
var this_li = $(input).data("settings").resultsFormatter(value);
this_li = find_value_and_highlight_term(this_li ,value[$(input).data("settings").propertyToSearch], query);
this_li = $(this_li).appendTo(dropdown_ul);
if(index % 2) {
this_li.addClass($(input).data("settings").classes.dropdownItem);
} else {
this_li.addClass($(input).data("settings").classes.dropdownItem2);
}
if(index === 0 && $(input).data("settings").autoSelectFirstResult) {
select_dropdown_item(this_li);
}
$.data(this_li.get(0), "tokeninput", value);
});
show_dropdown();
if($(input).data("settings").animateDropdown) {
dropdown_ul.slideDown("fast");
} else {
dropdown_ul.show();
}
} else {
if($(input).data("settings").noResultsText) {
dropdown.html("<p>" + escapeHTML($(input).data("settings").noResultsText) + "</p>");
show_dropdown();
}
}
}
// Highlight an item in the results dropdown
function select_dropdown_item (item) {
if(item) {
if(selected_dropdown_item) {
deselect_dropdown_item($(selected_dropdown_item));
}
item.addClass($(input).data("settings").classes.selectedDropdownItem);
selected_dropdown_item = item.get(0);
}
}
// Remove highlighting from an item in the results dropdown
function deselect_dropdown_item (item) {
item.removeClass($(input).data("settings").classes.selectedDropdownItem);
selected_dropdown_item = null;
}
// Do a search and show the "searching" dropdown if the input is longer
// than $(input).data("settings").minChars
function do_search() {
var query = input_box.val();
if(query && query.length) {
if(selected_token) {
deselect_token($(selected_token), POSITION.AFTER);
}
if(query.length >= $(input).data("settings").minChars) {
show_dropdown_searching();
clearTimeout(timeout);
timeout = setTimeout(function(){
run_search(query);
}, $(input).data("settings").searchDelay);
} else {
hide_dropdown();
}
}
}
// Do the actual search
function run_search(query) {
var cache_key = query + computeURL();
var cached_results = cache.get(cache_key);
if (cached_results) {
if ($.isFunction($(input).data("settings").onCachedResult)) {
cached_results = $(input).data("settings").onCachedResult.call(hiddenInput, cached_results);
}
populateDropdown(query, cached_results);
} else {
// Are we doing an ajax search or local data search?
if($(input).data("settings").url) {
var url = computeURL();
// Extract existing get params
var ajax_params = {};
ajax_params.data = {};
if(url.indexOf("?") > -1) {
var parts = url.split("?");
ajax_params.url = parts[0];
var param_array = parts[1].split("&");
$.each(param_array, function (index, value) {
var kv = value.split("=");
ajax_params.data[kv[0]] = kv[1];
});
} else {
ajax_params.url = url;
}
// Prepare the request
ajax_params.data[$(input).data("settings").queryParam] = query;
ajax_params.type = $(input).data("settings").method;
ajax_params.dataType = $(input).data("settings").contentType;
if ($(input).data("settings").crossDomain) {
ajax_params.dataType = "jsonp";
}
// exclude current tokens?
// send exclude list to the server, so it can also exclude existing tokens
if ($(input).data("settings").excludeCurrent) {
var currentTokens = $(input).data("tokenInputObject").getTokens();
var tokenList = $.map(currentTokens, function (el) {
if(typeof $(input).data("settings").tokenValue == 'function')
return $(input).data("settings").tokenValue.call(this, el);
return el[$(input).data("settings").tokenValue];
});
ajax_params.data[$(input).data("settings").excludeCurrentParameter] = tokenList.join($(input).data("settings").tokenDelimiter);
}
// Attach the success callback
ajax_params.success = function(results) {
cache.add(cache_key, $(input).data("settings").jsonContainer ? results[$(input).data("settings").jsonContainer] : results);
if($.isFunction($(input).data("settings").onResult)) {
results = $(input).data("settings").onResult.call(hiddenInput, results);
}
// only populate the dropdown if the results are associated with the active search query
if(input_box.val() === query) {
populateDropdown(query, $(input).data("settings").jsonContainer ? results[$(input).data("settings").jsonContainer] : results);
}
};
// Provide a beforeSend callback
if (settings.onSend) {
settings.onSend(ajax_params);
}
// Make the request
$.ajax(ajax_params);
} else if($(input).data("settings").local_data) {
// Do the search through local data
var results = $.grep($(input).data("settings").local_data, function (row) {
return row[$(input).data("settings").propertyToSearch].toLowerCase().indexOf(query.toLowerCase()) > -1;
});
cache.add(cache_key, results);
if($.isFunction($(input).data("settings").onResult)) {
results = $(input).data("settings").onResult.call(hiddenInput, results);
}
populateDropdown(query, results);
}
}
}
// compute the dynamic URL
function computeURL() {
var settings = $(input).data("settings");
return typeof settings.url == 'function' ? settings.url.call(settings) : settings.url;
}
// Bring browser focus to the specified object.
// Use of setTimeout is to get around an IE bug.
// (See, e.g., http://stackoverflow.com/questions/2600186/focus-doesnt-work-in-ie)
//
// obj: a jQuery object to focus()
function focusWithTimeout(object) {
setTimeout(
function() {
object.focus();
},
50
);
}
};
// Really basic cache for the results
$.TokenList.Cache = function (options) {
var settings, data = {}, size = 0, flush;
settings = $.extend({ max_size: 500 }, options);
flush = function () {
data = {};
size = 0;
};
this.add = function (query, results) {
if (size > settings.max_size) {
flush();
}
if (!data[query]) {
size += 1;
}
data[query] = results;
};
this.get = function (query) {
return data[query];
};
};
}(jQuery));
$(function(){
var select = $("select");
$("nav a").each(function(){
var $this = $(this);
var text = $this.text();
var level = $this.parents("ul").length;
var indent = '';
if (level > 1)
{
indent = str_repeat("\u2013", level);
}
select.append('<option>'+indent + text+'</option>');
});
});
function str_repeat (input, multiplier) {
// http://kevin.vanzonneveld.net
// + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
// + improved by: Ian Carter (http://euona.com/)
// * example 1: str_repeat('-=', 10);
// * returns 1: '-=-=-=-=-=-=-=-=-=-='
var y = '';
while (true) {
if (multiplier & 1) {
y += input;
}
multiplier >>= 1;
if (multiplier) {
input += input;
}
else {
break;
}
}
return y;
}
$(document).ready(function() {
function getChildren($row) {
var children = [], level = $row.attr('data-level');
while($row.next().attr('data-level') > level) {
children.push($row.next());
$row = $row.next();
}
return children;
}
$('.parent').on('click', function() {
var children = getChildren($(this));
$.each(children, function() {
$(this).toggle();
})
});
})
(function($){
$.fn.tzSelect = function(options){
options = $.extend({
render : function(option){
return $('<li>',{
html : option.text()
});
},
className : ''
},options);
return this.each(function(){
// The "this" points to the current select element:
var select = $(this);
var selectBoxContainer = $('<div>',{
width : select.outerWidth(),
className : 'tzSelect',
html : '<div class="selectBox"></div>'
});
var dropDown = $('<ul>',{className:'dropDown'});
var selectBox = selectBoxContainer.find('.selectBox');
// Looping though the options of the original select element
if(options.className){
dropDown.addClass(options.className);
}
select.find('option').each(function(i){
var option = $(this);
if(i==select.attr('selectedIndex')){
selectBox.html(option.text());
}
// As of jQuery 1.4.3 we can access HTML5
// data attributes with the data() method.
if(option.data('skip')){
return true;
}
// Creating a dropdown item according to the
// data-icon and data-html-text HTML5 attributes:
var li = options.render(option);
li.click(function(){
selectBox.html(option.text());
dropDown.trigger('hide');
// When a click occurs, we are also reflecting
// the change on the original select element:
select.val(option.val());
return false;
});
dropDown.append(li);
});
selectBoxContainer.append(dropDown.hide());
select.hide().after(selectBoxContainer);
// Binding custom show and hide events on the dropDown:
dropDown.bind('show',function(){
if(dropDown.is(':animated')){
return false;
}
selectBox.addClass('expanded');
dropDown.slideDown();
}).bind('hide',function(){
if(dropDown.is(':animated')){
return false;
}
selectBox.removeClass('expanded');
dropDown.slideUp();
}).bind('toggle',function(){
if(selectBox.hasClass('expanded')){
dropDown.trigger('hide');
}
else dropDown.trigger('show');
});
selectBox.click(function(){
dropDown.trigger('toggle');
return false;
});
// If we click anywhere on the page, while the
// dropdown is shown, it is going to be hidden:
$(document).click(function(){
dropDown.trigger('hide');
});
});
}
})(jQuery);