I've been confused with validation rules in Yii. I am sure when I give inputs there is no mistakes, corresponds to the rules given.
This is the validation rules in my model:
// public $user_phone; //updated: this isn't necessary
public $maxId;
...
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('user_phone', 'required', 'message'=>'{attribute} cannot be empty.<br />'),
array('user_phone', 'length', 'max'=>12),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('user_phone', 'safe', 'on'=>'search'),
);
}
This is when I call the validation function in the controller:
Updated: Added the assignment of the model's attributes
public function actionOrder(){
$order = new IptvOrder;
if(isset($_POST["IptvOrder"])) {
$order->attributes = $_POST["IptvOrder"]; // this is what I forgot
// some assignments to $id, $phone, $date, $time
if($order->validate()) {
$order->addOrder($id, $phone, $date, $time);
$this->redirect(array('order/orderConfirm'));
}
...blablabla...
}
And I put the validation error message in the view:
...blablabla...
<?php
echo $form->label($order,'Phone Number');
echo "<font color='red'> *</font>";
echo "<span style='font-size:10pt; color:#888888'><br/>Digunakan untuk konfirmasi pemesanan. Kerahasiaan kami jamin.</span><br/>";
echo $form->textField($order,'user_phone');
echo "<font color='red'>".$form->error($order, 'user_phone')."</font>";
?>
echo CHtml::submitButton('Pesan Sekarang', array('confirm' => 'Apakah anda yakin?
Silahkan cek pemesanan anda terlebih dahulu.'));
...blablabla...
// $form is CActiveForm, $order is the model
And it won't be redirected to order/orderConfirm although the textfield is not empty. Anybody can help? Thanks :)
Dump $order->attributes check the attribute user_phone has content or empty
Print out what your given error is from $order->getErrors()
About max length validation, because your input for that field is phone number, I exclude the possible of ASCII letter like below case
http://www.yiiframework.com/forum/index.php/topic/16338-validation-problem-with-length-on-textfields/
Updated: If your model name was Order as example, you should have to look like before you perform the validation
if(isset($_POST['Order']))
{
$order->attributes=$_POST['Order']; //<== Make sure you have set data for your order model before performing a validation
//validate part
...
}
Related
I am trying to apply some validation rules to my form data in CodeIgniter.
Expected Allowed output example like this: 22-some society, some street, city. 223399
What I Entered for check the validation: 42-some Society-3, some street. arcade ###*
This is my function which I use to validate the address.
function addr_line1($addr_line1) {
if (preg_match('/^[a-z0-9 .\-]+$/i',$addr_line1) !== FALSE)
return TRUE;
$this->form_validation->set_message('addr_line1', 'allow only space,comma,dot,numbers and alphabets.');
return FALSE;
}
Now I put all my validation in the config/form_validation.php
array(
'field' => 'addr_line1',
'label' => 'Address Line One',
'rules' => 'required|max_length[100]|callback_addr_line1'
),
After all this,I didn't get any validation error.
Am I not following the proper process?
or what should the regex code to validate this type of data?
change from
function addr_line1($addr_line1) {
if (preg_match('/^[a-z0-9 .\-]+$/i',$addr_line1) !== FALSE)
return TRUE;
$this->form_validation->set_message('addr_line1', 'allow only space,comma,dot,numbers and alphabets.');
return FALSE;
}
to
function addr_line1($addr_line1) {
if (preg_match('/[\'^£$%&*()}{##~?><>,|=_+¬-]/', $addr_line1))
{
$this->form_validation->set_message('addr_line1', 'allow only space,comma,dot,numbers and alphabets.');
}else{
return true;
}
}
Note:- you can replace £$%&*()}{##~?><>,|=_+¬- with your disallowed character
After Your suggestion and help, I finally found the correct Function.
function _validAddressCheck($addr_line1) {
if (preg_match('/^[0-9a-zA-Z .,-]+$/',$addr_line1)){
return TRUE;
} else {
$this->form_validation->set_message('_validAddressCheck', 'Only Allowed space, comma, dot, dash, numbers and alphabets.');
return FALSE;
}
}
I found that some rules which we have to follow if we are applying callback to the validation.
I have created config validation array at the application/config/form_validation.php
Put the callback function at the controller where I called that validations.
Find this link for creating a regex and test that. Link
<tr>
<td>
<label for="address">Address:</label></td><td>
<textarea name="address" placeholder="Write
something.."><?php echo set_value('address'); ?> </textarea>
</td>
<td>
<p class="err_msg">
<?php
echo form_error('address');
?>
</p>
</td>
in route page:-
$this->form_validation->set_rules('address','add','required|exact_length[18]',array('required'=>"Please Enter Address",'exact_length'=>"Please Enter At Least 10 Character"));
I have a field set as required in the model, yet I have seen users saving it as an empty string (ie. ''). When I tested it, I do receive the "Cannot be blank" message properly, so don't know how to prevent this in the future. Do I have to specify all scenarios in the rule (eg, 'insert', 'update')? By the way, I tried updating the field, and it doesn't let me save it empty (I even tries spaces).
These are the rules applied on the field (model):
public function rules()
{
return array(
array('field', 'required'),
array('field', 'length', 'max'=>4096),
array('field', 'safe', 'on'=>'search'),
);
}
For #RiggsFolly :) the controller action:
public function actionUpdate($id)
{
$model = Model::model()->findByPk($id);
$formData = Yii::app()->request->getPost('Model');
if ($formData)
{
$model->attributes = $formData;
$model->save();
}
$this->render('update',array(
'model'=>$model
));
}
... and the view:
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'form'
)); ?>
<?php echo $form->textArea($model,'text',array( 'rows'=>5 ')); ?>
<?php $this->endWidget(); ?>
Can you imagine any scenario this field could be saving an empty string in the database?
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
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.
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()],
}
There is a 'main.php' view that contains a form with email and name fields and a submit button. Eveyrthing works fine with action_index (the code is below), but I'm curious how to modify the code below so it validates if the email was entered correctly. It should not put values in the database if the email field is not valid. I hope it is possible to made using ->rule. Is it? If yes, then how where to add the validation? (I had no luck trying it in different ways).
public function action_index()
{
if ( !empty($_POST) ) {
$model = ORM::factory('tbl1'); // create
$model->values($_POST); // load values to model
if ($model->check()) {
$model->save(); // save the model
} else {
//show errors
}
}
$this->response->body(View::factory('main'));
}
Thank you.
Use rules function in your ORM model:
public function rules()
{
return array(
'email' => array(
array('email', array(':value')),
),
);
}
I have a drop down named "business_id".
<select name="business_id">
<option value="0">Select Business</option> More options...
</select>
Here comes the validation rule, user must select an option.
$this->form_validation->set_rules('business_id', 'Business', 'greater_than[0]');
Problem being the error message says: The Business field must contain a number greater than 0. Not very intuitive! I want it to say "You must select a business".
I tried:
$this->form_validation->set_message('Business', 'You must select a business');
But CI complete ignores this. Does anyone have a solution for this?
I had the same requirement for adding custom form validation error messages in codeigniter 2 (e.g. "You must agree to our Terms & Conditions"). Naturally it would be wrong to override the error messages for require and greater_than as it would erroneously produce messages for the rest of the form. I extended the CI_Form_validation class and have overridden the set_rules method to accept a new 'message' parameter:
<?php
class MY_Form_validation extends CI_Form_validation
{
private $_custom_field_errors = array();
public function _execute($row, $rules, $postdata = NULL, $cycles = 0)
{
// Execute the parent method from CI_Form_validation.
parent::_execute($row, $rules, $postdata, $cycles);
// Override any error messages for the current field.
if (isset($this->_error_array[$row['field']])
&& isset($this->_custom_field_errors[$row['field']]))
{
$message = str_replace(
'%s',
!empty($row['label']) ? $row['label'] : $row['field'],
$this->_custom_field_errors[$row['field']]);
$this->_error_array[$row['field']] = $message;
$this->_field_data[$row['field']]['error'] = $message;
}
}
public function set_rules($field, $label = '', $rules = '', $message = '')
{
$rules = parent::set_rules($field, $label, $rules);
if (!empty($message))
{
$this->_custom_field_errors[$field] = $message;
}
return $rules;
}
}
?>
With the above class you would produce your rule with a custom error message like so:
$this->form_validation->set_rules('business_id', 'Business', 'greater_than[0]', 'You must select a business');
You may also use '%s' in your custom message which will automatically fill in the label of fieldname.
If you'd like to customize the error messages that are displayed with each rule, you can find them in an array at:
/system/language/english/form_validation_lang.php
Try not setting the value attribute on the default select...
<select name="business_id">
<option value>Select Business</option> More options...
</select>
and then just using required for your form validation rule...
$this->form_validation->set_rules('business_id', 'Business', 'required');
I suppose you could try editing the way that you're trying to set the message also...
$this->form_validation->set_message('business_id', 'You must select a business');
instead of
$this->form_validation->set_message('Business', 'You must select a business');
I'm not entirely sure if that will do the trick though.
You should extend the Form_validation library as Anthony said.
For instance, I do something like this in a file called MY_Form_validation.php which should be put on /application/libraries
function has_selection($value, $params)
{
$CI =& get_instance();
$CI->form_validation->set_message('has_selection', 'The %s need to be selected.');
if ($value == -1) {
return false;
} else {
return true;
}
}
In your case, because your first option (Guidance option - Please select ...) has the value of 0, you may want to change the conditional statement from -1 to 0. Then, from now on, you could have this line to check selection value:
$this->form_validation->set_rules('business_id', 'Business', 'has_selection');
Hope this helps!
Here's a simple CI2 callback function that I used. I wanted something other than just 'required' as a default param of the validation. The documentation helps: http://codeigniter.com/user_guide/libraries/form_validation.html#callbacks
public function My_form() {
...Standard CI validation stuff...
$this->form_validation->set_rules('business_id', 'Business', 'callback_busid');
...
if ($this->form_validation->run() == FALSE) {
return false;
}
else {
...process the form...
$this->email->send();
}
} // Close My_form method
// Callback method
function busid($str) {
if ($str == '') {
$this->form_validation->set_message('business_id', 'Choose a business, Mang!');
return FALSE;
}
else {
return TRUE;
}
} // Close the callback method
For your case you could change the callback to check for if($str<0) - I'm assuming you've used numbers in your selection/dropdown menu.
If the callback returns false, the form is held and the error message is shown. Otherwise, it's passed and sent to the 'else' of the form method.
A little hack might not good for you but I have done this for a little change.
Example,
I want to change message 'The Email field must be a unique value'.
I have done this as
<?php
$error = form_error('email');
echo str_replace('field must be a unique value', 'is already in use.', $error);
// str_replace('string to search/compare', 'string to replace with', 'string to search in')
?>
If string found then it prints our custom message else it will display error message as it is like 'The Email field must be a valid email' etc...
for those of you working on CodeIgniter 3 you can do the following:
$this->form_validation->set_rules('business_id', 'Business', 'greater_than[0]', array(
'greater_than' => 'You must select a business',
));
And if you are using CodeIgniter 2, you will need to extend and override the CI_Form_validation class (https://ellislab.com/codeigniter/user-guide/general/creating_libraries.html for more info on how to do so) with the new CodeIgniter 3 CI_Form_validation class and use the function above.
The name of the rule is the last parameter.
Please try:
$this->form_validation->set_message('greater_than[0]', 'You must select a business');
More info:
https://ellislab.com/codeigniter/user-guide/libraries/form_validation.html#validationrules
I extended the form_validation library with a simple function that makes sure a drop down box does not have its default value selected. Hope this helps.
application/libraries/MY_Form_validation.php
<?php if (!defined('BASEPATH')) exit('No direct script access allowed.');
class MY_Form_validation extends CI_Form_validation {
function __construct()
{
parent::__construct();
$this->CI->lang->load('MY_form_validation');
}
/**
* Make sure a drop down field doesn't have its default value selected.
*
* #access public
* #param string
* #param field
* #return bool
* #author zechdc
*/
function require_dropdown($str, $string_to_compare)
{
return ($str == $string_to_compare) ? FALSE : TRUE;
}
}
application/language/english/MY_Form_validation_lang.php
$lang['require_dropdown'] = 'The %s field must have an item selected.';
How to Use:
1) Make your form drop down box:
<select name="business_id">
<option value="select">Select Business</option> More options...
</select>
2) Create Validation Rule. You might be able to set the value to 0 and use require_dropdown[0] but I've never tried that.
$this->form_validation->set_rules('business_id', 'Business', 'require_dropdown[select]');
3) Set your custom message: (Or skip this step and use the one in the language file.)
$this->form_validation->set_message('business_id', 'You must select a business');
Create Method username_check call back function
01.
public function username_check($str)
{
if ($str=="")
{
$this->form_validation->set_message('username_check', 'Merci d’indiquer le nombre d’adultes');
return FALSE;
}
else
{
return TRUE;
}
}
--
02. Then Put this Validation Code on your class
$this->form_validation->set_rules('number_adults', 'Label Name','Your Message',) 'callback_username_check');
This may help you