Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set validation message for field having ajax validation in scenarios? - Yii2

I'm using one model file for 2 forms. One for SIGNUP & Other for Adding members.

I didn't set any scenario for SIGNUP form. But, scenario for Adding members form is set.

Model

public function rules() {
  return [

    //Add Members
    ['first_name', 'required','message'=>'Please enter first name.','on'=>'addteammembersidebar'],
    ['email', 'required','message'=>'Please enter email address.','on'=>'addteammembersidebar'],
    ['mobile','required','message'=>'Please enter mobile number.','on'=>'addteammembersidebar'],

    //Common
    ['first_name', 'required','message'=>'Please enter your first name.'],
    ['email', 'required','message'=>'Please enter your email address.'],
    ['mobile','required','message'=>'Please enter your mobile number.'],

  ];
}

View

Here, I set scenario like $modelTeamMembers->scenario = 'addteammembersidebar';.

<?php foreach ($modelsTeamMembers as $indexMember => $modelTeamMembers): 
  $modelTeamMembers->scenario = 'addteammembersidebar';
  ?>
  <tr class="house-item">
    <td class="vcenter">
      <?php
      // necessary for update action.
      if (! $modelTeamMembers->isNewRecord) {
        echo Html::activeHiddenInput($modelTeamMembers, "[{$indexMember}]id");
      }
      ?>

      <?php 
      $modelTeamMembers->first_name = $first_name;
      echo $form->field($modelTeamMembers, "[{$indexMember}]first_name")->label(false); 
      ?>
    </td>
    <td>
      <?php
      $modelTeamMembers->last_name = $last_name;
      echo $form->field($modelTeamMembers, "[{$indexMember}]last_name")->label(false); 
      ?>
    </td>
    <td>
      <?php
      $modelTeamMembers->email = $email;
      echo $form->field($modelTeamMembers, "[{$indexMember}]email",['enableAjaxValidation' => true])->label(false); 
      ?>
    </td>
    <td>
      <?php
      $modelTeamMembers->mobile = $mobile_number;
      echo $form->field($modelTeamMembers, "[{$indexMember}]mobile",
          ['inputOptions' => ['class' => 'form-control', 'maxlength'=>"10"]])->label(false);
      ?>
    </td>
  </tr>

<?php endforeach; ?>

All validation error message working except for email field. If, I remove 'enableAjaxValidation' => true from field, it works. But, for me 'enableAjaxValidation' => true is required.

Image

enter image description here

As in image, it is clearly visible that error message coming "Please enter your email address." Which should be "Please enter email address.". Only email field validation error message not coming correct. Except all are fine.

How to set validation message for email field for scenarios? Any help/hint/suggestions are appreciable.

like image 525
Nana Partykar Avatar asked Dec 14 '22 04:12

Nana Partykar


1 Answers

May I know why exactly do you need to use email validation with AjaxValidation in here? For this type it is enough to write without it since AjaxValidation is more suitable when you want to search and retrieve data from database or other models, not model itself.

However, if you feel you need AjaxValidation, you must set up a few different things since you're current code won't work.


Setting up AjaxValidation in View:

// Set to: index.php?r=profile/email-validation
$form = ActiveForm::begin(['validationUrl' => ['profile/email-validation']]);

// This is set correctly (no changes are needed comparing to your attempt)
echo $form->field($modelTeamMembers, "[{$indexMember}]email", ['enableAjaxValidation' => true])->label(false);

Why this needed? You have set AjaxValidation to be active, but you haven't set URL that this Ajax will work on. It is set in ActiveForm::begin() in most cases.


Setting up AjaxValidation in Controller (required):

// Method that renders your view file
public function actionSomethingThatRendersView()
{
    // Code here
    $user->scenario = 'addteammembersidebar';                 // Custom scenario name
    return $this->render(/* the remaining code goes here */);
}

// This is the method that Ajax will send request to ($_POST[])
public function actionEmailValidation()
{
    $post = Yii::$app->request->post();
    if (!empty($post))
    {
        Yii::$app->response->format = Response::FORMAT_JSON;  // Must be in JSON format
        $profile = new User();                                // Edit your class name in here
        // Custom scenario (must be the same as above otherwise you might get unexpected response)
        $profile->scenario = 'addteammembersidebar';
        $profile->load($post);

        return ActiveForm::validate($profile);
    }
}

Why this needed? Ajax will send a request but request without any actions will do nothing. This will "create new" object with same rules and attributes and will attempt to validate with new set of data. For rendering method, $obj->scenario must also be set because otherwise it would use default scenario.


There are no changes to Model. Everything should remain the same as in your example.

In case you want to make it unique email, you have to make changes to Model as well:

public function rules()
{
    // ...
    ['email', 'unique', 'message' => 'Email must be unique'],
    // If your attribute is not in the same table as defined in class, then:
    ['email', 'unique', 'message' => 'Email must be unique', 'targetClass' => User2::className()],
}
like image 188
Gytis TG Avatar answered Dec 25 '22 11:12

Gytis TG