~horux-dev/horux-webcli/thfo

« back to all changes in this revision

Viewing changes to yii/framework/web/js/source/jquery.yiiactiveform.js

  • Committer: Thierry Forchelet
  • Date: 2011-02-25 13:30:15 UTC
  • Revision ID: thierry.forchelet@letux.ch-20110225133015-zxyj9w7sqv8ly971
Initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * jQuery yiiactiveform plugin file.
 
3
 *
 
4
 * @author Qiang Xue <qiang.xue@gmail.com>
 
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 2779 2010-12-28 13:10:09Z qiang.xue $
 
9
 * @since 1.1.1
 
10
 */
 
11
 
 
12
;(function($) {
 
13
        /**
 
14
         * yiiactiveform set function.
 
15
         * @param options map settings for the active form plugin. Please see {@link CActiveForm::options} for availablel options.
 
16
         */
 
17
        $.fn.yiiactiveform = function(options) {
 
18
                return this.each(function() {
 
19
                        var settings = $.extend({}, $.fn.yiiactiveform.defaults, options || {});
 
20
                        var $form = $(this);
 
21
                        var id = $form.attr('id');
 
22
                        if(settings.validationUrl == undefined)
 
23
                                settings.validationUrl = $form.attr('action');
 
24
                        $.each(settings.attributes, function(i,attribute){
 
25
                                settings.attributes[i] = $.extend({
 
26
                                        validationDelay : settings.validationDelay,
 
27
                                        validateOnChange : settings.validateOnChange,
 
28
                                        validateOnType : settings.validateOnType,
 
29
                                        hideErrorMessage : settings.hideErrorMessage,
 
30
                                        inputContainer : settings.inputContainer,
 
31
                                        errorCssClass : settings.errorCssClass,
 
32
                                        successCssClass : settings.successCssClass,
 
33
                                        beforeValidateAttribute : settings.beforeValidateAttribute,
 
34
                                        afterValidateAttribute : settings.afterValidateAttribute,
 
35
                                        validatingCssClass : settings.validatingCssClass
 
36
                                }, attribute);
 
37
                                settings.attributes[i].value = $('#'+attribute.inputID, $form).val();
 
38
                        });
 
39
                        $(this).data('settings', settings);
 
40
 
 
41
                        var submitting=false;  // whether it is waiting for ajax submission result
 
42
                        var validate = function(attribute, forceValidate) {
 
43
                                if (forceValidate)
 
44
                                        attribute.status = 2;
 
45
                                $.each(settings.attributes, function(){
 
46
                                        if (this.value != $('#'+this.inputID, $form).val()) {
 
47
                                                this.status = 2;
 
48
                                                forceValidate = true;
 
49
                                        }
 
50
                                });
 
51
                                if (!forceValidate)
 
52
                                        return;
 
53
 
 
54
                                if(settings.timer!=undefined) {
 
55
                                        clearTimeout(settings.timer);
 
56
                                }
 
57
 
 
58
                                settings.timer = setTimeout(function(){
 
59
                                        if(submitting)
 
60
                                                return;
 
61
                                        if(attribute.beforeValidateAttribute==undefined || attribute.beforeValidateAttribute($form, attribute)) {
 
62
                                                $.each(settings.attributes, function(){
 
63
                                                        if (this.status == 2) {
 
64
                                                                this.status = 3;
 
65
                                                                $.fn.yiiactiveform.getInputContainer(this, $form).addClass(this.validatingCssClass);
 
66
                                                        }
 
67
                                                });
 
68
                                                $.fn.yiiactiveform.validate($form, function(data) {
 
69
                                                        var hasError=false;
 
70
                                                        $.each(settings.attributes, function(){
 
71
                                                                if (this.status > 0) {
 
72
                                                                        hasError = $.fn.yiiactiveform.updateInput(this, data, $form) || hasError;
 
73
                                                                }
 
74
                                                        });
 
75
                                                        if(attribute.afterValidateAttribute!=undefined) {
 
76
                                                                attribute.afterValidateAttribute($form,attribute,data,hasError);
 
77
                                                        }
 
78
                                                });
 
79
                                        }
 
80
                                }, attribute.validationDelay);
 
81
                        };
 
82
 
 
83
                        $.each(settings.attributes, function(i, attribute) {
 
84
                                if (attribute.validateOnChange) {
 
85
                                        $('#'+attribute.inputID, $form).change(function(){
 
86
                                                validate(attribute,false);
 
87
                                        }).blur(function(){
 
88
                                                if(attribute.status!=2 && attribute.status!=3)
 
89
                                                        validate(attribute, !attribute.status);
 
90
                                        });
 
91
                                }
 
92
                                if (attribute.validateOnType) {
 
93
                                        $('#'+attribute.inputID, $form).keyup(function(){
 
94
                                                if (attribute.value != $('#'+attribute.inputID, $form).val())
 
95
                                                        validate(attribute, false);
 
96
                                        });
 
97
                                }
 
98
                        });
 
99
 
 
100
                        if (settings.validateOnSubmit) {
 
101
                                $form.find(':submit').live('mouseup keyup',function(){
 
102
                                        $form.data('submitObject',$(this));
 
103
                                });
 
104
                                var validated = false;
 
105
                                $form.submit(function(){
 
106
                                        if (validated)
 
107
                                                return true;
 
108
                                        if(settings.timer!=undefined) {
 
109
                                                clearTimeout(settings.timer);
 
110
                                        }
 
111
                                        submitting=true;
 
112
                                        if(settings.beforeValidate==undefined || settings.beforeValidate($form)) {
 
113
                                                $.fn.yiiactiveform.validate($form, function(data){
 
114
                                                        var hasError = false;
 
115
                                                        $.each(settings.attributes, function(i, attribute){
 
116
                                                                hasError = $.fn.yiiactiveform.updateInput(attribute, data, $form) || hasError;
 
117
                                                        });
 
118
                                                        $.fn.yiiactiveform.updateSummary($form, data);
 
119
                                                        if(settings.afterValidate==undefined || settings.afterValidate($form, data, hasError)) {
 
120
                                                                if(!hasError) {
 
121
                                                                        validated = true;
 
122
                                                                        var $button = $form.data('submitObject') || $form.find(':submit:first');
 
123
                                                                        // TODO: if the submission is caused by "change" event, it will not work
 
124
                                                                        if ($button.length)
 
125
                                                                                $button.click();
 
126
                                                                        else  // no submit button in the form
 
127
                                                                                $form.submit();
 
128
                                                                        return false;
 
129
                                                                }
 
130
                                                        }
 
131
                                                        submitting=false;
 
132
                                                });
 
133
                                        }
 
134
                                        else {
 
135
                                                submitting=false;
 
136
                                        }
 
137
                                        return false;
 
138
                                });
 
139
                        }
 
140
 
 
141
                        /*
 
142
                         * In case of reseting the form we need to reset error messages
 
143
                         * NOTE1: $form.reset - does not exist
 
144
                         * NOTE2: $form.live('reset',...) does not work
 
145
                         */
 
146
                        $form.bind('reset',function(){
 
147
                                /*
 
148
                                 * because we bind directly to a form reset event, not to a reset button (that could or could not exist),
 
149
                                 * when this function is executed form elements values have not been reset yet,
 
150
                                 * because of that we use the setTimeout
 
151
                                 */
 
152
                                setTimeout(function(){
 
153
                                        $.each(settings.attributes, function(i, attribute){
 
154
                                                attribute.status = 0;
 
155
                                                var $error = $('#'+attribute.errorID, $form);
 
156
                                                var $container = $.fn.yiiactiveform.getInputContainer(attribute, $form);
 
157
 
 
158
                                                $container
 
159
                                                        .removeClass(attribute.validatingCssClass)
 
160
                                                        .removeClass(attribute.errorCssClass)
 
161
                                                        .removeClass(attribute.successCssClass);
 
162
 
 
163
                                                $error.html('').hide();
 
164
 
 
165
                                                /*
 
166
                                                 * without the setTimeout() call val() would return the entered value instead of the reseted value
 
167
                                                 */
 
168
                                                attribute.value = $('#'+attribute.inputID, $form).val();
 
169
 
 
170
                                                /*
 
171
                                                 * If the form is submited (non ajax) with errors, labels and input gets the class 'error'
 
172
                                                 */
 
173
                                                $('label,input',$form).each(function(){
 
174
                                                        $(this).removeClass('error');
 
175
                                                });
 
176
                                        });
 
177
                                        $('#'+settings.summaryID+' ul').html('');
 
178
                                        $('#'+settings.summaryID).hide();
 
179
                                        //.. set to initial focus on reset
 
180
                                        if(settings.focus != undefined && !window.location.hash)
 
181
                                                $(settings.focus).focus();
 
182
                                },1);
 
183
                        });
 
184
 
 
185
                        /*
 
186
                         * set to initial focus
 
187
                         */
 
188
                        if(settings.focus != undefined && !window.location.hash)
 
189
                                $(settings.focus).focus();
 
190
                });
 
191
        };
 
192
 
 
193
        /**
 
194
         * Returns the container element of the specified attribute.
 
195
         * @param attribute object the configuration for a particular attribute.
 
196
         * @param form the form jQuery object
 
197
         * @return jquery the jquery representation of the container
 
198
         */
 
199
        $.fn.yiiactiveform.getInputContainer = function(attribute, form) {
 
200
                if(attribute.inputContainer == undefined)
 
201
                        return $('#'+attribute.inputID, form).closest('div');
 
202
                else
 
203
                        return $(attribute.inputContainer).filter(':has("#'+attribute.inputID+'")');
 
204
        };
 
205
 
 
206
        /**
 
207
         * updates the error message and the input container for a particular attribute.
 
208
         * @param attribute object the configuration for a particular attribute.
 
209
         * @param messages array the json data obtained from the ajax validation request
 
210
         * @param form the form jQuery object
 
211
         * @return boolean whether there is a validation error for the specified attribute
 
212
         */
 
213
        $.fn.yiiactiveform.updateInput = function(attribute, messages, form) {
 
214
                attribute.status = 1;
 
215
                var hasError = messages!=null && $.isArray(messages[attribute.inputID]) && messages[attribute.inputID].length>0;
 
216
                var $error = $('#'+attribute.errorID, form);
 
217
                var $container = $.fn.yiiactiveform.getInputContainer(attribute, form);
 
218
                $container.removeClass(attribute.validatingCssClass)
 
219
                        .removeClass(attribute.errorCssClass)
 
220
                        .removeClass(attribute.successCssClass);
 
221
 
 
222
                if(hasError) {
 
223
                        $error.html(messages[attribute.inputID][0]);
 
224
                        $container.addClass(attribute.errorCssClass);
 
225
                }
 
226
                else {
 
227
                        $container.addClass(attribute.successCssClass);
 
228
                }
 
229
                if(!attribute.hideErrorMessage)
 
230
                        $error.toggle(hasError);
 
231
 
 
232
                attribute.value = $('#'+attribute.inputID, form).val();
 
233
 
 
234
                return hasError;
 
235
        };
 
236
 
 
237
        /**
 
238
         * updates the error summary, if any.
 
239
         * @param form jquery the jquery representation of the form
 
240
         * @param messages array the json data obtained from the ajax validation request
 
241
         */
 
242
        $.fn.yiiactiveform.updateSummary = function(form, messages) {
 
243
                var settings = $(form).data('settings');
 
244
                if (settings.summaryID == undefined)
 
245
                        return;
 
246
                var content = '';
 
247
                $.each(settings.attributes, function(i, attribute){
 
248
                        if(messages && $.isArray(messages[attribute.inputID])) {
 
249
                                $.each(messages[attribute.inputID],function(j,message){
 
250
                                        content = content + '<li>' + message + '</li>';
 
251
                                });
 
252
                        }
 
253
                });
 
254
                $('#'+settings.summaryID+' ul').html(content);
 
255
                $('#'+settings.summaryID).toggle(content!='');
 
256
        };
 
257
 
 
258
        /**
 
259
         * Performs the ajax validation request.
 
260
         * This method is invoked internally to trigger the ajax validation.
 
261
         * @param form jquery the jquery representation of the form
 
262
         * @param successCallback function the function to be invoked if the ajax request succeeds
 
263
         * @param errorCallback function the function to be invoked if the ajax request fails
 
264
         */
 
265
        $.fn.yiiactiveform.validate = function(form, successCallback, errorCallback) {
 
266
                var $form = $(form);
 
267
                var settings = $form.data('settings');
 
268
                $.ajax({
 
269
                        url : settings.validationUrl,
 
270
                        type : $form.attr('method'),
 
271
                        data : $form.serialize()+'&'+settings.ajaxVar+'='+$form.attr('id'),
 
272
                        dataType : 'json',
 
273
                        success : function(data) {
 
274
                                if (data != null && typeof data == 'object') {
 
275
                                        successCallback(data);
 
276
                                }
 
277
                        },
 
278
                        error : function() {
 
279
                                if (errorCallback!=undefined) {
 
280
                                        errorCallback();
 
281
                                }
 
282
                        }
 
283
                });
 
284
        };
 
285
 
 
286
        /**
 
287
         * Returns the configuration for the specified form.
 
288
         * The configuration contains all needed information to perform ajax-based validation.
 
289
         * @param form jquery the jquery representation of the form
 
290
         * @return object the configuration for the specified form.
 
291
         */
 
292
        $.fn.yiiactiveform.getSettings = function(form) {
 
293
                return $(form).data('settings');
 
294
        };
 
295
 
 
296
        $.fn.yiiactiveform.defaults = {
 
297
                ajaxVar: 'ajax',
 
298
                validationUrl: undefined,
 
299
                validationDelay: 200,
 
300
                validateOnSubmit : false,
 
301
                validateOnChange : true,
 
302
                validateOnType : false,
 
303
                hideErrorMessage : false,
 
304
                inputContainer : undefined,
 
305
                errorCssClass : 'error',
 
306
                successCssClass : 'success',
 
307
                validatingCssClass : 'validating',
 
308
                summaryID : undefined,
 
309
                timer: undefined,
 
310
                beforeValidateAttribute: undefined, // function(form, attribute) : boolean
 
311
                afterValidateAttribute: undefined,  // function(form, attribute, data, hasError)
 
312
                beforeValidate: undefined, // function(form) : boolean
 
313
                afterValidate: undefined,  // function(form, data, hasError) : boolean
 
314
                /**
 
315
                 * list of attributes to be validated. Each array element is of the following structure:
 
316
                 * {
 
317
                 *     model : 'ModelClass', // the model class name
 
318
                 *     name : 'name', // attribute name
 
319
                 *     inputID : 'input-tag-id',
 
320
                 *     errorID : 'error-tag-id',
 
321
                 *     value : undefined,
 
322
                 *     status : 0,  // 0: empty, not entered before,  1: validated, 2: pending validation, 3: validating
 
323
                 *     focus : undefined,  // jquery selector that indicates which element to receive input focus initially
 
324
                 *     validationDelay: 200,
 
325
                 *     validateOnChange : true,
 
326
                 *     validateOnType : false,
 
327
                 *     hideErrorMessage : false,
 
328
                 *     inputContainer : undefined,
 
329
                 *     errorCssClass : 'error',
 
330
                 *     successCssClass : 'success',
 
331
                 *     validatingCssClass : 'validating',
 
332
                 *     beforeValidateAttribute: undefined, // function(form, attribute) : boolean
 
333
                 *     afterValidateAttribute: undefined,  // function(form, attribute, data, hasError)
 
334
                 * }
 
335
                 */
 
336
                attributes : []
 
337
        };
 
338
 
 
339
})(jQuery);
 
 
b'\\ No newline at end of file'