2015-09-11 7 views
3

У меня есть форму, созданную виджетами ActiveForm. Пользователь вводит почтовый индекс. В соответствующем контроллере я положить введенные данные в БД, например:Yii2, пользовательская проверка: clientValidateAttribute() не работает правильно

$company_profile_data->postal_code = $_POST['CompanyProfiles']['postal_code']; 
$company_profile_data->update(); 

я решил использовать отдельный валидатор для проверки почтового кода. Правила для этого атрибута в модели:

public function rules() { 
    return [ 
     //...some other rules... 
     ['postal_code', 'string', 'length' => [6,6]], 
     ['postal_code', PostalValidator::className()], //standalone validator 
    ]; 
} 

приложение/компоненты/валидаторов/PostalValidator код класса:

namespace app\components\validators; 

use yii\validators\Validator; 
use app\models\CompanyProfiles; 
use app\models\Users; 

class PostalValidator extends Validator { 
    public function init() { 
     parent::init(); 
    } 

    public function validateAttribute($model, $attribute) { 

    if (!preg_match('/^[0-9]{2}-[0-9]{3}$/', $model->$attribute)) 
     $model->addError($attribute, 'Wrong postal code format.'); 
    } 

public function clientValidateAttribute($model, $attribute, $view) { //want js-validation too 
    $message = 'Invalid status input.'; 
    return <<<JS 
if (!/^[0-9]{2}-[0-9]{3}$/.test("{$model->$attribute}")) { 
    messages.push("$message"); 
} 
JS; 
    } 
} 

Таким образом, пример правильного кода 00-202.

Когда я (в роли пользователя) введите неверное значение, страница перезагружается и я вижу Wrong postal code format. сообщений, хотя я пересмотрел clientValidateAttribute метод и написал JS-validation, который, как я предложил, не позволит странице перезагружать. Затем я снова нажимаю кнопку «Отправить»: эта страница времени не перезагружается, и я вижу сообщение Invalid status input. (поэтому, триггеры запуска JS второго нажатия). Но после ввода правильного кода я до сих пор вижу сообщение Invalid status input. и ничего не происходит.

Итак, что случилось с моим методом clientValidateAttribute()? validateAttribute() отлично работает.

UPDATE Отрывок из контроллера

public function actionProfile(){ //can't use massive assignment here, cause info from 2 (not 1) user models is needed 
    if (\Yii::$app->user->isGuest) { 
     return $this->redirect('/site/index/'); 
    } 
    $is_user_admin = Users::findOne(['is_admin' => 1]); 
    if ($is_user_admin->id == \Yii::$app->user->id) 
     return $this->redirect('/admin/login/'); 

    $is_user_blocked = Users::find()->where(['is_blocked' => 1, 'id' => \Yii::$app->user->id])->one(); 
    if($is_user_blocked) 
     return $this->actionLogout(); 

//3 model instances to retrieve data from users && company_profiles && logo 
    $user_data = Users::find()->where(['id'=>\Yii::$app->user->id])->one(); 
    $user_data->scenario = 'update'; 

    $company_profile_data = CompanyProfiles::find()->where(['user_id'=>Yii::$app->user->id])->one(); 
    $logo = LogoData::findOne(['user_id' => \Yii::$app->user->id]); 
    $logo_name = $logo->logo_name; //will be NULL, if user have never uploaded logo. In this case placeholder will be used 

    $upload_logo = new UploadLogo(); 
    if (Yii::$app->request->isPost) { 

     $upload_logo->imageFile = UploadedFile::getInstance($upload_logo, 'imageFile'); 

     if ($upload_logo->imageFile) { //1st part ($logo_data->imageFile) - whether user have uploaded logo 
      $logo_file_name = md5($user_data->id); 
      $is_uploaded = $upload_logo->upload($logo_file_name); 
      if ($is_uploaded) { //this cond is needed, cause validation for image fails (?) 
       //create record in 'logo_data' tbl, deleting previous 
       if ($logo_name) { 
        $logo->delete(); 
       } else { //if upload logo first time, set val to $logo_name. Otherwise NULL val will pass to 'profile' view, and user wont see his new logo at once 
        $logo_name = $logo_file_name.'.'.$upload_logo->imageFile->extension; 
       } 
       $logo_data = new LogoData; 
       $logo_data->user_id = \Yii::$app->user->id; 
       $logo_data->logo_name = $logo_name; 
       $logo_data->save(); 
      } 
     } 
    } 

    if (isset($_POST['CompanyProfiles'])){ 

     $company_profile_data->firm_data = $_POST['CompanyProfiles']['firm_data']; 
     $company_profile_data->company_name = $_POST['CompanyProfiles']['company_name']; 
     $company_profile_data->regon = $_POST['CompanyProfiles']['regon']; 
     $company_profile_data->pesel = $_POST['CompanyProfiles']['pesel']; 
     $company_profile_data->postal_code = $_POST['CompanyProfiles']['postal_code']; 
     $company_profile_data->nip = $_POST['CompanyProfiles']['nip']; 
     $company_profile_data->country = $_POST['CompanyProfiles']['country']; 
     $company_profile_data->city = $_POST['CompanyProfiles']['city']; 
     $company_profile_data->address = $_POST['CompanyProfiles']['address']; 
     $company_profile_data->telephone_num = $_POST['CompanyProfiles']['telephone_num']; 
     $company_profile_data->email = $_POST['CompanyProfiles']['email'];   
     $company_profile_data->update(); 
    } 

    if (isset($_POST['personal-data-button'])) { 
     $user_data->username = $_POST['Users']['username']; 
     $user_data->password_repeat = $user_data->password = md5($_POST['Users']['password']); 
     $user_data->update(); 
    } 
    return $this->render('profile', ['user_data' => $user_data, 'company_profile_data' => $company_profile_data, 'upload_logo' => $upload_logo, 'logo_name' => $logo_name]); 
} 
+0

Вы используете функцию загрузки? Я полагаю, что загрузка вызвана только после отправки формы. –

+0

Нет, я не использую его. Я делаю это (как я писал выше): '$ company_profile_data-> postal_code = $ _POST ['CompanyProfiles'] ['postal_code']'. Итак, я не использую массовое назначение. Вы видите, что другие атрибуты корректно проверяются (перед отправкой) без каких-либо 'load()'. Но не в случае автономной проверки. –

+0

I предмет проблема в контроллере. Вы можете обновить сообщение с помощью кода contoller? –

ответ

2

Моя неточность была в clientValidateAttribute() метод. Вместо $model->$attribute в фрагменте кода:

if (!/^[0-9]{2}-[0-9]{3}$/.test("{$model->$attribute}")) { 

... Я должен был использовать предопределенный JS-вар value, вызывают эти изменения Var с изменением введенного значения. Итак, мой новый код:

public function clientValidateAttribute($model, $attribute, $view) { 
    return <<<JS 
if (!/^[0-9]{2}-[0-9]{3}$/.test(value)) { 
    messages.push("Wrong postal code format."); 
} 
JS; 
} 
0

Модель не не загружает правила и поведение, пока not called any function от модели. Когда вы звоните $company_profile_data->update(); номер телефона update и validate функции.

Попробуйте добавить после $company_profile_data = CompanyProfiles::find() этот код:

$company_profile_data->validate(); 

Или просто использовать load функцию. Я думаю, это поможет.

+1

В обоих случаях успех невозможен. Но, я думаю, я решил проблему. Спасибо за участие. :) –

 Смежные вопросы

  • Нет связанных вопросов^_^