I'm trying to make a validation for 2 field that must have a different value. I only know how to set the rules for validate matching value.
$this->form_validation->set_rules('book1','Book1','required|matches[book2]');
$this->form_validation->set_rules('book2','Book2','required|matches[book1]');
if I input book1=novel, and book2=novel, the code above will return TRUE.
How can I validate 2 field where the value of each field is not matching each other? So if I input book1=novel and book2=comic, it will return TRUE.
You should use callback_ method for custom validation, CI form validation library does not provide notMatch type validation rule, see below sample code.
$this->form_validation->set_rules('book1','Book1','required');
$this->form_validation->set_rules('book2','Book2','required|callback__notMatch[book1]');
AND place method in controller class
function _notMatch($book2Value, $book1FieldName){
if($book2Value != $this->input->post($book1FieldName){
$this->form_validation->set_message('_notMatch', 'book1 and book2 values are not matching');
return false;
}
return true;
}
In codeigniter 3 you can use the differs[] set rule, to enforce that field values don't match.
$this->form_validation->set_rules('book1', 'Book 1', 'required|differs[book2]');
$this->form_validation->set_rules('book2', 'Book 2', 'required|differs[book1]');
This means you don't need to create an unnecessary callback. However, for older versions you will.
See the documentations for more: Codeigniter 3 Documentation
You can use differs like so:
$this->form_validation->set_rules('password', 'current password', 'max_length[25]|min_length[5]|required');
$this->form_validation->set_rules('new_password', 'new password', 'max_length[25]|min_length[5]|required|differs[password]');
$this->form_validation->set_rules('confirm_password', 'confirm password', 'required|max_length[25]|min_length[5]|matches[new_password]');
Related
I'm writing something where if you select a certain button or dropdown I want to change the rules of a certain field. Basically the logic is, check a button or select an ID from a select and you don't need to populate the address fields. I've been trying to do thing within the form_validation rather than in he controller where I could actually do something like this
if(isset($_POST['checkbox'])){
//check rules
}
So I've done this:
public function check_address($str,$prefix=null){
$this->set_message('check_address','Please select an address or fill out a new one');
//var_dump($this->_field_data);exit;
$remove=array('address_line1','address_line2','address_line3','city','postcode');
if($prefix!==null){
foreach($remove as &$r){
$r=$prefix.'_'.$r;
}
}
unset($r);
foreach($this->_field_data as $key=>$f){
if(in_array($key,$remove)){
unset($this->_field_data[$key]);
}
}
}
This works the way I want it to but I think I've interfered with codeiginter's Form_Validation class as it throws an error stating the required indexes in my array are not set.
The error message
A PHP Error was encountered
Severity: Notice
Message: Undefined index: billing_address_line1
Filename: libraries/Form_validation.php
Line Number: 481
I'm not really too sure how I can achieve what I want to do without interfering with what codeigniter needs? Is there another array I need to remove so that the key isn't sort after?
I've also done this now
foreach($this->_field_data as $key=>&$f){
if(in_array($key,$remove)){
//unset($this->_field_data[$key]);
//str_replace('/required\|/','',$f['rules']);
//str_replace('/required/','',$f['rules']);
foreach($f['rules']as$r=>$val){
$val=strtolower($val);
if($val=='required')unset($f['rules'][$r]);
}
var_dump($f);
}
}
unset($f);
This now does what is required by removing the rule required but the required function I think must've already of run?
Array of rules
$this->con['validation']['checkout']=array(
array('field'=>'address_line1','label'=>'Address line 1','rules'=>'required|min_length[3]|max_length[200]|check_basket'),
array('field'=>'address_line2','label'=>'Address line 2','rules'=>'min_length[3]|max_length[200]'),
array('field'=>'address_line3','label'=>'Address line 3','rules'=>'min_length[3]|max_length[200]'),
array('field'=>'city','label'=>'Town/City','rules'=>'required|min_length[3]|max_length[50]'),
array('field'=>'postcode','label'=>'Town/City','rules'=>'required|min_length[3]|max_length[9]|valid_postcode'),
array('field'=>'shipping_addressID','label'=>'Address','rules'=>'check_address[]'),
array('field'=>'billing_address_line1','label'=>'Billing address line 1','rules'=>'required|min_length[3]|max_length[200]'),
array('field'=>'billing_address_line2','label'=>'Billing address line 2','rules'=>'min_length[3]|max_length[200]'),
array('field'=>'billing_address_line3','label'=>'Billing address line 3','rules'=>'min_length[3]|max_length[200]'),
array('field'=>'billing_city','label'=>'Town/City','rules'=>'required|min_length[3]|max_length[50]'),
array('field'=>'billing_postcode','label'=>'Town/City','rules'=>'required|min_length[3]|max_length[9]|valid_postcode'),
array('field'=>'billing_address_same','label'=>'Billing Address','rules'=>'check_address[billing]'),
array('field'=>'billing_addressID','label'=>'Billing address','rules'=>'check_address[billing]')
);
I think the simplest approach is the best. In the controller, add the rule if the checkbox is checked.
if(isset($_POST['checkbox'])){
$this->form_validation->set_rules('billing_address_line1', 'Billing Address Line 1', 'required');
}
Added after comments and question edited
Still striving for the simplest implementation while avoiding foreach loops using a bunch of string manipulation, and multiple rules arrays that are nearly identical.
This makes use of the fact that form_validation->set_rules() can accept an array in the third argument (instead of the pipe separated string). The string gets turned into an array eventually anyway so starting with an array is more efficient at runtime.
Also in the name of efficient runtime, method chaining is used when setting rules.
Start by creating reusable "rules" arrays to be passed to set_rules().
$rules_address1 = ['required', 'min_length[3]', 'max_length[200]', 'callback_check_basket'];
$rules_address_23 = ['min_length[3]', 'max_length[200]'];
$rules_city = ['required', 'min_length[3]', 'max_length[50]'];
$rules_postcode = ['required', 'min_length[3]', 'max_length[9]', 'callback_valid_postcode'];
$this->form_validation->set_message('required', 'You must provide {field}.');
$this->form_validation
->set_rules('address_line1', 'Address line 1', $rules_address1)
->set_rules('address_line2', 'Address line 2', $rules_address_23)
->set_rules('address_line3', 'Address line 3', $rules_address_23)
->set_rules('city', 'Town/City', $rules_city)
->set_rules('postcode', 'Postal Code', $rules_postcode);
if(!isset($_POST['checkbox']))
{
unset($rules_address1[0]);
unset($rules_address_23[0]);
unset($rules_city[0]);
unset($rules_postcode[0]);
}
$this->form_validation
->set_rules('billing_address_line1', 'Billing Address line 1', $rules_address1)
->set_rules('billing_address_line2', 'Billing Address line 2', $rules_address_23)
->set_rules('billing_address_line3', 'Billing Address line 3', $rules_address_23)
->set_rules('billing_city', 'Town/City', $rules_city)
->set_rules('billing_postcode', 'Postal Code', $rules_postcode);
I skipped rules for the addressID field(s) as I'm not sure how it is used.
Also, per CI SOP, added callback_ to what appeared to me to be custom callback methods. Adjust accordingly.
As you know, this all takes place in the controller before $this->form_validation->run() is called.
Check it from Form validation class. Call your own validation method for rules that you want to delete. https://codeigniter.com/user_guide/libraries/form_validation.html#callbacks-your-own-validation-methods
Then in those methods, check whether Checkbox is checked or not. If checked, skip all rules, and return TRUE from callback function. Something like this:
address_line1_callback_function() {
CI = &get_instance();
if ( CI->input->post('checked') )
return true;
/// Rules for address line go here
}
I'm using Laravel for a project and want to know how to validate a particular scenario I'm facing. I would like to do this with the native features of Laravel if this is possible?
I have a form which has two questions (as dropdowns), for which both the answer can either be yes or no, however it should throw a validation error if both of the dropdowns equal to no, but they can both be yes.
I've check the laravel documentation, but was unsure what rule to apply here, if there is one at all that can be used? Would I need to write my own rule in this case?
very simple:
let's say both the fields names are foo and bar respectively.
then:
// Validate for those fields like $rules = ['foo'=>'required', 'bar'=>'required'] etc
// if validation passes, add this (i.e. inside if($validator->passes()))
if($_POST['foo'] == 'no' && $_POST['bar'] == 'no')
{
$messages = new Illuminate\Support\MessageBag;
$messages->add('customError', 'both fields can not be no');
return Redirect::route('route.name')->withErrors($validator);
}
the error messge will appear while retrieving.
if you get confuse, just dump the $error var and check how to retrieve it. even if validation passes but it gets failed in the above code, it won't be any difference than what would have happened if indeed validation failed.
Obviously don't know what your form fields are called, but this should work.
This is using the sometimes() method to add a conditional query, where the field value should not be no if the corresponding field equals no.
$data = array(
'field1' => 'no',
'field2' => 'no'
);
$validator = Validator::make($data, array());
$validator->sometimes('field1', 'not_in:no', function($input) {
return $input->field2 == 'no';
});
$validator->sometimes('field2', 'not_in:no', function($input) {
return $input->field1 == 'no';
});
if ($validator->fails()) {
// will fail in this instance
// changing one of the values in the $data array to yes (or anything else, obvs) will result in a pass
}
Just to note, this will only work in Laravel 4.2+
Well here is a example error Codeigniter will shoot out at the user if they don't type in their email.
email: The Email field is required.
Now the "email" part specifically. How can I change it to whatever I like? It seems its using the inputs name/id.
Example of how I setup form validation for email.
$this->form_validation->set_rules('email', 'Email', 'required|valid_email|is_unique[user.email]');
So maybe a better example .. say I wanted to change it from saying "email" to "The Email"
Thanks in advnace.
You should use set_message function in form_validation library.For example;
$this->form_validation->set_message('email', '%s is entered email adress, it's wrong!');
CodeIgniter's user-guide is very easy and interactive.You should check the documentation for these type of basic questions.
CodeIgniter user-guide
This is how I do it:
If you want to alter the message use set_message:
$this->form_validation->set_message('required', 'Your custom message here');
Using a Callback is a better way to do it:
$this->form_validation->set_rules('username', 'Username', 'check_user_name');
public function username_check($str)
{
if (strlen($str)<0)
{
$this->form_validation->set_message('check_user_name', 'The %s field is empty"');
return FALSE;
}
else
{
return TRUE;
}
}
Ok I don't know what's not working. I know my form validation is definitely working because all my other functions work properly, but I am setting messages whether it's true OR false and none of them show up so I feel like it's skipping right over the validation rule.. which is weird...
$this->form_validation->set_rules('region', 'required|valid_region');
The rule in MY_Form_validation.php in my libraries folder. The library IS loaded first. As I said all my other validations work properly such as my reCaptcha and everything.
function valid_region($str) {
$this->load->database();
if($this->db->query('SELECT id
FROM region
WHERE name = ?
LIMIT 1', array($str))->num_rows() == 0) {
//not a valid region name
$this->set_message('valid_region', 'The %s field does not have a valid value!');
return false;
}
$this->set_message('valid_region', 'Why is it validating?');
}
None of the messages will set so I have a feeling nothing is validating!
set_rules() function takes 3 parameters
The field name - the exact name you've given the form field.
A "human" name for this field, which will be inserted into the error message.
For example, if your field is named "user" you might give it a human
name of "Username". Note: If you would like the field name to be
stored in a language file, please see Translating Field Names.
The validation rules for this form field.
You put the validation rules as second parameter. That is why the validation is not running. Try this instead:
$this->form_validation->set_rules('region', 'Region', 'required|valid_region');
instead of
$this->form_validation->set_rules('region', 'required|valid_region');
try
$this->form_validation->set_rules('region', 'required|callback_valid_region');
when using custom validation rules you should use
callback to prepend the function name.
UPDATE
and use
$this->form_validation->set_message
instead of
$this->set_message
and in function valid_region
use return true when validation is successfull
$this->form_validation->set_rules('region', 'Region', 'required|valid_region');
function valid_region() {
$str = $this->input->post('name_of_input');
$this->load->database();
if($this->db->query('SELECT id
FROM region
WHERE name = ?
LIMIT 1', array($str))->num_rows() == 0) { // why compare "=" between `name` field and array() ?
//not a valid region name
$this->form_validation->set_message('valid_region', 'The %s field does not have a valid value!');
return false;
}
$this->form_validation->set_message('valid_region', 'Why is it validating?');
return true;
}
I'd like to have input validated with form_validation class, that'll allow me to put numeric or empty value in the field.
Something like this:
$this->form_validation->set_rules('field[]','The field','numeric or empty|xss_clean');
Is this possible to achieve?
$this->form_validation->set_rules('field[]', 'The field', 'numeric|xss_clean');
This should be sufficient in theory, since the field hasn't been set to required.
But, it returns me the errors
Then perhaps an extra step:
if (!empty($this->input->post('field[]')))
{
$this->form_validation->set_rules('field[]', 'The field', 'numeric|xss_clean');
}
For phone number with 10 digits:
$this->form_validation->set_rules('mobile', 'Mobile Number ', 'required|regex_match[/^[0-9]{10}$/]'); //{10} for 10 digits number
I think you mean "Using Arrays as Field Names"
You can have a look at this page
$this->form_validation->set_rules('field[]','The field','is_natural|trim|xss_clean');
if ($this->form_validation->run() == FALSE) {
$errors = $this->form_validation->error_array();
if (!empty($errors['field'])) {
$errors_data = $errors['field'];
}
print_r($errors_data);exit;
}
You can use is_natural that Returns FALSE if the form element contains anything other than a natural number: 0, 1, 2, 3, etc.
For empty checking required rule is used that Returns FALSE if the form element is empty. So remove the required rule is if used.
And use form_validation rules for showing your rules message