Yii 1.1 Decimalcommanumbervalidator

This class extends CNumberValidator so you can use all the options available there.

Additional option is replaceComma (default true) - this indicates whether the comma in attribute value should be replaced with dot.

Thanks to this you can validate your numeric fields with decimal comma (15,45 instead of 15.45) without filtering them first.

Remember that if replaceComma is set to false the attribute will not be changed so you have to prepare your database column properly.

Usage:

Import this class to your Yii application and use just like CNumberValidator. For example:




    public function rules()

    {

        return array(

            array('price', 'DecimalCommaNumberValidator', 'min' => 0),

        );

    }






<?php


/**

 * DecimalCommaNumberValidator class file.

 * @copyright 2014 Bizley

 * 

 * DecimalCommaNumberValidator allows to validate numeric 

 * fields with decimal comma as well as decimal dot mark.

 * All options available for CNumberValidator are 

 * available here as well with additional replaceComma.

 */

class DecimalCommaNumberValidator extends CNumberValidator

{

    /**

     * @var boolean whether the decimal comma in attribute 

     * value should be replaced with decimal dot. Defaults to true.

     */

    public $replaceComma = true;


    /**

     * Validates the attribute of the object.

     * If there is any error, the error message is added to the object.

     * @see CNumberValidator::validateAttribute

     * @param CModel $object the object being validated

     * @param string $attribute the attribute being validated

     */

    protected function validateAttribute($object, $attribute)

    {

        $value = $object->$attribute;

        

        if (is_string($value)) {

            $value = str_replace(',', '.', $value);

        }

        

        if ($this->allowEmpty && $this->isEmpty($value))

            return;

        if (!is_numeric($value)) {

            // https://github.com/yiisoft/yii/issues/1955

            // https://github.com/yiisoft/yii/issues/1669

            $message = $this->message !== null ? $this->message : Yii::t('yii', '{attribute} must be a number.');

            $this->addError($object, $attribute, $message);

            return;

        }

        

        if ($this->replaceComma) {

            $object->$attribute = $value;

        }

        

        if ($this->integerOnly) {

            if (!preg_match($this->integerPattern, "$value")) {

                $message = $this->message !== null ? $this->message : Yii::t('yii', '{attribute} must be an integer.');

                $this->addError($object, $attribute, $message);

            }

        }

        else {

            if (!preg_match($this->numberPattern, "$value")) {

                $message = $this->message !== null ? $this->message : Yii::t('yii', '{attribute} must be a number.');

                $this->addError($object, $attribute, $message);

            }

        }

        if ($this->min !== null && $value < $this->min) {

            $message = $this->tooSmall !== null ? $this->tooSmall : Yii::t('yii', '{attribute} is too small (minimum is {min}).');

            $this->addError($object, $attribute, $message, array('{min}' => $this->min));

        }

        if ($this->max !== null && $value > $this->max) {

            $message = $this->tooBig !== null ? $this->tooBig : Yii::t('yii', '{attribute} is too big (maximum is {max}).');

            $this->addError($object, $attribute, $message, array('{max}' => $this->max));

        }

    }


    /**

     * Returns the JavaScript needed for performing client-side validation.

     * @see CNumberValidator::clientValidateAttribute

     * @param CModel $object the data object being validated

     * @param string $attribute the name of the attribute to be validated.

     * @return string the client-side validation script.

     * @see CActiveForm::enableClientValidation

     * @since 1.1.7

     */

    public function clientValidateAttribute($object, $attribute)

    {

        $label = $object->getAttributeLabel($attribute);


        if (($message = $this->message) === null)

            $message = $this->integerOnly ? Yii::t('yii', '{attribute} must be an integer.') : Yii::t('yii', '{attribute} must be a number.');

        $message = strtr($message, array(

            '{attribute}' => $label,

        ));


        if (($tooBig = $this->tooBig) === null)

            $tooBig = Yii::t('yii', '{attribute} is too big (maximum is {max}).');

        $tooBig = strtr($tooBig, array(

            '{attribute}' => $label,

            '{max}' => $this->max,

        ));


        if (($tooSmall = $this->tooSmall) === null)

            $tooSmall = Yii::t('yii', '{attribute} is too small (minimum is {min}).');

        $tooSmall = strtr($tooSmall, array(

            '{attribute}' => $label,

            '{min}' => $this->min,

        ));


        $js = "value = value.replace(/,/g, '.');";

        

        $pattern = $this->integerOnly ? $this->integerPattern : $this->numberPattern;

        $js .= "

if(!value.match($pattern)) {

	messages.push(" . CJSON::encode($message) . ");

}

";

        if ($this->min !== null) {

            $js.="

if(value<{$this->min}) {

	messages.push(" . CJSON::encode($tooSmall) . ");

}

";

        }

        if ($this->max !== null) {

            $js.="

if(value>{$this->max}) {

	messages.push(" . CJSON::encode($tooBig) . ");

}

";

        }


        if ($this->allowEmpty) {

            $js = "

if(jQuery.trim(value)!='') {

	$js

}

";

        }


        return $js;

    }


}