1/* ----------------------------------------------------- 2 * Vanilla2 3 * (c) A-Websys (http://www.awebsys.cz) 4 * ----------------------------------------------------- 5 * $VanillaVersion:: 2.3 $ verze Vanilly 6 * $Revision:: 255 $ revize Vanilly 7 * $Author:: jaron $ autor 8 * $Date:: 2015-01-16 13:47:15 +0100 #$ datum 9 * ----------------------------------------------------- 10*/ 11/** 12 * OPTIONS: (vychozi hodnota na prvnim miste) 13 * messenger: null | messengerObject - objekt pro zobrazovani zprav 14 * messageElement: null | string | object | ? - $( messageElement ) bude element, do ktereho ma zobrazovat zpravy vychozi messenger 15 * successCleanup: 'remove'|'reset'|'none' - "vycisteni" formulare po uspesnem odeslani (odstranit formular, vyreserovat formular, nic) 16 * confirm: null | string | function() - pokud je nastaveno, tak necha uzivatele potrvrdit odeslani pres window.confirm() 17 * method: null | string | function() - pretlaci atribut METHOD formulare 18 * action: null | string | function() - pretlaci atribut ACTION formulare 19 * success: null | function(responseData) - vola se pokud ze serveru prisla informace o uspechu 20 * error: null | function(responseData) - vola se pokud ze serveru prisla informace o neuspechu (ale pouze pri 200) 21 * complete: null | function(status,responseData) - vola se vzdy (i pokud selze ajaxovy pozadavek) 22 * clsInAction: 'action-in-progress' - trida, ktera se zobrazi, u formulare behem "akce" 23 * 24 * - nema smysl zadavat messenger i messageElement 25 * - confirm, method, action lze zadat jako funkci (a vzdy kdyz je potreba hodnota, funkce se vyhodnoti) 26 * - vsechny callbacky se spousteji ve scope prislusneho formulare 27 */ 28;(function($, window, undefined){ 29 function Ajaxify ( formArgument, optionsArgument ) { // constructor 30 31 // private properties 32 var _this = this; 33 34 _this.settings = null; 35 36 37 function _expandOptionValue(optionValue, defaultValue) { 38 if ( null === optionValue || undefined === optionValue ) { 39 return defaultValue; 40 } 41 return 'function' === typeof _this.settings.action 42 ? optionValue.call(_this.form) 43 : optionValue; 44 } 45 46 47 function _processStatus( response ) { 48 var status = response.status; 49 if ( 'string' === typeof status ) { 50 switch( status ) { 51 case 'true': 52 case 'success': 53 return true; 54 default: 55 return false; 56 } 57 } 58 return status ? 'success' : 'error'; 59 } 60 function _processMessages( response ) { 61 var messages = response.messages || response.message || []; 62 return 'string' === typeof messages 63 ? [ messages ] 64 : messages; 65 } 66 67 68 function _removeErrors(){ 69 $( '.form-group', _this.form ).removeClass('has-error'); 70 $( 'ul.help-block', _this.form ).remove(); 71 } 72 73 function _showErrors( errors ) { 74 var name; 75 for( name in errors) { 76 77 var elm = _this.form.find('[name='+name+'][type!=hidden]'); 78 var elmType = elm.attr('type'); 79 80 elm.closest('.form-group').addClass('has-error'); 81 82 var errorEl = $('<ul></ul>').addClass('help-block'); 83 84 if (elmType === 'checkbox') { 85 var elmId = elm.attr('id'); 86 var elmLabel = $('label[for="' + elmId + '"]'); 87 errorEl.insertAfter(elmLabel); 88 } else { 89 errorEl.insertAfter(elm); 90 } 91 92 var mess = errors[name]; 93 94 for ( var i = 0; i < mess.length; i++ ) { 95 errorEl.append('<li>'+ mess[i] + '</li>'); 96 } 97 } 98 }; 99 100 /* 101 * vytvori defaultni messenger objekt 102 */ 103 function _createDefaultMessenger( messageEl ) { 104 var messenger = function( messages, status ) { 105 if ( 'string' === typeof messages ) { 106 messages = [messages]; 107 } 108 if ( messageEl && messageEl.length > 0 ) { 109 var alertClass = 'alert alert-' + status; 110 for ( var i = 0; i < messages.length; i++ ) { 111 $('<div>').addClass(alertClass).html(messages[i]).hide().appendTo(messageEl).fadeIn(500); 112 } 113 } else { //jinak se vyvola normalni alert 114 console.warn('ajaxify using alert'); 115 alert(messages.join('\n')); 116 } 117 }; 118 messenger.clear = function() { 119 messageEl && messageEl.empty && messageEl.empty(); 120 }; 121 return messenger; 122 } 123 124 125 function _processResult( response ) { 126 _this.messenger.clear(); 127 _removeErrors(); 128 129 var status = _processStatus( response ), 130 is_success = 'success' === status, 131 messages = _processMessages( response ) 132 ; 133 134 if ( !is_success && response.errors ) { 135 _showErrors( response.errors ); 136 } 137 if ( messages ) { 138 _this.messenger( messages, status ); 139 } 140 141 if ( is_success && 'function' === typeof _this.settings.success ) { 142 _this.settings.success.call( _this.form[0], response ); 143 } 144 if ( !is_success && 'function' === typeof _this.settings.error ) { 145 _this.settings.error.call( _this.form[0], response ); 146 } 147 if ( 'function' === typeof _this.settings.complete ) { 148 _this.settings.complete.call( _this.form[0], status, response ); 149 } 150 151 window.dataLayer = window.dataLayer || []; 152 153 if ( is_success ) {
154 _this.form.trigger('ajaxify:success', [_this.form[0], response]); 155 156 window.dataLayer.push({ 157 'event' : 'ajaxify:success' 158 }); 159 160 Ajaxify._cleanupHandlers[_this.settings.successCleanup] 161 && Ajaxify._cleanupHandlers[_this.settings.successCleanup].call(_this.form); 162 } else { 163 _this.form.trigger('ajaxify:error', [_this.form[0], response]); 164 165 window.dataLayer.push({ 166 'event' : 'ajaxify:error' 167 }); 168 } 169 } 170 171 function _onFormSubmit(e) { 172 e.preventDefault(); 173 174 var confimText = _expandOptionValue( _this.settings.confirm, null ); 175 176 if ( confimText ) { 177 if( ! window.confirm( confimText ) ) { 178 return false; 179 } 180 } 181 182 //var formData = _this.form.serializeArray(); 183 184 var formMethod = _expandOptionValue( _this.settings.method, _this.form.attr('method') ); 185 var formAction = _expandOptionValue( _this.settings.action, _this.form.attr('action') ); 186 187 _this.form.addClass(_this.settings.clsInAction); 188 189 var option = { 190 type: formMethod, 191 url: formAction, 192 dataType: 'json', 193 success: function(data){ 194 _processResult(data); 195 }, 196 complete: function(jqXHR, status) { 197 _this.form.removeClass(_this.settings.clsInAction); 198 if( "success" === status ) { // || "notmodified" === status 199 return; 200 } 201 if ( 'function' === typeof _this.settings.complete ) { 202 _this.settings.complete.call( _this.form[0], 'error', null ); 203 } 204 _this.messenger('Network Error '+jqXHR.status,'error'); 205 } 206 }; 207 208 if (_this.form.find(':file').length > 0 ) { 209 option.extraData = {'X-Vanilla2-Response-Format': 'text/plain'}; 210 option.iframe = true; 211 } 212 213 _this.form.ajaxSubmit(option); 214 } 215 216 217 function _checkOptions( options ) { 218 function warnType(type,name) { 219 console.warn('type '+type+' unsupported for option "'+name+'"'); 220 } 221 function checkTypeOrNull(name,type1, type2) { 222 if( ! options.hasOwnProperty(name) ) { 223 return true; 224 } 225 var type = typeof options[name]; 226 if ( null === options[name] 227 || ( type1 === type ) 228 || ( type2 === type ) 229 ) { 230 return true; 231 } else { 232 warnType(type,name); 233 options[name] = null; 234 return false; 235 } 236 } 237 checkTypeOrNull('success','function'); 238 checkTypeOrNull('error','function'); 239 checkTypeOrNull('complete','function'); 240 checkTypeOrNull('confirm','string','function'); 241 checkTypeOrNull('method','string','function'); 242 checkTypeOrNull('action','string','function'); 243 // nekontroluje se messageElement 244 if ( options.hasOwnProperty('messenger') && null !== options.messenger ) { 245 if ( 'function' !== typeof options.messenger || 'function' !== typeof options.messenger.clear ) { 246 console.warn('provided messenger lacks required API'); 247 options.messenger = null; 248 } 249 } 250 if ( options.hasOwnProperty('successCleanup') && ! Ajaxify._cleanupHandlers[options.successCleanup] ) { 251 console.warn('value "'+options.successCleanup+'" unsupported for option successCleanup'); 252 } 253 return options; 254 } 255 256 // privileged methods 257 this.init = function ( form, options ) { 258 259 options = _checkOptions( options ); 260 _this.settings = $.extend( {}, Ajaxify._defaults, options ); 261 _this.form = form; 262 if ( 'FORM' === form[0].tagName ) { 263 form.submit( _onFormSubmit ); 264 } 265 266 if ( _this.settings.messenger ) { 267 _this.messenger = _this.settings.messenger; 268 } else { 269 var messageElement; 270 messageElement = _this.settings.messageElement 271 ? $( _this.settings.messageElement ) 272 : form.prev('.widget-message'); 273 _this.messenger = _createDefaultMessenger( messageElement.length ? messageElement : null ); 274 } 275 }; 276 277 // constructor logic 278 optionsArgument = optionsArgument || {}; 279 this.init(formArgument, optionsArgument); 280 } 281 282 // public static properties 283 Ajaxify._defaults = { 284 success: null, // function(response) scope: form 285 confirm: null, // potvrzeni odeslani formulare 286 messageElement: null, // message element 287 messenger: null, // messenger object 288 method: null, // form METHOD 289 action: null, // form ACTION url\ 290 successCleanup: 'remove', // 'remove'|'none'|'reset'|'visibleReset' 291 clsInAction: 'action-in-progress', 292 error: null, // function(response) scope: form,
293 complete: null // function(status,response) scope: form, 294 }; 295 296 Ajaxify._cleanupHandlers = { 297 // this = $(form) 298 remove: function(){ 299 var form = this; 300 form.hide(200,function(){ form.remove(); }); 301 }, 302 reset: function(){ 303 this[0].reset(); 304 }, 305 visibleReset: function(){ 306 var form = this; 307 form.find(':input').not(':button, :submit, :reset, :hidden, :checkbox, :radio').val(''); 308 form.find(':checkbox, :radio').prop('checked', false); 309 }, 310 none: function(){} 311 }; 312 313 /** 314 * v zasade genericka metoda 315 */ 316 $.fn.ajaxify = function( first_arg ){ 317 var args = arguments, 318 options = {}, 319 method = null, 320 result; 321 322 if ( typeof first_arg === 'object') { 323 options = first_arg; 324 } 325 if ( typeof first_arg === 'string' && first_arg[0] !== '_' && first_arg !== 'init' ) { 326 method = first_arg; 327 } 328 329 this.each(function(){ 330 var form = $(this), 331 ajaxify = form.data('plugin_ajaxify'); 332 333 if ( ! ajaxify && 'destroy' !== method ) { 334 ajaxify = new Ajaxify(form, options); 335 form.data('plugin_ajaxify', ajaxify); 336 } 337 338 if ( method && ajaxify instanceof Ajaxify && typeof ajaxify[method] === 'function' ) { 339 result = ajaxify[method].apply( ajaxify, Array.prototype.slice.call( args, 1 ) ); 340 } 341 342 if ( 'destroy' === method ) { 343 form.data('plugin_ajaxify', null); 344 } 345 }); 346 347 return result !== undefined ? result : this; 348 }; 349 350})(jQuery, window);
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.