Restructure javascript directory, update zepto.js and jquery.js
parent
1e38b42edd
commit
148b5b602a
@ -1,18 +0,0 @@
|
||||
Vendor JavaScript Files
|
||||
========================
|
||||
|
||||
This directory contains the following scripts which are used by pelican-red.
|
||||
|
||||
* jQuery 1.10.0 compressed
|
||||
* Zepto.js 1.0 compressed
|
||||
* Foundation 4 JavaScript
|
||||
* Custom Modernizer from Foundation 4
|
||||
* Foundation.js
|
||||
* foundation.alerts
|
||||
* foundation.clearing
|
||||
* foundation.dropdown
|
||||
* foundation.forms
|
||||
* foundation.magellan
|
||||
* foundation.orbit
|
||||
* foundation.reveal
|
||||
* foundation.section
|
@ -1,429 +0,0 @@
|
||||
/*jslint unparam: true, browser: true, indent: 2 */
|
||||
|
||||
;(function ($, window, document, undefined) {
|
||||
'use strict';
|
||||
|
||||
Foundation.libs.forms = {
|
||||
name : 'forms',
|
||||
|
||||
version : '4.0.4',
|
||||
|
||||
settings : {
|
||||
disable_class: 'no-custom'
|
||||
},
|
||||
|
||||
init : function (scope, method, options) {
|
||||
this.scope = scope || this.scope;
|
||||
|
||||
if (typeof method === 'object') {
|
||||
$.extend(true, this.settings, method);
|
||||
}
|
||||
|
||||
if (typeof method != 'string') {
|
||||
if (!this.settings.init) {
|
||||
this.events();
|
||||
}
|
||||
|
||||
this.assemble();
|
||||
|
||||
return this.settings.init;
|
||||
} else {
|
||||
return this[method].call(this, options);
|
||||
}
|
||||
},
|
||||
|
||||
assemble : function () {
|
||||
$('form.custom input[type="radio"]', $(this.scope)).not('[data-customforms="disabled"]')
|
||||
.each(this.append_custom_markup);
|
||||
$('form.custom input[type="checkbox"]', $(this.scope)).not('[data-customforms="disabled"]')
|
||||
.each(this.append_custom_markup);
|
||||
$('form.custom select', $(this.scope))
|
||||
.not('[data-customforms="disabled"]')
|
||||
.not('[multiple=multiple]')
|
||||
.each(this.append_custom_select);
|
||||
},
|
||||
|
||||
events : function () {
|
||||
var self = this;
|
||||
|
||||
$(this.scope)
|
||||
.on('click.fndtn.forms', 'form.custom span.custom.checkbox', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
self.toggle_checkbox($(this));
|
||||
})
|
||||
.on('click.fndtn.forms', 'form.custom span.custom.radio', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
self.toggle_radio($(this));
|
||||
})
|
||||
.on('change.fndtn.forms', 'form.custom select:not([data-customforms="disabled"])', function (e) {
|
||||
self.refresh_custom_select($(this));
|
||||
})
|
||||
.on('click.fndtn.forms', 'form.custom label', function (e) {
|
||||
var $associatedElement = $('#' + self.escape($(this).attr('for')) + ':not([data-customforms="disabled"])'),
|
||||
$customCheckbox,
|
||||
$customRadio;
|
||||
if ($associatedElement.length !== 0) {
|
||||
if ($associatedElement.attr('type') === 'checkbox') {
|
||||
e.preventDefault();
|
||||
$customCheckbox = $(this).find('span.custom.checkbox');
|
||||
//the checkbox might be outside after the label or inside of another element
|
||||
if ($customCheckbox.length == 0) {
|
||||
$customCheckbox = $associatedElement.add(this).siblings('span.custom.checkbox').first();
|
||||
}
|
||||
self.toggle_checkbox($customCheckbox);
|
||||
} else if ($associatedElement.attr('type') === 'radio') {
|
||||
e.preventDefault();
|
||||
$customRadio = $(this).find('span.custom.radio');
|
||||
//the radio might be outside after the label or inside of another element
|
||||
if ($customRadio.length == 0) {
|
||||
$customRadio = $associatedElement.add(this).siblings('span.custom.radio').first();
|
||||
}
|
||||
self.toggle_radio($customRadio);
|
||||
}
|
||||
}
|
||||
})
|
||||
.on('click.fndtn.forms', 'form.custom div.custom.dropdown a.current, form.custom div.custom.dropdown a.selector', function (e) {
|
||||
var $this = $(this),
|
||||
$dropdown = $this.closest('div.custom.dropdown'),
|
||||
$select = $dropdown.prev();
|
||||
|
||||
// make sure other dropdowns close
|
||||
if(!$dropdown.hasClass('open'))
|
||||
$(self.scope).trigger('click');
|
||||
|
||||
e.preventDefault();
|
||||
if (false === $select.is(':disabled')) {
|
||||
$dropdown.toggleClass('open');
|
||||
|
||||
if ($dropdown.hasClass('open')) {
|
||||
$(self.scope).on('click.fndtn.forms.customdropdown', function () {
|
||||
$dropdown.removeClass('open');
|
||||
$(self.scope).off('.fndtn.forms.customdropdown');
|
||||
});
|
||||
} else {
|
||||
$(self.scope).on('.fndtn.forms.customdropdown');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.on('click.fndtn.forms touchend.fndtn.forms', 'form.custom div.custom.dropdown li', function (e) {
|
||||
var $this = $(this),
|
||||
$customDropdown = $this.closest('div.custom.dropdown'),
|
||||
$select = $customDropdown.prev(),
|
||||
selectedIndex = 0;
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
if ( ! $(this).hasClass('disabled')) {
|
||||
$('div.dropdown').not($customDropdown).removeClass('open');
|
||||
|
||||
var $oldThis= $this
|
||||
.closest('ul')
|
||||
.find('li.selected');
|
||||
$oldThis.removeClass('selected');
|
||||
|
||||
$this.addClass('selected');
|
||||
|
||||
$customDropdown
|
||||
.removeClass('open')
|
||||
.find('a.current')
|
||||
.html($this.html());
|
||||
|
||||
$this.closest('ul').find('li').each(function (index) {
|
||||
if ($this[0] == this) {
|
||||
selectedIndex = index;
|
||||
}
|
||||
|
||||
});
|
||||
$select[0].selectedIndex = selectedIndex;
|
||||
|
||||
//store the old value in data
|
||||
$select.data('prevalue', $oldThis.html());
|
||||
$select.trigger('change');
|
||||
}
|
||||
});
|
||||
|
||||
$(window).on('keydown', function (e) {
|
||||
var focus = document.activeElement,
|
||||
dropdown = $('.custom.dropdown.open');
|
||||
|
||||
if (dropdown.length > 0) {
|
||||
e.preventDefault();
|
||||
|
||||
if (e.which === 13) {
|
||||
dropdown.find('li.selected').trigger('click');
|
||||
}
|
||||
|
||||
if (e.which === 38) {
|
||||
var current = dropdown.find('li.selected'),
|
||||
prev = current.prev(':not(.disabled)');
|
||||
|
||||
if (prev.length > 0) {
|
||||
current.removeClass('selected');
|
||||
prev.addClass('selected');
|
||||
}
|
||||
} else if (e.which === 40) {
|
||||
var current = dropdown.find('li.selected'),
|
||||
next = current.next(':not(.disabled)');
|
||||
|
||||
if (next.length > 0) {
|
||||
current.removeClass('selected');
|
||||
next.addClass('selected');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.settings.init = true;
|
||||
},
|
||||
|
||||
append_custom_markup : function (idx, sel) {
|
||||
var $this = $(sel).addClass('hidden-field'),
|
||||
type = $this.attr('type'),
|
||||
$span = $this.next('span.custom.' + type);
|
||||
|
||||
if ($span.length === 0) {
|
||||
$span = $('<span class="custom ' + type + '"></span>').insertAfter($this);
|
||||
}
|
||||
|
||||
$span.toggleClass('checked', $this.is(':checked'));
|
||||
$span.toggleClass('disabled', $this.is(':disabled'));
|
||||
},
|
||||
|
||||
append_custom_select : function (idx, sel) {
|
||||
var self = Foundation.libs.forms,
|
||||
$this = $( sel ),
|
||||
$customSelect = $this.next( 'div.custom.dropdown' ),
|
||||
$customList = $customSelect.find( 'ul' ),
|
||||
$selectCurrent = $customSelect.find( ".current" ),
|
||||
$selector = $customSelect.find( ".selector" ),
|
||||
$options = $this.find( 'option' ),
|
||||
$selectedOption = $options.filter( ':selected' ),
|
||||
copyClasses = $this.attr('class') ? $this.attr('class').split(' ') : [],
|
||||
maxWidth = 0,
|
||||
liHtml = '',
|
||||
$listItems,
|
||||
$currentSelect = false;
|
||||
|
||||
if ($this.hasClass(self.settings.disable_class)) return;
|
||||
|
||||
if ($customSelect.length === 0) {
|
||||
var customSelectSize = $this.hasClass( 'small' ) ? 'small' :
|
||||
$this.hasClass( 'medium' ) ? 'medium' :
|
||||
$this.hasClass( 'large' ) ? 'large' :
|
||||
$this.hasClass( 'expand' ) ? 'expand' : '';
|
||||
|
||||
$customSelect = $('<div class="' + ['custom', 'dropdown', customSelectSize ].concat(copyClasses).filter(function(item, idx,arr){ if(item == '') return false; return arr.indexOf(item) == idx; }).join( ' ' ) + '"><a href="#" class="selector"></a><ul /></div>');
|
||||
$selector = $customSelect.find(".selector");
|
||||
$customList = $customSelect.find("ul");
|
||||
liHtml = $options.map(function() { return "<li>" + $( this ).html() + "</li>"; } ).get().join( '' );
|
||||
$customList.append(liHtml);
|
||||
$currentSelect = $customSelect.prepend('<a href="#" class="current">' + $selectedOption.html() + '</a>' ).find( ".current" );
|
||||
$this
|
||||
.after( $customSelect )
|
||||
.addClass('hidden-field');
|
||||
|
||||
} else {
|
||||
liHtml = $options.map(function() {
|
||||
return "<li>" + $( this ).html() + "</li>";
|
||||
})
|
||||
.get().join('');
|
||||
$customList
|
||||
.html('')
|
||||
.append(liHtml);
|
||||
|
||||
} // endif $customSelect.length === 0
|
||||
$customSelect.toggleClass('disabled', $this.is( ':disabled' ) );
|
||||
$listItems = $customList.find( 'li' );
|
||||
|
||||
$options.each( function ( index ) {
|
||||
if ( this.selected ) {
|
||||
$listItems.eq( index ).addClass( 'selected' );
|
||||
|
||||
if ($currentSelect) {
|
||||
$currentSelect.html( $( this ).html() );
|
||||
}
|
||||
|
||||
}
|
||||
if ($(this).is(':disabled')) {
|
||||
$listItems.eq( index ).addClass( 'disabled' );
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// If we're not specifying a predetermined form size.
|
||||
//
|
||||
if (!$customSelect.is('.small, .medium, .large, .expand')) {
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// This is a work-around for when elements are contained within hidden parents.
|
||||
// For example, when custom-form elements are inside of a hidden reveal modal.
|
||||
//
|
||||
// We need to display the current custom list element as well as hidden parent elements
|
||||
// in order to properly calculate the list item element's width property.
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
$customSelect.addClass( 'open' );
|
||||
//
|
||||
// Quickly, display all parent elements.
|
||||
// This should help us calcualate the width of the list item's within the drop down.
|
||||
//
|
||||
var self = Foundation.libs.forms;
|
||||
self.hidden_fix.adjust( $customList );
|
||||
|
||||
maxWidth = ( self.outerWidth($listItems) > maxWidth ) ? self.outerWidth($listItems) : maxWidth;
|
||||
|
||||
Foundation.libs.forms.hidden_fix.reset();
|
||||
|
||||
$customSelect.removeClass( 'open' );
|
||||
|
||||
} // endif
|
||||
|
||||
},
|
||||
|
||||
refresh_custom_select : function ($select) {
|
||||
var self = this;
|
||||
var maxWidth = 0,
|
||||
$customSelect = $select.next(),
|
||||
$options = $select.find('option');
|
||||
|
||||
$customSelect.find('ul').html('');
|
||||
|
||||
$options.each(function () {
|
||||
var $li = $('<li>' + $(this).html() + '</li>');
|
||||
$customSelect.find('ul').append($li);
|
||||
});
|
||||
|
||||
// re-populate
|
||||
$options.each(function (index) {
|
||||
if (this.selected) {
|
||||
$customSelect.find('li').eq(index).addClass('selected');
|
||||
$customSelect.find('.current').html($(this).html());
|
||||
}
|
||||
if ($(this).is(':disabled')) {
|
||||
$customSelect.find('li').eq(index).addClass('disabled');
|
||||
}
|
||||
});
|
||||
|
||||
// fix width
|
||||
$customSelect.removeAttr('style')
|
||||
.find('ul').removeAttr('style');
|
||||
$customSelect.find('li').each(function () {
|
||||
$customSelect.addClass('open');
|
||||
if (self.outerWidth($(this)) > maxWidth) {
|
||||
maxWidth = self.outerWidth($(this));
|
||||
}
|
||||
$customSelect.removeClass('open');
|
||||
});
|
||||
},
|
||||
|
||||
toggle_checkbox : function ($element) {
|
||||
var $input = $element.prev(),
|
||||
input = $input[0];
|
||||
|
||||
if (false === $input.is(':disabled')) {
|
||||
input.checked = ((input.checked) ? false : true);
|
||||
$element.toggleClass('checked');
|
||||
|
||||
$input.trigger('change');
|
||||
}
|
||||
},
|
||||
|
||||
toggle_radio : function ($element) {
|
||||
var $input = $element.prev(),
|
||||
$form = $input.closest('form.custom'),
|
||||
input = $input[0];
|
||||
|
||||
if (false === $input.is(':disabled')) {
|
||||
$form.find('input[type="radio"][name="' + this.escape($input.attr('name')) + '"]').next().not($element).removeClass('checked');
|
||||
if ( !$element.hasClass('checked') ) {
|
||||
$element.toggleClass('checked');
|
||||
}
|
||||
input.checked = $element.hasClass('checked');
|
||||
|
||||
$input.trigger('change');
|
||||
}
|
||||
},
|
||||
|
||||
escape : function (text) {
|
||||
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
||||
},
|
||||
|
||||
hidden_fix : {
|
||||
/**
|
||||
* Sets all hidden parent elements and self to visibile.
|
||||
*
|
||||
* @method adjust
|
||||
* @param {jQuery Object} $child
|
||||
*/
|
||||
|
||||
// We'll use this to temporarily store style properties.
|
||||
tmp : [],
|
||||
|
||||
// We'll use this to set hidden parent elements.
|
||||
hidden : null,
|
||||
|
||||
adjust : function( $child ) {
|
||||
// Internal reference.
|
||||
var _self = this;
|
||||
|
||||
// Set all hidden parent elements, including this element.
|
||||
_self.hidden = $child.parents().andSelf().filter( ":hidden" );
|
||||
|
||||
// Loop through all hidden elements.
|
||||
_self.hidden.each( function() {
|
||||
|
||||
// Cache the element.
|
||||
var $elem = $( this );
|
||||
|
||||
// Store the style attribute.
|
||||
// Undefined if element doesn't have a style attribute.
|
||||
_self.tmp.push( $elem.attr( 'style' ) );
|
||||
|
||||
// Set the element's display property to block,
|
||||
// but ensure it's visibility is hidden.
|
||||
$elem.css( { 'visibility' : 'hidden', 'display' : 'block' } );
|
||||
});
|
||||
|
||||
}, // end adjust
|
||||
|
||||
/**
|
||||
* Resets the elements previous state.
|
||||
*
|
||||
* @method reset
|
||||
*/
|
||||
reset : function() {
|
||||
// Internal reference.
|
||||
var _self = this;
|
||||
// Loop through our hidden element collection.
|
||||
_self.hidden.each( function( i ) {
|
||||
// Cache this element.
|
||||
var $elem = $( this ),
|
||||
_tmp = _self.tmp[ i ]; // Get the stored 'style' value for this element.
|
||||
|
||||
// If the stored value is undefined.
|
||||
if( _tmp === undefined )
|
||||
// Remove the style attribute.
|
||||
$elem.removeAttr( 'style' );
|
||||
else
|
||||
// Otherwise, reset the element style attribute.
|
||||
$elem.attr( 'style', _tmp );
|
||||
|
||||
});
|
||||
// Reset the tmp array.
|
||||
_self.tmp = [];
|
||||
// Reset the hidden elements variable.
|
||||
_self.hidden = null;
|
||||
|
||||
} // end reset
|
||||
|
||||
},
|
||||
|
||||
off : function () {
|
||||
$(this.scope).off('.fndtn.forms');
|
||||
}
|
||||
};
|
||||
}(Foundation.zj, this, this.document));
|
@ -0,0 +1,74 @@
|
||||
/*!
|
||||
* jQuery Cookie Plugin v1.3
|
||||
* https://github.com/carhartl/jquery-cookie
|
||||
*
|
||||
* Copyright 2011, Klaus Hartl
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
* http://www.opensource.org/licenses/GPL-2.0
|
||||
*
|
||||
* Modified to work with Zepto.js by ZURB
|
||||
*/
|
||||
(function ($, document, undefined) {
|
||||
|
||||
var pluses = /\+/g;
|
||||
|
||||
function raw(s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
function decoded(s) {
|
||||
return decodeURIComponent(s.replace(pluses, ' '));
|
||||
}
|
||||
|
||||
var config = $.cookie = function (key, value, options) {
|
||||
|
||||
// write
|
||||
if (value !== undefined) {
|
||||
options = $.extend({}, config.defaults, options);
|
||||
|
||||
if (value === null) {
|
||||
options.expires = -1;
|
||||
}
|
||||
|
||||
if (typeof options.expires === 'number') {
|
||||
var days = options.expires, t = options.expires = new Date();
|
||||
t.setDate(t.getDate() + days);
|
||||
}
|
||||
|
||||
value = config.json ? JSON.stringify(value) : String(value);
|
||||
|
||||
return (document.cookie = [
|
||||
encodeURIComponent(key), '=', config.raw ? value : encodeURIComponent(value),
|
||||
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
|
||||
options.path ? '; path=' + options.path : '',
|
||||
options.domain ? '; domain=' + options.domain : '',
|
||||
options.secure ? '; secure' : ''
|
||||
].join(''));
|
||||
}
|
||||
|
||||
// read
|
||||
var decode = config.raw ? raw : decoded;
|
||||
var cookies = document.cookie.split('; ');
|
||||
for (var i = 0, l = cookies.length; i < l; i++) {
|
||||
var parts = cookies[i].split('=');
|
||||
if (decode(parts.shift()) === key) {
|
||||
var cookie = decode(parts.join('='));
|
||||
return config.json ? JSON.parse(cookie) : cookie;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
config.defaults = {};
|
||||
|
||||
$.removeCookie = function (key, options) {
|
||||
if ($.cookie(key) !== null) {
|
||||
$.cookie(key, null, options);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
})(Foundation.zj, document);
|
@ -0,0 +1,525 @@
|
||||
(function ($, window, document, undefined) {
|
||||
'use strict';
|
||||
|
||||
Foundation.libs.forms = {
|
||||
name: 'forms',
|
||||
|
||||
version: '4.2.2',
|
||||
|
||||
cache: {},
|
||||
|
||||
settings: {
|
||||
disable_class: 'no-custom',
|
||||
last_combo : null
|
||||
},
|
||||
|
||||
init: function (scope, method, options) {
|
||||
|
||||
if (typeof method === 'object') {
|
||||
$.extend(true, this.settings, method);
|
||||
}
|
||||
|
||||
if (typeof method !== 'string') {
|
||||
if (!this.settings.init) {
|
||||
this.events();
|
||||
}
|
||||
|
||||
this.assemble();
|
||||
|
||||
return this.settings.init;
|
||||
} else {
|
||||
return this[method].call(this, options);
|
||||
}
|
||||
},
|
||||
|
||||
assemble: function () {
|
||||
$('form.custom input[type="radio"]', $(this.scope))
|
||||
.not('[data-customforms="disabled"]')
|
||||
.not('.' + this.settings.disable_class)
|
||||
.each(this.append_custom_markup);
|
||||
$('form.custom input[type="checkbox"]', $(this.scope))
|
||||
.not('[data-customforms="disabled"]')
|
||||
.not('.' + this.settings.disable_class)
|
||||
.each(this.append_custom_markup);
|
||||
$('form.custom select', $(this.scope))
|
||||
.not('[data-customforms="disabled"]')
|
||||
.not('.' + this.settings.disable_class)
|
||||
.not('[multiple=multiple]')
|
||||
.each(this.append_custom_select);
|
||||
},
|
||||
|
||||
events: function () {
|
||||
var self = this;
|
||||
|
||||
$(this.scope)
|
||||
.on('click.fndtn.forms', 'form.custom span.custom.checkbox', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
self.toggle_checkbox($(this));
|
||||
})
|
||||
.on('click.fndtn.forms', 'form.custom span.custom.radio', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
self.toggle_radio($(this));
|
||||
})
|
||||
.on('change.fndtn.forms', 'form.custom select', function (e, force_refresh) {
|
||||
if ($(this).is('[data-customforms="disabled"]')) return;
|
||||
self.refresh_custom_select($(this), force_refresh);
|
||||
})
|
||||
.on('click.fndtn.forms', 'form.custom label', function (e) {
|
||||
if ($(e.target).is('label')) {
|
||||
var $associatedElement = $('#' + self.escape($(this).attr('for'))).not('[data-customforms="disabled"]'),
|
||||
$customCheckbox,
|
||||
$customRadio;
|
||||
|
||||
if ($associatedElement.length !== 0) {
|
||||
if ($associatedElement.attr('type') === 'checkbox') {
|
||||
e.preventDefault();
|
||||
$customCheckbox = $(this).find('span.custom.checkbox');
|
||||
//the checkbox might be outside after the label or inside of another element
|
||||
if ($customCheckbox.length === 0) {
|
||||
$customCheckbox = $associatedElement.add(this).siblings('span.custom.checkbox').first();
|
||||
}
|
||||
self.toggle_checkbox($customCheckbox);
|
||||
} else if ($associatedElement.attr('type') === 'radio') {
|
||||
e.preventDefault();
|
||||
$customRadio = $(this).find('span.custom.radio');
|
||||
//the radio might be outside after the label or inside of another element
|
||||
if ($customRadio.length === 0) {
|
||||
$customRadio = $associatedElement.add(this).siblings('span.custom.radio').first();
|
||||
}
|
||||
self.toggle_radio($customRadio);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.on('mousedown.fndtn.forms', 'form.custom div.custom.dropdown', function () {
|
||||
return false;
|
||||
})
|
||||
.on('click.fndtn.forms', 'form.custom div.custom.dropdown a.current, form.custom div.custom.dropdown a.selector', function (e) {
|
||||
var $this = $(this),
|
||||
$dropdown = $this.closest('div.custom.dropdown'),
|
||||
$select = getFirstPrevSibling($dropdown, 'select');
|
||||
|
||||
// make sure other dropdowns close
|
||||
if (!$dropdown.hasClass('open')) $(self.scope).trigger('click');
|
||||
|
||||
e.preventDefault();
|
||||
if (false === $select.is(':disabled')) {
|
||||
$dropdown.toggleClass('open');
|
||||
|
||||
if ($dropdown.hasClass('open')) {
|
||||
$(self.scope).on('click.fndtn.forms.customdropdown', function () {
|
||||
$dropdown.removeClass('open');
|
||||
$(self.scope).off('.fndtn.forms.customdropdown');
|
||||
});
|
||||
} else {
|
||||
$(self.scope).on('.fndtn.forms.customdropdown');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.on('click.fndtn.forms touchend.fndtn.forms', 'form.custom div.custom.dropdown li', function (e) {
|
||||
var $this = $(this),
|
||||
$customDropdown = $this.closest('div.custom.dropdown'),
|
||||
$select = getFirstPrevSibling($customDropdown, 'select'),
|
||||
selectedIndex = 0;
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
if (!$(this).hasClass('disabled')) {
|
||||
$('div.dropdown').not($customDropdown).removeClass('open');
|
||||
|
||||
var $oldThis = $this.closest('ul')
|
||||
.find('li.selected');
|
||||
$oldThis.removeClass('selected');
|
||||
|
||||
$this.addClass('selected');
|
||||
|
||||
$customDropdown.removeClass('open')
|
||||
.find('a.current')
|
||||
.text($this.text());
|
||||
|
||||
$this.closest('ul').find('li').each(function (index) {
|
||||
if ($this[0] === this) {
|
||||
selectedIndex = index;
|
||||
}
|
||||
});
|
||||
$select[0].selectedIndex = selectedIndex;
|
||||
|
||||
//store the old value in data
|
||||
$select.data('prevalue', $oldThis.html());
|
||||
$select.trigger('change');
|
||||
}
|
||||
});
|
||||
|
||||
$(window).on('keydown', function (e) {
|
||||
var focus = document.activeElement,
|
||||
self = Foundation.libs.forms,
|
||||
dropdown = $('.custom.dropdown.open');
|
||||
|
||||
if (dropdown.length > 0) {
|
||||
e.preventDefault();
|
||||
|
||||
if (e.which === 13) {
|
||||
dropdown.find('li.selected').trigger('click');
|
||||
}
|
||||
|
||||
if (e.which === 27) {
|
||||
dropdown.removeClass('open');
|
||||
}
|
||||
|
||||
if (e.which >= 65 && e.which <= 90) {
|
||||
var next = self.go_to(dropdown, e.which),
|
||||
current = dropdown.find('li.selected');
|
||||
|
||||
if (next) {
|
||||
current.removeClass('selected');
|
||||
self.scrollTo(next.addClass('selected'), 300);
|
||||
}
|
||||
}
|
||||
|
||||
if (e.which === 38) {
|
||||
var current = dropdown.find('li.selected'),
|
||||
prev = current.prev(':not(.disabled)');
|
||||
|
||||
if (prev.length > 0) {
|
||||
prev.parent()[0].scrollTop = prev.parent().scrollTop() - self.outerHeight(prev);
|
||||
current.removeClass('selected');
|
||||
prev.addClass('selected');
|
||||
}
|
||||
} else if (e.which === 40) {
|
||||
var current = dropdown.find('li.selected'),
|
||||
next = current.next(':not(.disabled)');
|
||||
|
||||
if (next.length > 0) {
|
||||
next.parent()[0].scrollTop = next.parent().scrollTop() + self.outerHeight(next);
|
||||
current.removeClass('selected');
|
||||
next.addClass('selected');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.settings.init = true;
|
||||
},
|
||||
|
||||
go_to: function (dropdown, character) {
|
||||
var lis = dropdown.find('li'),
|
||||
count = lis.length;
|
||||
|
||||
if (count > 0) {
|
||||
for (var i = 0; i < count; i++) {
|
||||
var first_letter = lis.eq(i).text().charAt(0).toLowerCase();
|
||||
if (first_letter === String.fromCharCode(character).toLowerCase()) return lis.eq(i);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
scrollTo: function (el, duration) {
|
||||
if (duration < 0) return;
|
||||
var parent = el.parent();
|
||||
var li_height = this.outerHeight(el);
|
||||
var difference = (li_height * (el.index())) - parent.scrollTop();
|
||||
var perTick = difference / duration * 10;
|
||||
|
||||
this.scrollToTimerCache = setTimeout(function () {
|
||||
if (!isNaN(parseInt(perTick, 10))) {
|
||||
parent[0].scrollTop = parent.scrollTop() + perTick;
|
||||
this.scrollTo(el, duration - 10);
|
||||
}
|
||||
}.bind(this), 10);
|
||||
},
|
||||
|
||||
append_custom_markup: function (idx, sel) {
|
||||
var $this = $(sel),
|
||||
type = $this.attr('type'),
|
||||
$span = $this.next('span.custom.' + type);
|
||||
|
||||
if (!$this.parent().hasClass('switch')) {
|
||||
$this.addClass('hidden-field');
|
||||
}
|
||||
|
||||
if ($span.length === 0) {
|
||||
$span = $('<span class="custom ' + type + '"></span>').insertAfter($this);
|
||||
}
|
||||
|
||||
$span.toggleClass('checked', $this.is(':checked'));
|
||||
$span.toggleClass('disabled', $this.is(':disabled'));
|
||||
},
|
||||
|
||||
append_custom_select: function (idx, sel) {
|
||||
var self = Foundation.libs.forms,
|
||||
$this = $(sel),
|
||||
$customSelect = $this.next('div.custom.dropdown'),
|
||||
$customList = $customSelect.find('ul'),
|
||||
$selectCurrent = $customSelect.find(".current"),
|
||||
$selector = $customSelect.find(".selector"),
|
||||
$options = $this.find('option'),
|
||||
$selectedOption = $options.filter(':selected'),
|
||||
copyClasses = $this.attr('class') ? $this.attr('class').split(' ') : [],
|
||||
maxWidth = 0,
|
||||
liHtml = '',
|
||||
$listItems,
|
||||
$currentSelect = false;
|
||||
|
||||
if ($customSelect.length === 0) {
|
||||
var customSelectSize = $this.hasClass('small') ? 'small' : $this.hasClass('medium') ? 'medium' : $this.hasClass('large') ? 'large' : $this.hasClass('expand') ? 'expand' : '';
|
||||
|
||||
$customSelect = $('<div class="' + ['custom', 'dropdown', customSelectSize].concat(copyClasses).filter(function (item, idx, arr) {
|
||||
if (item === '') return false;
|
||||
return arr.indexOf(item) === idx;
|
||||
}).join(' ') + '"><a href="#" class="selector"></a><ul /></div>');
|
||||
|
||||
$selector = $customSelect.find(".selector");
|
||||
$customList = $customSelect.find("ul");
|
||||
|
||||
liHtml = $options.map(function () {
|
||||
var copyClasses = $(this).attr('class') ? $(this).attr('class') : '';
|
||||
return "<li class='" + copyClasses + "'>" + $(this).html() + "</li>";
|
||||
}).get().join('');
|
||||
|
||||
$customList.append(liHtml);
|
||||
|
||||
$currentSelect = $customSelect
|
||||
.prepend('<a href="#" class="current">' + $selectedOption.html() + '</a>')
|
||||
.find(".current");
|
||||
|
||||
$this.after($customSelect)
|
||||
.addClass('hidden-field');
|
||||
} else {
|
||||
liHtml = $options.map(function () {
|
||||
return "<li>" + $(this).html() + "</li>";
|
||||
})
|
||||
.get().join('');
|
||||
|
||||
$customList.html('')
|
||||
.append(liHtml);
|
||||
|
||||
} // endif $customSelect.length === 0
|
||||
|
||||
self.assign_id($this, $customSelect);
|
||||
$customSelect.toggleClass('disabled', $this.is(':disabled'));
|
||||
$listItems = $customList.find('li');
|
||||
|
||||
// cache list length
|
||||
self.cache[$customSelect.data('id')] = $listItems.length;
|
||||
|
||||
$options.each(function (index) {
|
||||
if (this.selected) {
|
||||
$listItems.eq(index).addClass('selected');
|
||||
|
||||
if ($currentSelect) {
|
||||
$currentSelect.html($(this).html());
|
||||
}
|
||||
}
|
||||
if ($(this).is(':disabled')) {
|
||||
$listItems.eq(index).addClass('disabled');
|
||||
}
|
||||
});
|
||||
|
||||
//
|
||||
// If we're not specifying a predetermined form size.
|
||||
//
|
||||
if (!$customSelect.is('.small, .medium, .large, .expand')) {
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// This is a work-around for when elements are contained within hidden parents.
|
||||
// For example, when custom-form elements are inside of a hidden reveal modal.
|
||||
//
|
||||
// We need to display the current custom list element as well as hidden parent elements
|
||||
// in order to properly calculate the list item element's width property.
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
$customSelect.addClass('open');
|
||||
//
|
||||
// Quickly, display all parent elements.
|
||||
// This should help us calcualate the width of the list item's within the drop down.
|
||||
//
|
||||
var self = Foundation.libs.forms;
|
||||
self.hidden_fix.adjust($customList);
|
||||
|
||||
maxWidth = (self.outerWidth($listItems) > maxWidth) ? self.outerWidth($listItems) : maxWidth;
|
||||
|
||||
Foundation.libs.forms.hidden_fix.reset();
|
||||
|
||||
$customSelect.removeClass('open');
|
||||
|
||||
} // endif
|
||||
|
||||
},
|
||||
|
||||
assign_id: function ($select, $customSelect) {
|
||||
var id = [+new Date(), Foundation.random_str(5)].join('-');
|
||||
$select.attr('data-id', id);
|
||||
$customSelect.attr('data-id', id);
|
||||
},
|
||||
|
||||
refresh_custom_select: function ($select, force_refresh) {
|
||||
var self = this;
|
||||
var maxWidth = 0,
|
||||
$customSelect = $select.next(),
|
||||
$options = $select.find('option'),
|
||||
$listItems = $customSelect.find('li');
|
||||
|
||||
if ($listItems.length !== this.cache[$customSelect.data('id')] || force_refresh) {
|
||||
$customSelect.find('ul').html('');
|
||||
|
||||
$options.each(function () {
|
||||
var $li = $('<li>' + $(this).html() + '</li>');
|
||||
$customSelect.find('ul').append($li);
|
||||
});
|
||||
|
||||
// re-populate
|
||||
$options.each(function (index) {
|
||||
if (this.selected) {
|
||||
$customSelect.find('li').eq(index).addClass('selected');
|
||||
$customSelect.find('.current').html($(this).html());
|
||||
}
|
||||
if ($(this).is(':disabled')) {
|
||||
$customSelect.find('li').eq(index).addClass('disabled');
|
||||
}
|
||||
});
|
||||
|
||||
// fix width
|
||||
$customSelect.removeAttr('style')
|
||||
.find('ul').removeAttr('style');
|
||||
$customSelect.find('li').each(function () {
|
||||
$customSelect.addClass('open');
|
||||
if (self.outerWidth($(this)) > maxWidth) {
|
||||
maxWidth = self.outerWidth($(this));
|
||||
}
|
||||
$customSelect.removeClass('open');
|
||||
});
|
||||
|
||||
$listItems = $customSelect.find('li');
|
||||
// cache list length
|
||||
this.cache[$customSelect.data('id')] = $listItems.length;
|
||||
}
|
||||
},
|
||||
|
||||
toggle_checkbox: function ($element) {
|
||||
var $input = $element.prev(),
|
||||
input = $input[0];
|
||||
|
||||
if (false === $input.is(':disabled')) {
|
||||
input.checked = ((input.checked) ? false : true);
|
||||
$element.toggleClass('checked');
|
||||
|
||||
$input.trigger('change');
|
||||
}
|
||||
},
|
||||
|
||||
toggle_radio: function ($element) {
|
||||
var $input = $element.prev(),
|
||||
$form = $input.closest('form.custom'),
|
||||
input = $input[0];
|
||||
|
||||
if (false === $input.is(':disabled')) {
|
||||
$form.find('input[type="radio"][name="' + this.escape($input.attr('name')) + '"]')
|
||||
.next().not($element).removeClass('checked');
|
||||
|
||||
if (!$element.hasClass('checked')) {
|
||||
$element.toggleClass('checked');
|
||||
}
|
||||
|
||||
input.checked = $element.hasClass('checked');
|
||||
|
||||
$input.trigger('change');
|
||||
}
|
||||
},
|
||||
|
||||
escape: function (text) {
|
||||
if (!text) return '';
|
||||
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
|
||||
},
|
||||
|
||||
hidden_fix: {
|
||||
/**
|
||||
* Sets all hidden parent elements and self to visibile.
|
||||
*
|
||||
* @method adjust
|
||||
* @param {jQuery Object} $child
|
||||
*/
|
||||
|
||||
// We'll use this to temporarily store style properties.
|
||||
tmp: [],
|
||||
|
||||
// We'll use this to set hidden parent elements.
|
||||
hidden: null,
|
||||
|
||||
adjust: function ($child) {
|
||||
// Internal reference.
|
||||
var _self = this;
|
||||
|
||||
// Set all hidden parent elements, including this element.
|
||||
_self.hidden = $child.parents();
|
||||
_self.hidden = _self.hidden.add($child).filter(":hidden");
|
||||
|
||||
// Loop through all hidden elements.
|
||||
_self.hidden.each(function () {
|
||||
|
||||
// Cache the element.
|
||||
var $elem = $(this);
|
||||
|
||||
// Store the style attribute.
|
||||
// Undefined if element doesn't have a style attribute.
|
||||
_self.tmp.push($elem.attr('style'));
|
||||
|
||||
// Set the element's display property to block,
|
||||
// but ensure it's visibility is hidden.
|
||||
$elem.css({
|
||||
'visibility': 'hidden',
|
||||
'display': 'block'
|
||||
});
|
||||
});
|
||||
|
||||
}, // end adjust
|
||||
|
||||
/**
|
||||
* Resets the elements previous state.
|
||||
*
|
||||
* @method reset
|
||||
*/
|
||||
reset: function () {
|
||||
// Internal reference.
|
||||
var _self = this;
|
||||
// Loop through our hidden element collection.
|
||||
_self.hidden.each(function (i) {
|
||||
// Cache this element.
|
||||
var $elem = $(this),
|
||||
_tmp = _self.tmp[i]; // Get the stored 'style' value for this element.
|
||||
|
||||
// If the stored value is undefined.
|
||||
if (_tmp === undefined)
|
||||
// Remove the style attribute.
|
||||
$elem.removeAttr('style');
|
||||
else
|
||||
// Otherwise, reset the element style attribute.
|
||||
$elem.attr('style', _tmp);
|
||||
});
|
||||
// Reset the tmp array.
|
||||
_self.tmp = [];
|
||||
// Reset the hidden elements variable.
|
||||
_self.hidden = null;
|
||||
|
||||
} // end reset
|
||||
},
|
||||
|
||||
off: function () {
|
||||
$(this.scope).off('.fndtn.forms');
|
||||
},
|
||||
|
||||
reflow : function () {}
|
||||
};
|
||||
|
||||
var getFirstPrevSibling = function($el, selector) {
|
||||
var $el = $el.prev();
|
||||
while ($el.length) {
|
||||
if ($el.is(selector)) return $el;
|
||||
$el = $el.prev();
|
||||
}
|
||||
return $();
|
||||
};
|
||||
}(Foundation.zj, this, this.document));
|
@ -0,0 +1,271 @@
|
||||
/*jslint unparam: true, browser: true, indent: 2 */
|
||||
|
||||
;(function ($, window, document, undefined) {
|
||||
'use strict';
|
||||
|
||||
Foundation.libs.interchange = {
|
||||
name : 'interchange',
|
||||
|
||||
version : '4.2.2',
|
||||
|
||||
cache : {},
|
||||
|
||||
settings : {
|
||||
load_attr : 'interchange',
|
||||
|
||||
named_queries : {
|
||||
'default' : 'only screen and (min-width: 1px)',
|
||||
small : 'only screen and (min-width: 768px)',
|
||||
medium : 'only screen and (min-width: 1280px)',
|
||||
large : 'only screen and (min-width: 1440px)',
|
||||
landscape : 'only screen and (orientation: landscape)',
|
||||
portrait : 'only screen and (orientation: portrait)',
|
||||
retina : 'only screen and (-webkit-min-device-pixel-ratio: 2),' +
|
||||
'only screen and (min--moz-device-pixel-ratio: 2),' +
|
||||
'only screen and (-o-min-device-pixel-ratio: 2/1),' +
|
||||
'only screen and (min-device-pixel-ratio: 2),' +
|
||||
'only screen and (min-resolution: 192dpi),' +
|
||||
'only screen and (min-resolution: 2dppx)'
|
||||
},
|
||||
|
||||
directives : {
|
||||
replace : function (el, path) {
|
||||
if (/IMG/.test(el[0].nodeName)) {
|
||||
var path_parts = path.split('/'),
|
||||
path_file = path_parts[path_parts.length - 1],
|
||||
orig_path = el[0].src;
|
||||
|
||||
if (new RegExp(path_file, 'i').test(el[0].src)) return;
|
||||
|
||||
el[0].src = path;
|
||||
|
||||
return el.trigger('replace', [el[0].src, orig_path]);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
init : function (scope, method, options) {
|
||||
Foundation.inherit(this, 'throttle');
|
||||
|
||||
if (typeof method === 'object') {
|
||||
$.extend(true, this.settings, method);
|
||||
}
|
||||
|
||||
this.events();
|
||||
this.images();
|
||||
|
||||
if (typeof method !== 'string') {
|
||||
return this.settings.init;
|
||||
} else {
|
||||
return this[method].call(this, options);
|
||||
}
|
||||
},
|
||||
|
||||
events : function () {
|
||||
var self = this;
|
||||
|
||||
$(window).on('resize.fndtn.interchange', self.throttle(function () {
|
||||
self.resize.call(self);
|
||||
}, 50));
|
||||
},
|
||||
|
||||
resize : function () {
|
||||
var cache = this.cache;
|
||||
|
||||
for (var uuid in cache) {
|
||||
if (cache.hasOwnProperty(uuid)) {
|
||||
var passed = this.results(uuid, cache[uuid]);
|
||||
|
||||
if (passed) {
|
||||
this.settings.directives[passed
|
||||
.scenario[1]](passed.el, passed.scenario[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
results : function (uuid, scenarios) {
|
||||
var count = scenarios.length,
|
||||
results_arr = [];
|
||||
|
||||
if (count > 0) {
|
||||
var el = $('[data-uuid="' + uuid + '"]');
|
||||
|
||||
for (var i = count - 1; i >= 0; i--) {
|
||||
var rule = scenarios[i][2];
|
||||
if (this.settings.named_queries.hasOwnProperty(rule)) {
|
||||
var mq = matchMedia(this.settings.named_queries[rule]);
|
||||
} else {
|
||||
var mq = matchMedia(scenarios[i][2]);
|
||||
}
|
||||
if (mq.matches) {
|
||||
return {el: el, scenario: scenarios[i]};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
images : function (force_update) {
|
||||
if (typeof this.cached_images === 'undefined' || force_update) {
|
||||
return this.update_images();
|
||||
}
|
||||
|
||||
return this.cached_images;
|
||||
},
|
||||
|
||||
update_images : function () {
|
||||
var images = document.getElementsByTagName('img'),
|
||||
count = images.length,
|
||||
data_attr = 'data-' + this.settings.load_attr;
|
||||
|
||||
this.cached_images = [];
|
||||
|
||||
for (var i = count - 1; i >= 0; i--) {
|
||||
this.loaded($(images[i]), (i === 0), function (image, last) {
|
||||
if (image) {
|
||||
var str = image.getAttribute(data_attr) || '';
|
||||
|
||||
if (str.length > 0) {
|
||||
this.cached_images.push(image);
|
||||
}
|
||||
}
|
||||
|
||||
if (last) this.enhance();
|
||||
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
return 'deferred';
|
||||
},
|
||||
|
||||
// based on jquery.imageready.js
|
||||
// @weblinc, @jsantell, (c) 2012
|
||||
|
||||
loaded : function (image, last, callback) {
|
||||
function loaded () {
|
||||
callback(image[0], last);
|
||||
}
|
||||
|
||||
function bindLoad () {
|
||||
this.one('load', loaded);
|
||||
|
||||
if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)) {
|
||||
var src = this.attr( 'src' ),
|
||||
param = src.match( /\?/ ) ? '&' : '?';
|
||||
|
||||
param += 'random=' + (new Date()).getTime();
|
||||
this.attr('src', src + param);
|
||||
}
|
||||
}
|
||||
|
||||
if (!image.attr('src')) {
|
||||
loaded();
|
||||
return;
|
||||
}
|
||||
|
||||
if (image[0].complete || image[0].readyState === 4) {
|
||||
loaded();
|
||||
} else {
|
||||
bindLoad.call(image);
|
||||
}
|
||||
},
|
||||
|
||||
enhance : function () {
|
||||
var count = this.images().length;
|
||||
|
||||
for (var i = count - 1; i >= 0; i--) {
|
||||
this._object($(this.images()[i]));
|
||||
}
|
||||
|
||||
return $(window).trigger('resize');
|
||||
},
|
||||
|
||||
parse_params : function (path, directive, mq) {
|
||||
return [this.trim(path), this.convert_directive(directive), this.trim(mq)];
|
||||
},
|
||||
|
||||
convert_directive : function (directive) {
|
||||
var trimmed = this.trim(directive);
|
||||
|
||||
if (trimmed.length > 0) {
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
return 'replace';
|
||||
},
|
||||
|
||||
_object : function(el) {
|
||||
var raw_arr = this.parse_data_attr(el),
|
||||
scenarios = [], count = raw_arr.length;
|
||||
|
||||
if (count > 0) {
|
||||
for (var i = count - 1; i >= 0; i--) {
|
||||
var split = raw_arr[i].split(/\((.*?)(\))$/);
|
||||
|
||||
if (split.length > 1) {
|
||||
var cached_split = split[0].split(','),
|
||||
params = this.parse_params(cached_split[0],
|
||||
cached_split[1], split[1]);
|
||||
|
||||
scenarios.push(params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this.store(el, scenarios);
|
||||
},
|
||||
|
||||
uuid : function (separator) {
|
||||
var delim = separator || "-";
|
||||
|
||||
function S4() {
|
||||
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
|
||||
}
|
||||
|
||||
return (S4() + S4() + delim + S4() + delim + S4()
|
||||
+ delim + S4() + delim + S4() + S4() + S4());
|
||||
},
|
||||
|
||||
store : function (el, scenarios) {
|
||||