3

I Posted one question yesterday regarding custom validation for radio button Textfield Mandatory On Radio Button. I got answer. But, that was not exact answer. But, it solved one problem of mine.

Actually, I've 2 radio button.

  • Individual
  • Firm

When, Radio Button having "Individual" value is selected, CompanyName textbox should not be mandatory. But, when Radio Button having "Firm" value is selected, CompanyName textbox should be mandatory.

Now what happening is, When i select radio button 'Firm' and not filling any value for CompanyName textbox, data is not inserting in database table. FINE. Which is OK. But, Error message is not displaying in form. Error message should be displayed as CompanyName Textbox is mandatory after selecting Radio Button Firm.

I'm not getting where i'm doing mistake. Here is my View, Controller And Model Code. Please Help me.

register.php (VIEW)

<?php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use yii\captcha\Captcha;
use yii\bootstrap\Modal;
use yii\helpers\Url;
?>

<?php $form = ActiveForm::begin(['id' => 'register-form']); ?>
    .
    .
    .
    <?= $form->field($model, 'AdminType')
            ->radioList(array('Individual'=>'An Individual', 'Firm'=>'Firm/Company'))
            ->label('Are You')?>
    <?= $form->field($model, 'CompanyName')->textInput()->label('Company Name')->error() ?>
    .
    .
<?php ActiveForm::end(); ?>

SiteController.php (CONTROLLER)

<?php

namespace app\controllers;

use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\swiftmailer\Mailer;
use app\models\RegisterForm;

public function actionRegister()
{
    // Register Model
    $model = new RegisterForm();
    if ($model->load(Yii::$app->request->post())) 
    {
        $post = Yii::$app->request->post('RegisterForm');
        if ($model->validate())
        {

        }
        else
        {
            // HERE YOU CAN PRINT THE ERRORS OF MODEL
            echo "<pre>";
            print_r($model->getErrors());
            echo "</pre>";
        }
        return $this->refresh();
    }

}

RegisterForm.php (MODEL)

<?php

namespace app\models;

use Yii;
use yii\base\Model;
use kartik\password\StrengthValidator;


class RegisterForm extends Model
{
    public $fname;
    public $lname;
    public $email;
    public $password;
    public $confirmPassword;
    public $AdminType;
    public $CompanyName;
    public $verifyCode;

    public function rules()
    {
        return [
                [['fname','lname', 'email', 'password','confirmPassword','verifyCode','AdminType'], 'required'],
                ['email', 'email'],
            ['confirmPassword', 'compare', 'compareAttribute' => 'password'], 
                ['verifyCode', 'captcha'],

        //add rule that uses the validator function
                ['AdminType','radioValidator'],
        ];
    }

    //implement the validator
    public function radioValidator($attribute)
    {
        if($this->$attribute === 'Firm')
            return $this->addError('CompanyName', 'Company Name cannot be blank');
    }
}
Community
  • 1
  • 1
Nana Partykar
  • 10,556
  • 10
  • 48
  • 77

5 Answers5

1

You should to add 'enableAjaxValidation' => true in ActiveForm.

After do this your code should be,

controller

public function actionRegister()
{
    $model = new RegisterForm();
    if(Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
      \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
      return \yii\widgets\ActiveForm::validate($model);
    }

    if ($model->load(Yii::$app->request->post())) 
    {
    }
    else
    {
        // HERE YOU CAN PRINT THE ERRORS OF MODEL
        echo "<pre>";
        print_r($model->getErrors());
        echo "</pre>";
    }
    return $this->refresh();
}

View

<?php $form = ActiveForm::begin([
           'id' => 'register-form',
           'enableAjaxValidation' => true,
]); ?>
    .
    .
    .
    <?= $form->field($model, 'AdminType')
            ->radioList(array('Individual'=>'An Individual', 'Firm'=>'Firm/Company'))
            ->label('Are You')?>
    <?= $form->field($model, 'CompanyName')->textInput()->label('Company Name')->error() ?>
    .
    .
<?php ActiveForm::end(); ?>

It may help you.

