diff --git a/framework/assets.php b/framework/assets.php index 627b0fb..f17e576 100644 --- a/framework/assets.php +++ b/framework/assets.php @@ -14,11 +14,18 @@ return array( ), 'depends' => array('jquery'), ), + 'yii/validation' => array( + 'sourcePath' => __DIR__ . '/assets', + 'js' => array( + 'yii-validation.js', + ), + 'depends' => array('yii'), + ), 'yii/form' => array( 'sourcePath' => __DIR__ . '/assets', 'js' => array( 'yii-form.js', ), - 'depends' => array('yii'), + 'depends' => array('yii', 'yii/validation'), ), ); \ No newline at end of file diff --git a/framework/assets/yii-form.js b/framework/assets/yii-form.js index a0569e8..27b16fa 100644 --- a/framework/assets/yii-form.js +++ b/framework/assets/yii-form.js @@ -10,425 +10,6 @@ * @since 2.0 */ -;(function ($) { - /* - * returns the value of the CActiveForm input field - * performs additional checks to get proper values for checkbox / radiobutton / checkBoxList / radioButtonList - * @param o object the jQuery object of the input element - */ - var getAFValue = function (o) { - var type, - c = []; - if (!o.length) { - return undefined; - } - if (o[0].tagName.toLowerCase() === 'span') { - o.find(':checked').each(function () { - c.push(this.value); - }); - return c.join(','); - } - type = o.attr('type'); - if (type === 'checkbox' || type === 'radio') { - return o.filter(':checked').val(); - } else { - return o.val(); - } - }; +!function ($) { - /** - * yiiactiveform set function. - * @param options map settings for the active form plugin. Please see {@link CActiveForm::options} for availablel options. - */ - $.fn.yiiactiveform = function (options) { - return this.each(function () { - var settings = $.extend({}, $.fn.yiiactiveform.defaults, options || {}), - $form = $(this); - - if (settings.validationUrl === undefined) { - settings.validationUrl = $form.attr('action'); - } - $.each(settings.attributes, function (i) { - this.value = getAFValue($form.find('#' + this.inputID)); - settings.attributes[i] = $.extend({}, { - validationDelay: settings.validationDelay, - validateOnChange: settings.validateOnChange, - validateOnType: settings.validateOnType, - hideErrorMessage: settings.hideErrorMessage, - inputContainer: settings.inputContainer, - errorCssClass: settings.errorCssClass, - successCssClass: settings.successCssClass, - beforeValidateAttribute: settings.beforeValidateAttribute, - afterValidateAttribute: settings.afterValidateAttribute, - validatingCssClass: settings.validatingCssClass - }, this); - }); - $form.data('settings', settings); - - settings.submitting = false; // whether it is waiting for ajax submission result - var validate = function (attribute, forceValidate) { - if (forceValidate) { - attribute.status = 2; - } - $.each(settings.attributes, function () { - if (this.value !== getAFValue($form.find('#' + this.inputID))) { - this.status = 2; - forceValidate = true; - } - }); - if (!forceValidate) { - return; - } - - if (settings.timer !== undefined) { - clearTimeout(settings.timer); - } - settings.timer = setTimeout(function () { - if (settings.submitting || $form.is(':hidden')) { - return; - } - if (attribute.beforeValidateAttribute === undefined || attribute.beforeValidateAttribute($form, attribute)) { - $.each(settings.attributes, function () { - if (this.status === 2) { - this.status = 3; - $.fn.yiiactiveform.getInputContainer(this, $form).addClass(this.validatingCssClass); - } - }); - $.fn.yiiactiveform.validate($form, function (data) { - var hasError = false; - $.each(settings.attributes, function () { - if (this.status === 2 || this.status === 3) { - hasError = $.fn.yiiactiveform.updateInput(this, data, $form) || hasError; - } - }); - if (attribute.afterValidateAttribute !== undefined) { - attribute.afterValidateAttribute($form, attribute, data, hasError); - } - }); - } - }, attribute.validationDelay); - }; - - $.each(settings.attributes, function (i, attribute) { - if (this.validateOnChange) { - $form.find('#' + this.inputID).change(function () { - validate(attribute, false); - }).blur(function () { - if (attribute.status !== 2 && attribute.status !== 3) { - validate(attribute, !attribute.status); - } - }); - } - if (this.validateOnType) { - $form.find('#' + this.inputID).keyup(function () { - if (attribute.value !== getAFValue($(this))) { - validate(attribute, false); - } - }); - } - }); - - if (settings.validateOnSubmit) { - $form.on('mouseup keyup', ':submit', function () { - $form.data('submitObject', $(this)); - }); - var validated = false; - $form.submit(function () { - if (validated) { - validated = false; - return true; - } - if (settings.timer !== undefined) { - clearTimeout(settings.timer); - } - settings.submitting = true; - if (settings.beforeValidate === undefined || settings.beforeValidate($form)) { - $.fn.yiiactiveform.validate($form, function (data) { - var hasError = false; - $.each(settings.attributes, function () { - hasError = $.fn.yiiactiveform.updateInput(this, data, $form) || hasError; - }); - $.fn.yiiactiveform.updateSummary($form, data); - if (settings.afterValidate === undefined || settings.afterValidate($form, data, hasError)) { - if (!hasError) { - validated = true; - var $button = $form.data('submitObject') || $form.find(':submit:first'); - // TODO: if the submission is caused by "change" event, it will not work - if ($button.length) { - $button.click(); - } else { // no submit button in the form - $form.submit(); - } - return; - } - } - settings.submitting = false; - }); - } else { - settings.submitting = false; - } - return false; - }); - } - - /* - * In case of reseting the form we need to reset error messages - * NOTE1: $form.reset - does not exist - * NOTE2: $form.on('reset', ...) does not work - */ - $form.bind('reset', function () { - /* - * because we bind directly to a form reset event, not to a reset button (that could or could not exist), - * when this function is executed form elements values have not been reset yet, - * because of that we use the setTimeout - */ - setTimeout(function () { - $.each(settings.attributes, function () { - this.status = 0; - var $error = $form.find('#' + this.errorID), - $container = $.fn.yiiactiveform.getInputContainer(this, $form); - - $container.removeClass( - this.validatingCssClass + ' ' + - this.errorCssClass + ' ' + - this.successCssClass - ); - - $error.html('').hide(); - - /* - * without the setTimeout() we would get here the current entered value before the reset instead of the reseted value - */ - this.value = getAFValue($form.find('#' + this.inputID)); - }); - /* - * If the form is submited (non ajax) with errors, labels and input gets the class 'error' - */ - $form.find('label, :input').each(function () { - $(this).removeClass(settings.errorCss); - }); - $('#' + settings.summaryID).hide().find('ul').html(''); - //.. set to initial focus on reset - if (settings.focus !== undefined && !window.location.hash) { - $form.find(settings.focus).focus(); - } - }, 1); - }); - - /* - * set to initial focus - */ - if (settings.focus !== undefined && !window.location.hash) { - $form.find(settings.focus).focus(); - } - }); - }; - - /** - * Returns the container element of the specified attribute. - * @param attribute object the configuration for a particular attribute. - * @param form the form jQuery object - * @return jQuery the jQuery representation of the container - */ - $.fn.yiiactiveform.getInputContainer = function (attribute, form) { - if (attribute.inputContainer === undefined) { - return form.find('#' + attribute.inputID).closest('div'); - } else { - return form.find(attribute.inputContainer).filter(':has("#' + attribute.inputID + '")'); - } - }; - - /** - * updates the error message and the input container for a particular attribute. - * @param attribute object the configuration for a particular attribute. - * @param messages array the json data obtained from the ajax validation request - * @param form the form jQuery object - * @return boolean whether there is a validation error for the specified attribute - */ - $.fn.yiiactiveform.updateInput = function (attribute, messages, form) { - attribute.status = 1; - var $error, $container, - hasError = false, - $el = form.find('#' + attribute.inputID), - errorCss = form.data('settings').errorCss; - - if ($el.length) { - hasError = messages !== null && $.isArray(messages[attribute.id]) && messages[attribute.id].length > 0; - $error = form.find('#' + attribute.errorID); - $container = $.fn.yiiactiveform.getInputContainer(attribute, form); - - $container.removeClass( - attribute.validatingCssClass + ' ' + - attribute.errorCssClass + ' ' + - attribute.successCssClass - ); - $container.find('label, :input').each(function () { - $(this).removeClass(errorCss); - }); - - if (hasError) { - $error.html(messages[attribute.id][0]); - $container.addClass(attribute.errorCssClass); - } else if (attribute.enableAjaxValidation || attribute.clientValidation) { - $container.addClass(attribute.successCssClass); - } - if (!attribute.hideErrorMessage) { - $error.toggle(hasError); - } - - attribute.value = getAFValue($el); - } - return hasError; - }; - - /** - * updates the error summary, if any. - * @param form jquery the jquery representation of the form - * @param messages array the json data obtained from the ajax validation request - */ - $.fn.yiiactiveform.updateSummary = function (form, messages) { - var settings = $(form).data('settings'), - content = ''; - if (settings.summaryID === undefined) { - return; - } - if (messages) { - $.each(settings.attributes, function () { - if ($.isArray(messages[this.id])) { - $.each(messages[this.id], function (j, message) { - content = content + '