1"use strict"; 2 3/** 4 * Slideform - A plugin to make full height sliders with forms. 5 * 6 * Author: Andrés Smerkin <[email protected]> 7 */ 8( function ($) { 9 10 $.fn.slideform = function( userOptions, args ) { 11 12 // The form object. 13 var $form = $(this); 14 15 // Slides List 16 var $slides = $form.find('.slideform-slide'); 17 18 // The slideshows wrapper, or tracker. 19 var $wrapper = null; 20 21 // The track is where the wrapper slides in. 22 var $track = null; 23 24 // We start our current slide in 0. 25 var $current = 0; 26 27 // The max slide we've reached. 28 var $max = 0; 29 30 // Our default options. These will be overriden with the user defined options. 31 var $options = { 32 nextButtonText: 'Next', 33 prevButtonText: 'Back', 34 submitButtonText: 'Send', 35 validate: null, 36 submit: null 37 } 38 39 // Here we should load all user defined options into our array. Undefined 40 // options will default to our main options object. 41 if ( typeof userOptions !== 'undefined' ) { 42 for (var attr in userOptions) { $options[attr] = userOptions[attr]; } 43 } 44 45 // Let's initialize the slider, validations, etc. 46 init(); 47 48 49 // Back and next button behaviors. 50 $form.on('click', '.slideform-btn', function (event) { 51 event.preventDefault(); 52 var btn = $(this); 53 54 if ( btn.hasClass('slideform-btn-next') ) { 55 56 var valid = true; 57 btn.closest('.slideform-group').find('input').each ( function () {
58 if ($.validator && !$(this).valid()) { 59 valid = false; 60 } 61 }); 62 63 if ( valid ) $form.goForward(); 64 } 65 66 if ( btn.hasClass('slideform-btn-prev') ) { 67 $form.goBack(); 68 } 69 70 if ( btn.hasClass('slideform-btn-submit')) { 71 $form.submit(); 72 }; 73 74 }); 75 76 77 /* 78 * Binds for checkbox and radio buttons, to enable or disable behaviors 79 */ 80 $form.find('input[type=radio] + span, input[type=checkbox] + span').on( 'click', function() { 81 82 // Getting our element behind the span. 83 var input = $(this).prev(); 84 85 if ( (input.attr('type') != 'radio' || !input.is(':checked')) && !input.is(':disabled') ) { 86 input.prop('checked', !input.is(':checked') ).change(); 87 } 88 89 }); 90 91 92 /* 93 * When a value change, we need to watch the result to trigger condition updates. 94 * Here probably we could get an array of form values, and then use theat 95 */ 96 $('input, textarea, select').on('blur change', function (event) { 97 triggerConditions(); 98 }); 99 100 101 // We adjust slides size on resizing. 102 $(window).resize( function() { 103 setSlidesHeight(); 104 }); 105 106 107 108 function init() { 109 110 $form.addClass('slideform-form') 111 .addClass('slideform-initialized'); 112 113 // Adding the track. 114 $track = $('<div />', { class: 'slideform-track'}) 115 .insertBefore( $form.find('.slideform-slide').eq(0) ); 116 117 // Adding the wrapper. 118 $wrapper = $('<div />', { class: 'slideform-wrapper' }) 119 .appendTo( $track ) 120 .append($form.find('.slideform-slide')); 121 122 123 setSlidesHeight(); 124 125 /* 126 * If there is a validation array, and we detecte jQuery validation is 127 * present, then we validate the form. 128 */ 129 enableValidation(); 130 131 132 /* 133 * We need to update buttons status so users can't go beyond the form 134 * if they have not filled all fields correctly. 135 */ 136 updateButtonsStatus( $current ); 137 138 139 /* 140 * We need to add the continue buttons via Javascript, so we don't bloat 141 * the html file with this type of content, only referred to our work. 142 */ 143 $form.find('.slideform-slide').each( function (k, v) { 144 145 // Setting the active slide. 146 if ( k == 0 ) $(this).addClass('active'); 147 148 if ( k < $slides.length - 2 ) { 149 $(this).find('.slideform-group').append('<button class="slideform-btn slideform-btn-next">' + $options.nextButtonText + '</button>'); 150 } else if (k < $slides.length - 1 ) { 151 $(this).find('.slideform-group').append('<button type="submit" class="slideform-btn slideform-btn-submit"><i class="icon-check"></i> ' + $options.submitButtonText + '</button>') 152 } 153 }); 154 155 /* 156 * Let's disable all inputs within elements with conditions. The only 157 * way these can be enabled is if the parent conditiosn are met. 158 */ 159 $('[data-condition]').find('input, select, textarea, button').prop('disabled', true ); 160 161 } 162 163 164 $form.on('submit',function ( event ) { 165 if ( $options.submit ) { 166 event.preventDefault(); 167 $options.submit (event, $form); 168 } 169 }); 170 171 172 173 /* 174 * Enables jQuery validation for our elements. Useful to contain all the logic 175 * related to validation initialization. 176 * 177 * We want to keep this function private. 178 */ 179 function enableValidation() { 180 181 /* 182 * We don't load validation if these are not defined. 183 */ 184 if ( !$options.validate || !$.validator ) return; 185 186 var data = { 187 // We change where errors are shown for radio buttons and checkboxes. 188 errorPlacement: function(error, element) { 189 if(element.attr("type") == "radio" || element.attr('type') == 'checkbox') { 190 error.appendTo( element.closest('div') ); 191 } else { 192 error.insertAfter(element); 193 } 194 } 195 } 196 197 if ( typeof $options.validate.rules !== 'undefined' ) { 198 data.rules = $options.validate.rules; 199 } 200 201 if ( typeof $options.validate.messages !== 'undefined' ) { 202 data.messages = $options.validate.messages; 203 } 204 205 $form.validate( data ); 206 } 207 208 209 210 /* 211 * Go to a Specific slide. 212 */ 213 $form.goTo = function( slide ) { 214 var translation = slide * ( 100 / $slides.length ); 215 var percentage = 0; 216 217 if ( slide <= 0 ) { 218 percentage = 0; 219 } else if ( slide == ( $slides.length )) { 220 percentage = 100; 221 } else { 222 percentage = (slide) * ( 100 / ($slides.length - 1) ); 223 } 224 225 // We translate the wrapper to produce the sliding effect. 226 $wrapper.css('transform', 'translateY(' + translation * -1 + '%)'); 227 228 // We also update the progress bar. 229 $('.slideform-progress-bar span').css('width', percentage + '%' ); 230 231 // We need to scroll top the active slide. 232 $slides.filter('.active').animate({ scrollTop: 0}, 'fast' ); 233 234 // Let's set the active class. 235 $slides.eq( slide ).addClass('active').siblings().removeClass('active'); 236 237 // Let's set the new max if available. 238 $max = ( slide > $max ) ? slide : $max; 239 240 // Let's update buttons status 241 updateButtonsStatus( slide ); 242 } 243 244 /* 245 * Going Forward to the next slide. 246 */ 247 $form.goForward = function() { 248 249 // First let's check validation rules and we go forward if they allow us 250 if (!validateSlideInputs( $current )) return; 251 252 // If there are no more slides, we just return. 253 if ( $current == ( $slides.length - 1 )) return; 254 255 // Let's go to the next slide. 256 $form.goTo( ++$current ); 257 } 258 259 260 /* 261 * Going Backwards to the previous slide. 262 */ 263 $form.goBack = function() { 264 if ( $current == 0 ) return; 265 266 $current--; 267 $form.goTo( $current ); 268 } 269 270 271 /** 272 * Sets the parent track height to all slides. 273 * @return {[type]} [description] 274 */ 275 function setSlidesHeight() { 276 $form.find('.slideform-slide').css('height', $track.outerHeight()); 277 } 278 279 280 /** 281 * Updating buttons status. 282 * @param integer slideNumber the slide number 283 * @return void 284 */ 285 function updateButtonsStatus( slideNumber ) { 286 $form.find('.slideform-btn-next').prop('disabled', ( slideNumber == $slides.length - 1) ); 287 $form.find('.slideform-btn-prev').prop('disabled', ( slideNumber == 0) ); 288 289 $form.find('footer .slideform-btn-next').prop('disabled', ( slideNumber >= $max )); 290 } 291 292 293 /** 294 * Validates the current slide ( active slide ) inputs. Returns true if all 295 * imputs are valid. 296 * 297 * @param integer slideNumber Slide Number 298 * @return void 299 */ 300 function validateSlideInputs ( slideNumber ) { 301 302 if (!$.validator) return true; 303
304 var valid = true; 305 306 $slides.eq( slideNumber ).find('input, textarea, select').each( function () { 307 if ( !$(this).valid() ) valid = false; 308 }); 309 310 return valid; 311 } 312 313 314 /** 315 * Triggers and excecutes or hides different conditions. 316 * @return {[type]} [description] 317 */ 318 function triggerConditions () { 319 320 var input = {}; 321 var array = $form.serializeArray().map( function (i) { input[i.name] = i.value }); 322 323 // watching chnges. 324 $form.find('[data-condition]').each( function () { 325 326 var valid = eval( $(this).data('condition') ); 327 328 // We toggle true or false, depending if the condition is valid or not. 329 $(this).find('input, textarea, select').prop('disabled', !valid); 330 331 if ( valid ) { 332 $(this).slideDown(); 333 } else { 334 $(this).slideUp(); 335 } 336 }); 337 } 338 339 340 function callFunction( name, args ) { 341 var fn = '$form.' + name + '()'; 342 console.log ( fn ); 343 return eval( fn ); 344 } 345 346 347 $form.on('goForward', function() { 348 $form.goForward(); 349 }); 350 351 $form.on('goBack', function() { 352 $form.goBack(); 353 }); 354 355 $form.on('goTo', function (event, slide) { 356 $form.goTo( slide ); 357 }); 358 } 359 360 361}(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.