1/* 2 * jQuery Custom Forms Plugin 1.0 3 * www.ZURB.com 4 * Copyright 2010, ZURB 5 * Free to use under the MIT license. 6 * http://www.opensource.org/licenses/mit-license.php 7*/ 8 9(function( $ ){ 10 11 /** 12 * Helper object used to quickly adjust all hidden parent element's, display and visibility properties. 13 * This is currently used for the custom drop downs. When the dropdowns are contained within a reveal modal 14 * we cannot accurately determine the list-item elements width property, since the modal's display property is set 15 * to 'none'. 16 * 17 * This object will help us work around that problem. 18 * 19 * NOTE: This could also be plugin. 20 * 21 * @function hiddenFix 22 */ 23 var hiddenFix = function() { 24 25 return { 26 /** 27 * Sets all hidden parent elements and self to visibile. 28 * 29 * @method adjust 30 * @param {jQuery Object} $child 31 */ 32 33 // We'll use this to temporarily store style properties. 34 tmp : [], 35 36 // We'll use this to set hidden parent elements. 37 hidden : null, 38 39 adjust : function( $child ) { 40 // Internal reference. 41 var _self = this; 42 43 // Set all hidden parent elements, including this element. 44 _self.hidden = $child.parents().andSelf().filter( ":hidden" ); 45 46 // Loop through all hidden elements. 47 _self.hidden.each( function() { 48 49 // Cache the element. 50 var $elem = $( this ); 51 52 // Store the style attribute. 53 // Undefined if element doesn't have a style attribute. 54 _self.tmp.push( $elem.attr( 'style' ) ); 55 56 // Set the element's display property to block, 57 // but ensure it's visibility is hidden. 58 $elem.css( { 'visibility' : 'hidden', 'display' : 'block' } ); 59 }); 60 61 }, // end adjust 62 63 /** 64 * Resets the elements previous state. 65 * 66 * @method reset 67 */ 68 reset : function() { 69 // Internal reference. 70 var _self = this; 71 // Loop through our hidden element collection. 72 _self.hidden.each( function( i ) { 73 // Cache this element. 74 var $elem = $( this ), 75 _tmp = _self.tmp[ i ]; // Get the stored 'style' value for this element. 76 77 // If the stored value is undefined. 78 if( _tmp === undefined ) 79 // Remove the style attribute. 80 $elem.removeAttr( 'style' ); 81 else 82 // Otherwise, reset the element style attribute. 83 $elem.attr( 'style', _tmp ); 84 85 }); 86 // Reset the tmp array. 87 _self.tmp = []; 88 // Reset the hidden elements variable. 89 _self.hidden = null; 90 91 } // end reset 92 93 }; // end return 94 95 }; 96 97 jQuery.foundation = jQuery.foundation || {}; 98 jQuery.foundation.customForms = jQuery.foundation.customForms || {}; 99 100 $.foundation.customForms.appendCustomMarkup = function ( options ) { 101 102 var defaults = { 103 disable_class: "js-disable-custom" 104 }; 105 106 options = $.extend( defaults, options ); 107 108 function appendCustomMarkup(idx, sel) { 109 var $this = $(sel).hide(), 110 type = $this.attr('type'), 111 $span = $this.next('span.custom.' + type); 112 113 if ($span.length === 0) { 114 $span = $('<span class="custom ' + type + '"></span>').insertAfter($this); 115 } 116 117 $span.toggleClass('checked', $this.is(':checked')); 118 $span.toggleClass('disabled', $this.is(':disabled')); 119 } 120 121 function appendCustomSelect(idx, sel) { 122 var hiddenFixObj = hiddenFix(); 123 // 124 // jQueryify the <select> element and cache it. 125 // 126 var $this = $( sel ), 127 // 128 // Find the custom drop down element. 129 // 130 $customSelect = $this.next( 'div.custom.dropdown' ), 131 // 132 // Find the custom select element within the custom drop down. 133 // 134 $customList = $customSelect.find( 'ul' ), 135 // 136 // Find the custom a.current element. 137 // 138 $selectCurrent = $customSelect.find( ".current" ), 139 // 140 // Find the custom a.selector element (the drop-down icon). 141 // 142 $selector = $customSelect.find( ".selector" ), 143 // 144 // Get the <options> from the <select> element. 145 // 146 $options = $this.find( 'option' ), 147 // 148 // Filter down the selected options 149 // 150 $selectedOption = $options.filter( ':selected' ), 151 // 152 // Initial max width. 153 // 154 maxWidth = 0, 155 // 156 // We'll use this variable to create the <li> elements for our custom select. 157 // 158 liHtml = '', 159 // 160 // We'll use this to cache the created <li> elements within our custom select. 161 // 162 $listItems 163 ; 164 var $currentSelect = false;
165 // 166 // Should we not create a custom list? 167 // 168 if ( $this.hasClass( 'no-custom' ) ) return; 169 170 // 171 // Did we not create a custom select element yet? 172 // 173 if ( $customSelect.length === 0 ) { 174 // 175 // Let's create our custom select element! 176 // 177 178 // 179 // Determine what select size to use. 180 // 181 var customSelectSize = $this.hasClass( 'small' ) ? 'small' : 182 $this.hasClass( 'medium' ) ? 'medium' : 183 $this.hasClass( 'large' ) ? 'large' : 184 $this.hasClass( 'expand' ) ? 'expand' : '' 185 ; 186 // 187 // Build our custom list. 188 // 189 $customSelect = $('<div class="' + ['custom', 'dropdown', customSelectSize ].join( ' ' ) + '"><a href="#" class="selector"></a><ul /></div>"'); 190 // 191 // Grab the selector element 192 // 193 $selector = $customSelect.find( ".selector" ); 194 // 195 // Grab the unordered list element from the custom list. 196 // 197 $customList = $customSelect.find( "ul" ); 198 // 199 // Build our <li> elements. 200 // 201 liHtml = $options.map( function() { return "<li>" + $( this ).html() + "</li>"; } ).get().join( '' ); 202 // 203 // Append our <li> elements to the custom list (<ul>). 204 // 205 $customList.append( liHtml ); 206 // 207 // Insert the the currently selected list item before all other elements. 208 // Then, find the element and assign it to $currentSelect. 209 // 210 211 $currentSelect = $customSelect.prepend( '<a href="#" class="current">' + $selectedOption.html() + '</a>' ).find( ".current" ); 212 // 213 // Add the custom select element after the <select> element. 214 // 215 $this.after( $customSelect ) 216 // 217 //then hide the <select> element. 218 // 219 .hide(); 220 221 } else { 222 // 223 // Create our list item <li> elements. 224 // 225 liHtml = $options.map( function() { return "<li>" + $( this ).html() + "</li>"; } ).get().join( '' ); 226 // 227 // Refresh the ul with options from the select in case the supplied markup doesn't match. 228 // Clear what's currently in the <ul> element. 229 // 230 $customList.html( '' ) 231 // 232 // Populate the list item <li> elements. 233 // 234 .append( liHtml ); 235 236 } // endif $customSelect.length === 0 237 238 // 239 // Determine whether or not the custom select element should be disabled. 240 // 241 $customSelect.toggleClass( 'disabled', $this.is( ':disabled' ) ); 242 // 243 // Cache our List item elements. 244 // 245 $listItems = $customList.find( 'li' ); 246 247 // 248 // Determine which elements to select in our custom list. 249 // 250 $options.each( function ( index ) { 251 252 if ( this.selected ) { 253 // 254 // Add the selected class to the current li element 255 // 256 $listItems.eq( index ).addClass( 'selected' ); 257 // 258 // Update the current element with the option value. 259 // 260 if ($currentSelect) { 261 $currentSelect.html( this.value ); 262 } 263 264 } 265 266 }); 267 268 // 269 // Update the custom <ul> list width property. 270 // 271 $customList.css( 'width', 'inherit' ); 272 // 273 // Set the custom select width property. 274 // 275 $customSelect.css( 'width', 'inherit' ); 276 277 // 278 // If we're not specifying a predetermined form size. 279 // 280 if ( !$customSelect.is( '.small, .medium, .large, .expand' ) ) { 281 282 // ------------------------------------------------------------------------------------ 283 // This is a work-around for when elements are contained within hidden parents. 284 // For example, when custom-form elements are inside of a hidden reveal modal. 285 // 286 // We need to display the current custom list element as well as hidden parent elements 287 // in order to properly calculate the list item element's width property. 288 // ------------------------------------------------------------------------------------- 289 290 // 291 // Show the drop down. 292 // This should ensure that the list item's width values are properly calculated. 293 // 294 $customSelect.addClass( 'open' ); 295 // 296 // Quickly, display all parent elements. 297 // This should help us calcualate the width of the list item's within the drop down. 298 // 299 hiddenFixObj.adjust( $customList ); 300 // 301 // Grab the largest list item width. 302 // 303 maxWidth = ( $listItems.outerWidth() > maxWidth ) ? $listItems.outerWidth() : maxWidth; 304 // 305 // Okay, now reset the parent elements. 306 // This will hide them again. 307 // 308 hiddenFixObj.reset(); 309 // 310 // Finally, hide the drop down. 311 // 312 $customSelect.removeClass( 'open' ); 313 // 314 // Set the custom list width. 315 // 316 $customSelect.width( maxWidth + 18); 317 // 318 // Set the custom list element (<ul />) width. 319 // 320 $customList.width( maxWidth + 16 ); 321 322 } // endif 323 324 } 325 326 $('form.custom input:radio[data-customforms!=disabled]').each(appendCustomMarkup); 327 $('form.custom input:checkbox[data-customforms!=disabled]').each(appendCustomMarkup); 328 $('form.custom select[data-customforms!=disabled]').each(appendCustomSelect); 329 }; 330 331 var refreshCustomSelect = function($select) { 332 var maxWidth = 0, 333 $customSelect = $select.next(); 334 $options = $select.find('option'); 335 $customSelect.find('ul').html(''); 336 337 $options.each(function () { 338 $li = $('<li>' + $(this).html() + '</li>'); 339 $customSelect.find('ul').append($li); 340 }); 341 342 // re-populate 343 $options.each(function (index) { 344 if (this.selected) { 345 $customSelect.find('li').eq(index).addClass('selected'); 346 $customSelect.find('.current').html($(this).html()); 347 } 348 }); 349 350 // fix width 351 $customSelect.removeAttr('style') 352 .find('ul').removeAttr('style'); 353 $customSelect.find('li').each(function () { 354 $customSelect.addClass('open'); 355 if ($(this).outerWidth() > maxWidth) { 356 maxWidth = $(this).outerWidth(); 357 } 358 $customSelect.removeClass('open'); 359 }); 360 $customSelect.css('width', maxWidth + 18 + 'px'); 361 $customSelect.find('ul').css('width', maxWidth + 16 + 'px'); 362 363 }; 364 365 var toggleCheckbox = function($element) { 366 var $input = $element.prev(), 367 input = $input[0]; 368 369 if (false == $input.is(':disabled')) { 370 input.checked = ((input.checked) ? false : true); 371 $element.toggleClass('checked'); 372 373 $input.trigger('change'); 374 } 375 }; 376 377 var toggleRadio = function($element) { 378 var $input = $element.prev(), 379 input = $input[0]; 380 381 if (false == $input.is(':disabled')) { 382 $('input:radio[name="' + $input.attr('name') + '"]').each(function () { 383 $(this).next().removeClass('checked'); 384 }); 385 input.checked = ((input.checked) ? false : true); 386 $element.toggleClass('checked'); 387 388 $input.trigger('change'); 389 } 390 }; 391 392 $('form.custom span.custom.checkbox').on('click', function (event) { 393 event.preventDefault(); 394 event.stopPropagation(); 395 396 toggleCheckbox($(this)); 397 }); 398 399 $('form.custom span.custom.radio').on('click', function (event) { 400 event.preventDefault(); 401 event.stopPropagation(); 402 403 toggleRadio($(this)); 404 }); 405 406 $('form.custom select').on('change', function (event) { 407 refreshCustomSelect($(this)); 408 }); 409 410 $('form.custom label').on('click', function (event) { 411 var $associatedElement = $('#' + $(this).attr('for')), 412 $customCheckbox, 413 $customRadio; 414 if ($associatedElement.length !== 0) { 415 if ($associatedElement.attr('type') === 'checkbox') { 416 event.preventDefault(); 417 $customCheckbox = $(this).find('span.custom.checkbox'); 418 toggleCheckbox($customCheckbox); 419 } else if ($associatedElement.attr('type') === 'radio') { 420 event.preventDefault(); 421 $customRadio = $(this).find('span.custom.radio'); 422 toggleRadio($customRadio); 423 } 424 } 425 }); 426 427 $('form.custom div.custom.dropdown a.current, form.custom div.custom.dropdown a.selector').live('click', function (event) { 428 var $this = $(this), 429 $dropdown = $this.closest('div.custom.dropdown'), 430 $select = $dropdown.prev(); 431 432 event.preventDefault(); 433 $('div.dropdown').removeClass('open'); 434 435 if (false == $select.is(':disabled')) { 436 $dropdown.toggleClass('open'); 437 438 if ($dropdown.hasClass('open')) { 439 $(document).bind('click.customdropdown', function (event) { 440 $dropdown.removeClass('open'); 441 $(document).unbind('.customdropdown'); 442 }); 443 } else { 444 $(document).unbind('.customdropdown'); 445 } 446 return false;
447 } 448 }); 449 450 $('form.custom div.custom.dropdown li').live('click', function (event) { 451 var $this = $(this), 452 $customDropdown = $this.closest('div.custom.dropdown'), 453 $select = $customDropdown.prev(), 454 selectedIndex = 0; 455 456 event.preventDefault(); 457 event.stopPropagation(); 458 $('div.dropdown').removeClass('open'); 459 460 $this 461 .closest('ul') 462 .find('li') 463 .removeClass('selected'); 464 $this.addClass('selected'); 465 466 $customDropdown 467 .removeClass('open') 468 .find('a.current') 469 .html($this.html()); 470 471 $this.closest('ul').find('li').each(function (index) { 472 if ($this[0] == this) { 473 selectedIndex = index; 474 } 475 476 }); 477 $select[0].selectedIndex = selectedIndex; 478 479 $select.trigger('change'); 480 }); 481 482 483 $.fn.foundationCustomForms = $.foundation.customForms.appendCustomMarkup; 484 485})( jQuery );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.