4

I want to disable or make readOnly a field when user will update, i.e. username. When registered user update their information, they will see that username disable. I tried based on this answer but it does not work for me rather giving an error User has an invalid validation rule. The rule must specify attributes to be validated and the validator name. I wrote in the rules:

array('username', 'readOnly'=>true, 'on'=>'update'),

and in the form:

echo $form->textFieldRow($model,'username',array(
         'class'=>'span5',
         'maxlength'=>45,
         'readOnly'=>($model->scenario == 'update')? true : false
     ));

But do not understand why this shows error.

Community
  • 1
  • 1
StreetCoder
  • 9,871
  • 9
  • 44
  • 62

5 Answers5

7

That validation rule is meaningless.

The error message tells you that the validator name is missing:

 array('username', 'ValidatorNameGoesHere', 'readOnly'=>true, 'on'=>'update'),

But even if you fill in something for the validator name it still won't work because there is no validator in Yii that has a readOnly attribute; this role is played by the safe attribute.

Making certain fields read-only when updating in a secure manner (i.e. one that the user cannot override) means that you will have to look at the submitted data, determine independently if the data includes the PK of an existing model (which tells you if you are adding or updating) and set the model's scenario based on that. If you don't do this, your users can easily manipulate the HTTP requests sent to the server and bypass the read-only logic.

After the scenario is set you can easily enforce the read-only logic with a couple of rules:

 array('username', 'safe', 'except'=>'update'),
 array('username', 'unsafe', 'on'=>'update'),
Jon
  • 428,835
  • 81
  • 738
  • 806
  • 1
    Noteworthy: `safe` validator works only for mass assignment and will not deny updating model's attribute with individual assignment (`$model->someAttribute`). – Wirone Aug 31 '16 at 05:17
  • There is no [`unsafe` validator](http://www.yiiframework.com/doc-2.0/yii-validators-validator.html) - the 2nd line is redundant. – bakavic Jan 09 '18 at 03:09
  • @bakavic there is an `unsafe` validator in Yii 1 (e.g. see [here](http://www.yiiframework.com/wiki/533/safe-and-unsafe-model-validators-massive-assignments/)), which this question is about. Yii 2 had not even been released when I wrote this answer. =) – Jon Jan 11 '18 at 14:26
  • @Jon apologies - the syntax for rules are pretty similar between the 2 frameworks, so I assumed this question was about yii2. – bakavic Jan 13 '18 at 05:51
3

The HTML code you generate is not correct.

 This is incorrect: <input id='username' readonly='true'>
 This is correct: <input id='username' readonly='readonly'>

Therefore, change your code to

echo $form->textFieldRow($model,'username',array(
         'class'=>'span5',
         'maxlength'=>45,
         'readOnly'=>($model->scenario == 'update')? "readonly" : ""
     ));

References : http://www.w3.org/TR/html-markup/input.text.html#input.text.attrs.readonly

References : What is the correct readonly attribute syntax for input text elements?

Community
  • 1
  • 1
crafter
  • 6,246
  • 1
  • 34
  • 46
1

This way is even better!

echo $form->textFieldRow($model,'username',array(
     'class'=>'span5',
     'maxlength'=>45,
     'readOnly'=>($model->scenario == 'update')? "readonly" : false
 ));
0

We can use below code since it will work on create and update both:

<?php echo $form->textField($model,'promo_code', ($model->scenario == 'update') ? array('size'=>60,'maxlength'=>1000,   'readOnly'=>'readOnly') :array('size'=>60,'maxlength'=>1000)); ?>
Sud
  • 135
  • 2
  • 12
0
<?PHP echo $form->textFieldRow($model,'username', ($model->isNewRecord)?array('class' => 'form-control','span'=>5,'maxlength'=>255):array('class' => 'form-control','span'=>5,'maxlength'=>255,'readOnly'=>'readOnly'));?>