GAMITG
  • 3,810
  • 7
  • 32
  • 51
  • Ok. Let Me Check Mr @gamitg. – Nana Partykar Oct 06 '15 at 12:38
  • After editing my code what you said Mr @gamitg. Now, form is not getting submitted. Means, now submit button is acting as normal button. Not, submitting any thing. – Nana Partykar Oct 06 '15 at 12:47
  • see error in firebug's console. what is error occur? – GAMITG Oct 06 '15 at 12:49
  • Error is showing now after selecting FIRM. But, captcha showing "The verification code is incorrect.". And, i've not touched any thing after that. And, one more thing, form is not getting submitted even after radio button INDIVIDUAL being selected. I think because of captcha. – Nana Partykar Oct 06 '15 at 13:22
  • I think you are close to answer Mr @gamitg. Yours working but now captcha not working because of that. – Nana Partykar Oct 06 '15 at 13:29
  • NEVER use captcha with enableAjaxValidation = true, because if you have ajax validation enabled it does a post to the controller and validates it. If you have e.g. multiple input fields and do a ajax post on every blur event then you would create a new "captcha" on the controller side after the testLimit is reached (which is default 3) so after 3 ajax requests you will have another captcha on the server side marked as valid and therefore your submit will always fail! – BHoft Oct 06 '15 at 14:32
  • Source: `Note that once CAPTCHA validation succeeds, a new CAPTCHA will be generated automatically. As a result, CAPTCHA validation should not be used in AJAX validation mode because it may fail the validation even if a user enters the same code as shown in the CAPTCHA image which is actually different from the latest CAPTCHA code.` http://www.yiiframework.com/doc-2.0/yii-captcha-captchavalidator.html – BHoft Oct 06 '15 at 14:33
  • Then, how to disable ajaxValidation only for captcha Mr @BHoft ? – Nana Partykar Oct 06 '15 at 15:04
  • see my answer (because code has to be added which is not possible in the comments) – BHoft Oct 07 '15 at 07:43
1

Atlast, i got my answer

     //company_name
      ['company_name', 'required', 'when' => function($model){
        return ($model->user_type == 'Firm' ? true : false);
      }, 'whenClient' => "function (attribute, value) {
          return $('input[type=\"radio\"][name=\"Users[user_type]\"]:checked').val() == 'Firm';
      }"],
Nana Partykar
  • 10,556
  • 10
  • 48
  • 77
0

If you call error without options you supress error output

ActiveField error method

yii\widgets\ActiveField

public function error($options = [])
{
    if ($options === false) {
        $this->parts['{error}'] = '';
        return $this;
    }
    $options = array_merge($this->errorOptions, $options);
    $this->parts['{error}'] = Html::error($this->model, $this->attribute, $options);

    return $this;
}

Your have to remove call error method into VIEW

<?= $form->field($model, 'CompanyName')->label('Company Name')->textInput() ?>
Sergey
  • 5,208
  • 25
  • 36
0

@Nana Partykar

As you asked how the ajax validation can be disabled for the captcha i tried this way. But i am not sure if this is the correct way.

I have set to the the form with this settings

'enableAjaxValidation' => true,
'enableClientValidation' => false,
'validateOnSubmit' => false,

and changed the validation on the action to this (i removed my captcha in my case 'verifyCode' from the attributes which should be validated.

if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
        Yii::$app->response->format = 'json';
        $validateAttributes = $model->activeAttributes();
        $key = array_search('verifyCode', $validateAttributes);
        if ($key!==false) {
            array_splice($validateAttributes, $key, 1);
        }
        return \yii\widgets\ActiveForm::validate($model, $validateAttributes);
}
BHoft
  • 1,663
  • 11
  • 18
0

Actually, your action method is incorrect. When you call refresh(), you basically reload the page. If the model has not been updated in the database, you will see nothing special, and no errors since you reload a fresh model.

This code will display the error as usual in your view :

   /**
     * @return \yii\web\Response
     */
    public function actionRegister()
    {
        // Register Model
        $model = new RegisterForm();
        if ($model->load(Yii::$app->request->post()))
        {
            $post = Yii::$app->request->post('RegisterForm');
            if ($model->validate())
            {
                 // whatever
            }

//            return $this->refresh(); // do not refresh but...
        }

        // ... render the view with the current model, who's errors attribute is filled
        return $this->render('register', compact('model'));
    }

NB : also, you don't have to call errors() in your view, the ActiveFormField rendering method takes care of it for you :

<?= $form->field($model, 'CompanyName')->textInput()->label('Company Name') ?>

is enough

ChristopheBrun
  • 1,237
  • 7
  • 22