I want to pass multiple callbacks in codeigniter form validation rules.... but only one of the callbacks work
I am using this syntax in my contoller
$this->form_validation->set_rules(
array(
'field' => 'field_name',
'label' => 'Field Name',
'rules' => 'callback_fieldcallback_1|callback_fieldcallback_2[param]',
'errors' => array(
'fieldcallback_1' => 'Error message for rule 1.',
'fieldcallback_2' => 'Error message for rule 2.',
)
),
);
and the callback functions are....
function fieldcallback_1 (){
if(condition == TRUE){
return TRUE;
} else {
return FALSE;
}
}
function fieldcallback_2 ($param){
if(condition == TRUE){
return TRUE;
} else {
return FALSE;
}
}
Someone please help me out with this problem.... any other solutions regarding passing multiple callbacks in form validation rules are also appreciated...
All validation routines must have at least one argument which is the value of the field to be validated. So, a callback that has no extra arguments should be defined like this.
function fieldcallback_1($str){
return ($str === "someValue");
}
A callback that requires two arguments is defined like this
function fieldcallback_2 ($str, $param){
//are they the same value?
if($str === $param){
return TRUE;
} else {
$this->form_validation->set_message('fieldcallback_2', 'Error message for rule 2.');
//Note: `set_message()` rule name (first argument) should not include the prefix "callback_"
return FALSE;
}
Maybe like this?
$this->form_validation->set_rules(
array(
'field' => 'field_name',
'label' => 'Field Name',
'rules' => 'callback_fieldcallback_1[param]'),
);
// Functions for rules
function fieldcallback_1 ($param){
if(condition == TRUE){
return fieldcallback_2($param);
} else {
$this->form_validation->set_message('callback_fieldcallback_1', 'Error message for rule 1.');
return FALSE;
}
}
function fieldcallback_2 ($param){
if(condition == TRUE){
return TRUE;
} else {
$this->form_validation->set_message('callback_fieldcallback_1', 'Error message for rule 2.');
return FALSE;
}
}
Related
On the HTML form, I have a field such as:
<?php
$token = array(
'name' => 'pc_token',
'id' => 'pc_token',
'class' => 'form-control'
);
echo form_input($token, set_value('pc_token')); ?>
The validation rules set on the field are:
$this->form_validation->set_rules(
'pc_token', 'Token number', 'trim|required|min_length[5]|max_length[12]|callback_token_exists',
array(
'required' => 'You have not provided %s.',
'token_exists' => 'The %s is not valid. Please recheck again'
)
);
And here is the function for the callback
public function token_exists($key)
{
$this->load->model('tokens');
return $this->tokens->IsValidToken($key); // will return true if found in database or false if not found
}
The problem here is that when I keep the pc_token field empty/blank and submit the form, I don't get the expected error message printed on screen.
Current Output
The Token number is not valid. Please recheck again
Expected Output
You have not provided Token number
So why does CI ignore the previous rules (such as required, min_length etc) in this case? If my assumption is correct, the direction is left to right and if even one fails, it does not move to the next rule.
try this in your callback function
check for empty
public function token_exists($key='')
{
if(empty($key)){
$this->form_validation->set_message('token_exists', 'The {field} field is required.');
return FALSE;
}else{
$this->load->model('tokens');
return $this->tokens->IsValidToken($key);
}
// will return true if found in database or false if not found
}
I'll post the approach that I took. But I'll accept Abhishek's answer as he led me in the right direction. It's a bit sad that CI3 did not address it so I'm forced to use an alternate approach.
So, the validation rules become:
$this->form_validation->set_rules(
'pc_token', 'Token number', 'callback_token_exists'
);
And the callback function becomes:
public function token_exists($key)
{
if(trim($key) == "" || empty($key))
{
$this->form_validation->set_message('token_exists', 'You have not provided %s.');
return FALSE;
}
else if(strlen($key) < 5)
{
$this->form_validation->set_message('token_exists', '%s should be at least 5 characters long.');
return FALSE;
}
else if(strlen($key) > 12)
{
$this->form_validation->set_message('token_exists', '%s cannot be greater than 12 characters long.');
return FALSE;
}
else
{
$this->load->model('tokens');
$isValid = $this->tokens->IsValidToken($key);
if(! $isValid)
{
$this->form_validation->set_message('token_exists', 'You have not provided %s.');
}
return $isValid;
}
}
I have a code like this given below:
$this->form_validation->set_rules("codetype", "Code Type", array(
"codecheck" => function ($str) {
// just return it false.
return false;
}
), array("codecheck"=>"return this message"));
I want it to return the codecheck error message. but codeigniter form validation class returns this message:
"Unable to access an error message corresponding to your field name
Code Type".
How can I write a fully anonymous CodeIgniter function with an error message?
Hope this will help you :
You can remove required if you want and also set your if condition
$this->form_validation->set_rules('codetype', 'Code Type',
array(
'required',
array(
'codecheck_callable',
function($str)
{
// Check validity of $str and return TRUE or FALSE
if ($str == 'test')
{
$this->form_validation->set_message('codecheck_callable', 'can not be test');
return false;
}
else
{
return TRUE;
}
}
)
)
);
For more : https://www.codeigniter.com/user_guide/libraries/form_validation.html#callbacks-your-own-validation-methods
According to CodeIgniter docs at https://www.codeigniter.com/userguide3/libraries/form_validation.html
you can do it like this
$this->form_validation->set_message('username_check', 'The {field} field can not be the word "test"');
I've an attribute in model which I want to validate in such a way that - It must be an array and must have 3 element, also every element inside array must be a string. Currently I'm using.
['config', 'each', 'rule' => ['string']]
You could simply use a custom validator, e.g. :
['config', function ($attribute, $params) {
if(!is_array($this->$attribute) || count($this->$attribute)!==3){
$this->addError($attribute, 'Error message');
}
}],
['config', 'each', 'rule' => ['string']]
Read more about creating validators.
You can add a custom validation rules like below:
public function rules()
{
return ['config','checkIsArray'];
}
public function checkIsArray($attribute, $params)
{
if (empty($this->config)) {
$this->addError('config', "config cannot be empty");
}
elseif (!is_array($this->config)) {
$this->addError('config', "config must be array.");
}
elseif (count($this->config)<3) {
$this->addError('config', "config must have 3 elements");
}
else {
foreach ($this->config as $value) {
if (!is_string($value)) {
$this->addError('config ', "config should have only string values.");
}
}
}
}
I want to limit my registration to emails with #mywork.com I made the following in My_Form_validation.
public function email_check($email)
{
$findme='mywork.com';
$pos = strpos($email,$findme);
if ($pos===FALSE)
{
$this->CI->form_validation->set_message('email_check', "The %s field does not have our email.");
return FALSE;
}
else
{
return TRUE;
}
}
I use it as follows. I use CI rules for username and password and it works, for email it accepts any email address. Any I appreciate any help.
function register_form($container)
{
....
....
/ Set Rules
$config = array(
...//for username
// for email
array(
'field'=>'email',
'label'=>$this->CI->lang->line('userlib_email'),
'rules'=>"trim|required|max_length[254]|valid_email|callback_email_check|callback_spare_email"
),
...// for password
);
$this->CI->form_validation->set_rules($config);
The problem with creating a callback directly in the controller is that it is now accessible in the url by calling http://localhost/yourapp/yourcontroller/yourcallback which isn't desirable. There is a more modular approach that tucks your validation rules away into configuration files. I recommend:
Your controller:
<?php
class Your_Controller extends CI_Controller{
function submit_signup(){
$this->load->library('form_validation');
if(!$this->form_validation->run('submit_signup')){
//error
}
else{
$p = $this->input->post();
//insert $p into database....
}
}
}
application/config/form_validation.php:
<?php
$config = array
(
//this array key matches what you passed into run()
'submit_signup' => array
(
array(
'field' => 'email',
'label' => 'Email',
'rules' => 'required|max_length[255]|valid_email|belongstowork'
)
/*
,
array(
...
)
*/
)
//you would add more run() routines here, for separate form submissions.
);
application/libraries/MY_Form_validation.php:
<?php
class MY_Form_validation extends CI_Form_validation{
function __construct($config = array()){
parent::__construct($config);
}
function belongstowork($email){
$endsWith = "#mywork.com";
//see: http://stackoverflow.com/a/619725/568884
return substr_compare($endsWith, $email, -strlen($email), strlen($email)) === 0;
}
}
application/language/english/form_validation_lang.php:
Add: $lang['belongstowork'] = "Sorry, the email must belong to work.";
Are you need validation something like this in a Codeigniter callback function?
$this->form_validation->set_rules('email', 'email', 'trim|required|max_length[254]|valid_email|xss_clean|callback_spare_email[' . $this->input->post('email') . ']');
if ($this->form_validation->run() == FALSE)
{
// failed
echo 'FAIL';
}
else
{
// success
echo 'GOOD';
}
function spare_email($str)
{
// if first_item and second_item are equal
if(stristr($str, '#mywork.com') !== FALSE)
{
// success
return $str;
}
else
{
// set error message
$this->form_validation->set_message('spare_email', 'No match');
// return fail
return FALSE;
}
}
A correction to Jordan's answer, the language file that you need to edit should be located in
system/language/english/form_validation_lang.php
not application/.../form_validation_lang.php. If you create the new file under the application path with the same name, it will overwrite the original in the system path. Thus you will lose all the usage of the original filters.
I'm trying to create a custom validation rule for when a checkbox is checked, an input field will need to be filled out in order to proceed to the next page. If unchecked, the input field will not be required.
Here's my code in View:
echo $this->Form->inputs(array(
'legend'=>'Certifications',
'rn_box'=>array(
'type'=>'checkbox',
'label'=>'RN',
'value' => $results['Education']['rn_box']
),
'rn_number'=>array(
'label'=>'RN Number:',
'value' => $results['Education']['rn_number']
),
));
In my Model I created a function:
public function rnCheck () {
if ($this->data['Education']['rn_box'] == '0') {
return false;
}
return true;
}
public $validate = array(
'rn_number' => array(
'rnCheck'=>array(
'rule'=>'rnCheck',
'message'=>'Please Provide a Number'
),
),
);
The checkbox returns a value of 1 if checked, and a value of 0 unchecked. The rn_number field is an input field that I'm trying to validate. I tried playing with 'required', 'allowEmpty', etc. with no luck. If anyone can point me in the right direct, that would be great, thanks!
You can probably just handle it all in the function callback for rn_number. I would also call the function and rule name rn_number to avoid any confusion.
For example, change your validate array to:
public $validate = array(
'rn_number' => array(
'rn_number'=>array(
'rule'=>'rn_number'
),
),
);
And then your custom validation function can look like:
public function rn_number () {
if ($this->data['Education']['rn_box'] == 1) {
if($this->data['Education']['rn_number'] == '')
$errors[] = "Please enter your RN Number.";
}
if (!empty($errors))
return implode("\n", $errors);
return true;
}
I'm handling the error message in the custom validation function - not in the validate array. Let me know if this doesn't work!