/components/foundation/javascripts/jquery.foundation.forms.js
https://bitbucket.org/ceoaliongroo/torredelprior · JavaScript · 486 lines · 365 code · 28 blank · 93 comment · 6 complexity · 67a3f0d91d5fc4142fe71cda2de49271 MD5 · raw file
- /*
- * jQuery Custom Forms Plugin 1.0
- * www.ZURB.com
- * Copyright 2010, ZURB
- * Free to use under the MIT license.
- * http://www.opensource.org/licenses/mit-license.php
- */
- (function( $ ){
- /**
- * Helper object used to quickly adjust all hidden parent element's, display and visibility properties.
- * This is currently used for the custom drop downs. When the dropdowns are contained within a reveal modal
- * we cannot accurately determine the list-item elements width property, since the modal's display property is set
- * to 'none'.
- *
- * This object will help us work around that problem.
- *
- * NOTE: This could also be plugin.
- *
- * @function hiddenFix
- */
- var hiddenFix = function() {
- return {
- /**
- * 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
- }; // end return
- };
- jQuery.foundation = jQuery.foundation || {};
- jQuery.foundation.customForms = jQuery.foundation.customForms || {};
- $.foundation.customForms.appendCustomMarkup = function ( options ) {
- var defaults = {
- disable_class: "js-disable-custom"
- };
- options = $.extend( defaults, options );
- function appendCustomMarkup(idx, sel) {
- var $this = $(sel).hide(),
- 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'));
- }
- function appendCustomSelect(idx, sel) {
- var hiddenFixObj = hiddenFix();
- //
- // jQueryify the <select> element and cache it.
- //
- var $this = $( sel ),
- //
- // Find the custom drop down element.
- //
- $customSelect = $this.next( 'div.custom.dropdown' ),
- //
- // Find the custom select element within the custom drop down.
- //
- $customList = $customSelect.find( 'ul' ),
- //
- // Find the custom a.current element.
- //
- $selectCurrent = $customSelect.find( ".current" ),
- //
- // Find the custom a.selector element (the drop-down icon).
- //
- $selector = $customSelect.find( ".selector" ),
- //
- // Get the <options> from the <select> element.
- //
- $options = $this.find( 'option' ),
- //
- // Filter down the selected options
- //
- $selectedOption = $options.filter( ':selected' ),
- //
- // Initial max width.
- //
- maxWidth = 0,
- //
- // We'll use this variable to create the <li> elements for our custom select.
- //
- liHtml = '',
- //
- // We'll use this to cache the created <li> elements within our custom select.
- //
- $listItems
- ;
- var $currentSelect = false;
- //
- // Should we not create a custom list?
- //
- if ( $this.hasClass( 'no-custom' ) ) return;
- //
- // Did we not create a custom select element yet?
- //
- if ( $customSelect.length === 0 ) {
- //
- // Let's create our custom select element!
- //
- //
- // Determine what select size to use.
- //
- var customSelectSize = $this.hasClass( 'small' ) ? 'small' :
- $this.hasClass( 'medium' ) ? 'medium' :
- $this.hasClass( 'large' ) ? 'large' :
- $this.hasClass( 'expand' ) ? 'expand' : ''
- ;
- //
- // Build our custom list.
- //
- $customSelect = $('<div class="' + ['custom', 'dropdown', customSelectSize ].join( ' ' ) + '"><a href="#" class="selector"></a><ul /></div>"');
- //
- // Grab the selector element
- //
- $selector = $customSelect.find( ".selector" );
- //
- // Grab the unordered list element from the custom list.
- //
- $customList = $customSelect.find( "ul" );
- //
- // Build our <li> elements.
- //
- liHtml = $options.map( function() { return "<li>" + $( this ).html() + "</li>"; } ).get().join( '' );
- //
- // Append our <li> elements to the custom list (<ul>).
- //
- $customList.append( liHtml );
- //
- // Insert the the currently selected list item before all other elements.
- // Then, find the element and assign it to $currentSelect.
- //
- $currentSelect = $customSelect.prepend( '<a href="#" class="current">' + $selectedOption.html() + '</a>' ).find( ".current" );
- //
- // Add the custom select element after the <select> element.
- //
- $this.after( $customSelect )
- //
- //then hide the <select> element.
- //
- .hide();
- } else {
- //
- // Create our list item <li> elements.
- //
- liHtml = $options.map( function() { return "<li>" + $( this ).html() + "</li>"; } ).get().join( '' );
- //
- // Refresh the ul with options from the select in case the supplied markup doesn't match.
- // Clear what's currently in the <ul> element.
- //
- $customList.html( '' )
- //
- // Populate the list item <li> elements.
- //
- .append( liHtml );
- } // endif $customSelect.length === 0
- //
- // Determine whether or not the custom select element should be disabled.
- //
- $customSelect.toggleClass( 'disabled', $this.is( ':disabled' ) );
- //
- // Cache our List item elements.
- //
- $listItems = $customList.find( 'li' );
- //
- // Determine which elements to select in our custom list.
- //
- $options.each( function ( index ) {
- if ( this.selected ) {
- //
- // Add the selected class to the current li element
- //
- $listItems.eq( index ).addClass( 'selected' );
- //
- // Update the current element with the option value.
- //
- if ($currentSelect) {
- $currentSelect.html( $( this ).html() );
- }
- }
- });
- //
- // Update the custom <ul> list width property.
- //
- $customList.css( 'width', 'inherit' );
- //
- // Set the custom select width property.
- //
- $customSelect.css( 'width', 'inherit' );
- //
- // 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.
- // -------------------------------------------------------------------------------------
- //
- // Show the drop down.
- // This should ensure that the list item's width values are properly calculated.
- //
- $customSelect.addClass( 'open' );
- //
- // Quickly, display all parent elements.
- // This should help us calcualate the width of the list item's within the drop down.
- //
- hiddenFixObj.adjust( $customList );
- //
- // Grab the largest list item width.
- //
- maxWidth = ( $listItems.outerWidth() > maxWidth ) ? $listItems.outerWidth() : maxWidth;
- //
- // Okay, now reset the parent elements.
- // This will hide them again.
- //
- hiddenFixObj.reset();
- //
- // Finally, hide the drop down.
- //
- $customSelect.removeClass( 'open' );
- //
- // Set the custom list width.
- //
- $customSelect.width( maxWidth + 18);
- //
- // Set the custom list element (<ul />) width.
- //
- $customList.width( maxWidth + 16 );
- } // endif
- }
- $('form.custom input:radio[data-customforms!=disabled]').each(appendCustomMarkup);
- $('form.custom input:checkbox[data-customforms!=disabled]').each(appendCustomMarkup);
- $('form.custom select[data-customforms!=disabled]').each(appendCustomSelect);
- };
- var refreshCustomSelect = function($select) {
- var maxWidth = 0,
- $customSelect = $select.next();
- $options = $select.find('option');
- $customSelect.find('ul').html('');
- $options.each(function () {
- $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());
- }
- });
- // fix width
- $customSelect.removeAttr('style')
- .find('ul').removeAttr('style');
- $customSelect.find('li').each(function () {
- $customSelect.addClass('open');
- if ($(this).outerWidth() > maxWidth) {
- maxWidth = $(this).outerWidth();
- }
- $customSelect.removeClass('open');
- });
- $customSelect.css('width', maxWidth + 18 + 'px');
- $customSelect.find('ul').css('width', maxWidth + 16 + 'px');
- };
- var toggleCheckbox = 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');
- }
- };
- var toggleRadio = function($element) {
- var $input = $element.prev(),
- input = $input[0];
- if (false === $input.is(':disabled')) {
- $('input:radio[name="' + $input.attr('name') + '"]').next().not($element).removeClass('checked');
- if ( !$element.hasClass('checked') ) {
- $element.toggleClass('checked');
- }
- input.checked = $element.hasClass('checked');
- $input.trigger('change');
- }
- };
- $(document).on('click', 'form.custom span.custom.checkbox', function (event) {
- event.preventDefault();
- event.stopPropagation();
- toggleCheckbox($(this));
- });
- $(document).on('click', 'form.custom span.custom.radio', function (event) {
- event.preventDefault();
- event.stopPropagation();
- toggleRadio($(this));
- });
- $(document).on('change', 'form.custom select[data-customforms!=disabled]', function (event) {
- refreshCustomSelect($(this));
- });
- $(document).on('click', 'form.custom label', function (event) {
- var $associatedElement = $('#' + $(this).attr('for') + '[data-customforms!=disabled]'),
- $customCheckbox,
- $customRadio;
- if ($associatedElement.length !== 0) {
- if ($associatedElement.attr('type') === 'checkbox') {
- event.preventDefault();
- $customCheckbox = $(this).find('span.custom.checkbox');
- toggleCheckbox($customCheckbox);
- } else if ($associatedElement.attr('type') === 'radio') {
- event.preventDefault();
- $customRadio = $(this).find('span.custom.radio');
- toggleRadio($customRadio);
- }
- }
- });
- $(document).on('click', 'form.custom div.custom.dropdown a.current, form.custom div.custom.dropdown a.selector', function (event) {
- var $this = $(this),
- $dropdown = $this.closest('div.custom.dropdown'),
- $select = $dropdown.prev();
- event.preventDefault();
- $('div.dropdown').removeClass('open');
- if (false === $select.is(':disabled')) {
- $dropdown.toggleClass('open');
- if ($dropdown.hasClass('open')) {
- $(document).bind('click.customdropdown', function (event) {
- $dropdown.removeClass('open');
- $(document).unbind('.customdropdown');
- });
- } else {
- $(document).unbind('.customdropdown');
- }
- return false;
- }
- });
- $(document).on('click', 'form.custom div.custom.dropdown li', function (event) {
- var $this = $(this),
- $customDropdown = $this.closest('div.custom.dropdown'),
- $select = $customDropdown.prev(),
- selectedIndex = 0;
- event.preventDefault();
- event.stopPropagation();
- $('div.dropdown').removeClass('open');
- $this
- .closest('ul')
- .find('li')
- .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;
- $select.trigger('change');
- });
- $.fn.foundationCustomForms = $.foundation.customForms.appendCustomMarkup;
- })( jQuery );