PageSourceSearch

https://www.zitate.de/assets/c7b9c917/jquery.yiiactiveform.js

js zitate.de collected 2026-10-01 14:34:11 UTC 14,255 bytes, 426 lines download raw bytes

1/**
2 * jQuery yiiactiveform plugin file.
3 *
4 * @author Qiang Xue <[email protected]>
5 * @link http://www.yiiframework.com/
6 * @copyright Copyright &copy; 2008-2010 Yii Software LLC
7 * @license http://www.yiiframework.com/license/
8 * @version $Id: jquery.yiiactiveform.js 3538 2012-01-14 18:24:30Z mdomba $
9 * @since 1.1.1
10 */
11
12(function ($) {
13	/*
14	 * returns the value of the CActiveForm input field
15	 * performs additional checks to get proper values for checkbox / radiobutton / checkBoxList / radioButtonList
16	 * @param o object the jQuery object of the input element
17	 */
18	var getAFValue = function (o) {
19		var type,
20			c = [];
21		if (!o.length) {
22			return undefined;
23		}
24		if (o[0].tagName.toLowerCase() === 'span') {
25			o.find(':checked').each(function () {
26				c.push(this.value);
27			});
28			return c.join(',');
29		}
30		type = o.attr('type');
31		if (type === 'checkbox' || type === 'radio') {
32			return o.filter(':checked').val();
33		} else {
34			return o.val();
35		}
36	};
37
38	/**
39	 * yiiactiveform set function.
40	 * @param options map settings for the active form plugin. Please see {@link CActiveForm::options} for availablel options.
41	 */
42	$.fn.yiiactiveform = function (options) {
43		return this.each(function () {
44			var settings = $.extend({}, $.fn.yiiactiveform.defaults, options || {}),
45				$form = $(this);
46
47			if (settings.validationUrl === undefined) {
48				settings.validationUrl = $form.attr('action');
49			}
50			$.each(settings.attributes, function (i) {
51				this.value = getAFValue($form.find('#' + this.inputID));
52				settings.attributes[i] = $.extend({}, {
53					validationDelay: settings.validationDelay,
54					validateOnChange: settings.validateOnChange,
55					validateOnType: settings.validateOnType,
56					hideErrorMessage: settings.hideErrorMessage,
57					inputContainer: settings.inputContainer,
58					errorCssClass: settings.errorCssClass,
59					successCssClass: settings.successCssClass,
60					beforeValidateAttribute: settings.beforeValidateAttribute,
61					afterValidateAttribute: settings.afterValidateAttribute,
62					validatingCssClass: settings.validatingCssClass
63				}, this);
64			});
65			$form.data('settings', settings);
66
67			settings.submitting = false;  // whether it is waiting for ajax submission result
68			var validate = function (attribute, forceValidate) {
69				if (forceValidate) {
70					attribute.status = 2;
71				}
72				$.each(settings.attributes, function () {
73					if (this.value !== getAFValue($form.find('#' + this.inputID))) {
74						this.status = 2;
75						forceValidate = true;
76					}
77				});
78				if (!forceValidate) {
79					return;
80				}
81
82				if (settings.timer !== undefined) {
83					clearTimeout(settings.timer);
84				}
85				settings.timer = setTimeout(function () {
86					if (settings.submitting || $form.is(':hidden')) {
87						return;
88					}
89					if (attribute.beforeValidateAttribute === undefined || attribute.beforeValidateAttribute($form, attribute)) {
90						$.each(settings.attributes, function () {
91							if (this.status === 2) {
92								this.status = 3;
93								$.fn.yiiactiveform.getInputContainer(this, $form).addClass(this.validatingCssClass);
94							}
95						});
96						$.fn.yiiactiveform.validate($form, function (data) {
97							var hasError = false;
98							$.each(settings.attributes, function () {
99								if (this.status === 2 || this.status === 3) {
100									hasError = $.fn.yiiactiveform.updateInput(this, data, $form) || hasError;
101								}
102							});
103							if (attribute.afterValidateAttribute !== undefined) {
104								attribute.afterValidateAttribute($form, attribute, data, hasError);
105							}
106						});
107					}
108				}, attribute.validationDelay);
109			};
110
111			$.each(settings.attributes, function (i, attribute) {
112				if (this.validateOnChange) {
113					$form.find('#' + this.inputID).change(function () {
114						validate(attribute, false);
115					}).blur(function () {
116						if (attribute.status !== 2 && attribute.status !== 3) {
117							validate(attribute, !attribute.status);
118						}
119					});
120				}
121				if (this.validateOnType) {
122					$form.find('#' + this.inputID).keyup(function () {
123						if (attribute.value !== getAFValue($(this))) {
124							validate(attribute, false);
125						}
126					});
127				}
128			});
129
130			if (settings.validateOnSubmit) {
131				$form.find(':submit').live('mouseup keyup', function () {
132					$form.data('submitObject', $(this));
133				});
134				var validated = false;
135				$form.submit(function () {
136					if (validated) {
137						return true;
138					}
139					if (settings.timer !== undefined) {
140						clearTimeout(settings.timer);
141					}
142					settings.submitting = true;
143					if (settings.beforeValidate === undefined || settings.beforeValidate($form)) {
144						$.fn.yiiactiveform.validate($form, function (data) {
145							var hasError = false;
146							$.each(settings.attributes, function () {
147								hasError = $.fn.yiiactiveform.updateInput(this, data, $form) || hasError;
148							});
149							$.fn.yiiactiveform.updateSummary($form, data);
150							if (settings.afterValidate === undefined || settings.afterValidate($form, data, hasError)) {
151								if (!hasError) {
152									validated = true;
153									var $button = $form.data('submitObject') || $form.find(':submit:first');
154									// TODO: if the submission is caused by "change" event, it will not work
155									if ($button.length) {
156										$button.click();
157									} else {  // no submit button in the form
158										$form.submit();
159									}
160									return;
161								}
162							}
163							settings.submitting = false;
164						});
165					} else {
166						settings.submitting = false;
167					}
168					return false;
169				});
170			}
171
172			/*
173			 * In case of reseting the form we need to reset error messages
174			 * NOTE1: $form.reset - does not exist
175			 * NOTE2: $form.live('reset', ...) does not work
176			 */
177			$form.bind('reset', function () {
178				/*
179				 * because we bind directly to a form reset event, not to a reset button (that could or could not exist),
180				 * when this function is executed form elements values have not been reset yet,
181				 * because of that we use the setTimeout
182				 */
183				setTimeout(function () {
184					$.each(settings.attributes, function () {
185						this.status = 0;
186						var $error = $form.find('#' + this.errorID),
187							$container = $.fn.yiiactiveform.getInputContainer(this, $form);
188
189						$container.removeClass(
190							this.validatingCssClass + ' ' +
191							this.errorCssClass + ' ' +
192							this.successCssClass
193						);
194
195						$error.html('').hide();
196
197						/*
198						 * without the setTimeout() we would get here the current entered value before the reset instead of the reseted value
199						 */
200						this.value = getAFValue($form.find('#' + this.inputID));
201					});
202					/*
203					 * If the form is submited (non ajax) with errors, labels and input gets the class 'error'
204					 */
205					$form.find('label, input').each(function () {
206						$(this).removeClass('error');
207					});
208					$('#' + settings.summaryID).hide().find('ul').html('');
209					//.. set to initial focus on reset
210					if (settings.focus !== undefined && !window.location.hash) {
211						$form.find(settings.focus).focus();
212					}
213				}, 1);
214			});
215
216			/*
217			 * set to initial focus
218			 */
219			if (settings.focus !== undefined && !window.location.hash) {
220				$form.find(settings.focus).focus();
221			}
222		});
223	};
224
225	/**
226	 * Returns the container element of the specified attribute.
227	 * @param attribute object the configuration for a particular attribute.
228	 * @param form the form jQuery object
229	 * @return jquery the jquery representation of the container
230	 */
231	$.fn.yiiactiveform.getInputContainer = function (attribute, form) {
232		if (attribute.inputContainer === undefined) {
233			return form.find('#' + attribute.inputID).closest('div');
234		} else {
235			return form.find(attribute.inputContainer).filter(':has("#' + attribute.inputID + '")');
236		}
237	};
238
239	/**
240	 * updates the error message and the input container for a particular attribute.
241	 * @param attribute object the configuration for a particular attribute.
242	 * @param messages array the json data obtained from the ajax validation request
243	 * @param form the form jQuery object
244	 * @return boolean whether there is a validation error for the specified attribute
245	 */
246	$.fn.yiiactiveform.updateInput = function (attribute, messages, form) {
247		attribute.status = 1;
248		var $error, $container,
249			hasError = false,
250			$el = form.find('#' + attribute.inputID);
251		if ($el.length) {
252			hasError = messages !== null && $.isArray(messages[attribute.id]) && messages[attribute.id].length > 0;
253			$error = form.find('#' + attribute.errorID);
254			$container = $.fn.yiiactiveform.getInputContainer(attribute, form);
255
256			$container.removeClass(
257				attribute.validatingCssClass + ' ' + 
258				attribute.errorCssClass + ' ' + 
259				attribute.successCssClass
260			);
261
262			if (hasError) {
263				$error.html(messages[attribute.id][0]);
264				$container.addClass(attribute.errorCssClass);
265			} else if (attribute.enableAjaxValidation || attribute.clientValidation) {
266				$container.addClass(attribute.successCssClass);
267			}
268			if (!attribute.hideErrorMessage) {
269				$error.toggle(hasError);
270			}
271
272			attribute.value = getAFValue($el);
273		}
274		return hasError;
275	};
276
277	/**
278	 * updates the error summary, if any.
279	 * @param form jquery the jquery representation of the form
280	 * @param messages array the json data obtained from the ajax validation request
281	 */
282	$.fn.yiiactiveform.updateSummary = function (form, messages) {
283		var settings = $(form).data('settings'),
284			content = '';
285		if (settings.summaryID === undefined) {
286			return;
287		}
288		if (messages) {
289			$.each(settings.attributes, function () {
290				if ($.isArray(messages[this.id])) {
291					$.each(messages[this.id], function (j, message) {
292						content = content + '<li>' + message + '</li>';
293					});
294				}
295			});
296		}
297		$('#' + settings.summaryID).toggle(content !== '').find('ul').html(content);
298	};
299
300	/**
301	 * Performs the ajax validation request.
302	 * This method is invoked internally to trigger the ajax validation.
303	 * @param form jquery the jquery representation of the form
304	 * @param successCallback function the function to be invoked if the ajax request succeeds
305	 * @param errorCallback function the function to be invoked if the ajax request fails
306	 */
307	$.fn.yiiactiveform.validate = function (form, successCallback, errorCallback) {
308		var $form = $(form),
309			settings = $form.data('settings'),
310			needAjaxValidation = false,
311			messages = {};
312		$.each(settings.attributes, function () {
313			var value,
314				msg = [];
315			if (this.clientValidation !== undefined && (settings.submitting || this.status === 2 || this.status === 3)) {
316				value = getAFValue($form.find('#' + this.inputID));
317				this.clientValidation(value, msg, this);
318				if (msg.length) {
319					messages[this.id] = msg;
320				}
321			}
322			if (this.enableAjaxValidation && !msg.length && (settings.submitting || this.status === 2 || this.status === 3)) {
323				needAjaxValidation = true;
324			}
325		});
326
327		if (!needAjaxValidation || settings.submitting && !$.isEmptyObject(messages)) {
328			if (settings.submitting) {
329				// delay callback so that the form can be submitted without problem
330				setTimeout(function () {
331					successCallback(messages);
332				}, 200);
333			} else {
334				successCallback(messages);
335			}
336			return;
337		}
338
339		var $button = $form.data('submitObject'),
340			extData = '&' + settings.ajaxVar + '=' + $form.attr('id');
341		if ($button && $button.length) {
342			extData += '&' + $button.attr('name') + '=' + $button.attr('value');
343		}
344
345		$.ajax({
346			url : settings.validationUrl,
347			type : $form.attr('method'),
348			data : $form.serialize() + extData,
349			dataType : 'json',
350			success : function (data) {
351				if (data !== null && typeof data === 'object') {
352					$.each(settings.attributes, function () {
353						if (!this.enableAjaxValidation) {
354							delete data[this.id];
355						}
356					});
357					successCallback($.extend({}, messages, data));
358				} else {
359					successCallback(messages);
360				}
361			},
362			error : function () {
363				if (errorCallback !== undefined) {
364					errorCallback();
365				}
366			}
367		});
368	};
369
370	/**
371	 * Returns the configuration for the specified form.
372	 * The configuration contains all needed information to perform ajax-based validation.
373	 * @param form jquery the jquery representation of the form
374	 * @return object the configuration for the specified form.
375	 */
376	$.fn.yiiactiveform.getSettings = function (form) {
377		return $(form).data('settings');
378	};
379
380	$.fn.yiiactiveform.defaults = {
381		ajaxVar: 'ajax',
382		validationUrl: undefined,
383		validationDelay: 200,
384		validateOnSubmit : false,
385		validateOnChange : true,
386		validateOnType : false,
387		hideErrorMessage : false,
388		inputContainer : undefined,
389		errorCssClass : 'error',
390		successCssClass : 'success',
391		validatingCssClass : 'validating',
392		summaryID : undefined,
393		timer: undefined,
394		beforeValidateAttribute: undefined, // function (form, attribute) : boolean
395		afterValidateAttribute: undefined,  // function (form, attribute, data, hasError)
396		beforeValidate: undefined, // function (form) : boolean
397		afterValidate: undefined,  // function (form, data, hasError) : boolean
398		/**
399		 * list of attributes to be validated. Each array element is of the following structure:
400		 * {
401		 *     id : 'ModelClass_attribute', // the unique attribute ID
402		 *     model : 'ModelClass', // the model class name
403		 *     name : 'name', // attribute name
404		 *     inputID : 'input-tag-id',
405		 *     errorID : 'error-tag-id',
406		 *     value : undefined,
407		 *     status : 0,  // 0: empty, not entered before,  1: validated, 2: pending validation, 3: validating
408		 *     focus : undefined,  // jquery selector that indicates which element to receive input focus initially
409		 *     validationDelay: 200,
410		 *     validateOnChange : true,
411		 *     validateOnType : false,
412		 *     hideErrorMessage : false,
413		 *     inputContainer : undefined,
414		 *     errorCssClass : 'error',
415		 *     successCssClass : 'success',
416		 *     validatingCssClass : 'validating',
417		 *     enableAjaxValidation : true,
418		 *     enableClientValidation : true,
419		 *     clientValidation : undefined, // function (value, messages, attribute) : client-side validation
420		 *     beforeValidateAttribute: undefined, // function (form, attribute) : boolean
421		 *     afterValidateAttribute: undefined,  // function (form, attribute, data, hasError)
422		 * }
423		 */
424		attributes : []
425	};
426})(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.