2
votes

I have form which contain address, country, district field. If address is not empty then country and district is required. If address is empty then country, district not required.

I define in table model rules method like this using conditional validation as document says

public function rules()
{
    return [
        [['username', 'password', 'email', 'tanggal_daftar','password_validate'], 'required'],
        [['customer_id','propinsi_id', 'kota_id', 'kecamatan_id', 'user_status_id','poin'], 'integer'],
        [['tanggal_daftar','mobile_token','fb_id','newsletter','agree','password_validate','old_password'], 'safe'],
        [['username', 'jenis_kelamin'], 'string', 'max' => 10],
        [['password'], 'string', 'max' => 70],
        [['identitas'], 'required', 'on' => 'login'],
        [['email','username'], 'unique','except' => 'login'],
        [['email'],'email'],
        [['nama', 'hobby', 'pekerjaan'], 'string', 'max' => 30],

        //address field 
        [['alamat'], 'string', 'max' => 200],

        //country field
        [['negara_id'], 'string', 'max' => 3],

        [['kode_pos'], 'string', 'max' => 6],
        [['hp'], 'string', 'max' => 18],
        [['is_agent'],'boolean'],
        [['profile_picture'],'string','max' => 100],
        [['password_validate'], 'compare', 'compareAttribute'=>'password', 'message'=>Yii::t('app', 'Password tidak sama')],
        [['agree'],'compare','operator' => '==','compareValue' => true,'message' => ''],

//country field     
[['country_id'], 'required', 'when' => function($model){
                return $model->address != null;
                .. 
                what about the code if address is empty then country not required??
 }],

My view

...
... 
.. address field ..
<?= $form->field($model, 'alamat')->textInput(['maxlength' => true,'class'=>'input_text'])->label('Address')?>

... country field drop down ..
<?= $form->field($model, 'negara_id')->dropDownList(ArrayHelper::map(TbNegara::find()->all(), 'negara_id', 'negara_name'),['prompt'=>'-- Pilih Negara --','id'=>'negara_id','class'=>'input_select'])->label('Country') ?>
...
...

If I test above code, whether address empty or not in my form then country field always required.

Am I doing wrong?

UPDATED

country is required when address is not null is working now.

so if I type in address field and press submit button it show required error, then if I type nothing in adress field and press submit button, it will process the submit.

Solution is

without 'enableAjaxValidation' => true, at begin form

and here is my table model rules for country field

[['negara_id'], 'required', 'when' => function($model){
                return $model->alamat != null;
            }, 'whenClient' => "function (attribute, value){
                return $('#tbcustomer-alamat').val() != '';
            }"],

now I have other similar problem when I implement this code

[['propinsi_id'], 'required', 'when' => function($model){
                //district required if country is set
                return $model->negara_id != null;
            }, 'whenClient' => "function (attribute, value){
                return $('#negara_id').val() != '';
            }"],

district is not required even country is set, it should required if country set.

so If I type in address and set country, and leave district blank and I press submit, it will process submit but resulting in district cann't be blank [ 'propinsi_id' => [ 0 => 'ID Propinsi cannot be blank.' ] ]

something like my validation work on server side but not in client side.

district loaded via ajax when country is set

here is view for district field

                <div class="form_grup leftside fl">
                    <div class="input_select">
                    <?php
                        if (isset($model->propinsi)){
                            echo $form->field($model, 'propinsi_id')->widget(DepDrop::classname(), [
                            'options'=>['id'=>'propinsi_id','class'=>'input_select'],
                            'data'=>[$model->propinsi_id=>$model->propinsi->propinsi_name],
                            'pluginOptions'=>[
                                'initialize' => true,
                                 //depends on country  
                                'depends'=>['negara_id'],
                                    'class'=>'input_select',
                                'placeholder'=>'-- Pilih Propinsi --',
                                'url'=>Url::to(['customer2/propinsi'])
                            ]
                        ]);
                        } else {
                            echo $form->field($model, 'propinsi_id')->widget(DepDrop::classname(), [
                                    'options'=>['id'=>'propinsi_id','class'=>'input_select'],
                                    'pluginOptions'=>[
                                            'initialize' => true,
                                            //depends on country  
                                            'depends'=>['negara_id'],
                                            'class'=>'input_select',
                                            'placeholder'=>'-- Pilih Propinsi --',
                                            'url'=>Url::to(['customer2/propinsi'])
                                    ]
                                    ]);
                        }
                    ?>
 <!--                       <i class="fa fa-angle-down"></i> -->
                    </div>
                </div>

what am I doing wrong for district field client side validation?

1
show all model rules. - Insane Skull
@InsaneSkull done. :D - Dark Cyber
so, you want required validation for district field or not? Unclear to me. - Insane Skull
district is required if country is set, and no if country is not set. Just like country is required if address is not empty and no if address is empty. - Dark Cyber

1 Answers

2
votes

_form.php

<?php $form = ActiveForm::begin(['enableAjaxValidation' => true]); ?>

controller

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

model

[['country_id'], 'required', 'when' => function ($model) { return $model->address != null;}, 'enableClientValidation' => false ],
[['propinsi_id'], 'required', 'when' => function ($model) { return $model->country_id != null;}, 'enableClientValidation' => false ],