This is my callback function, I want to check the database for duplicate value, I have tried a lot, but I can't get validation to work. I'm new to Codeigniter so any help would be appreciated!
public function alias_exist_check()
{
$scol_code = $this->input->post('school_code');
$user_id=$this->input->post('user_id');
$query=$this->db->get_where('user_application',array('school_code'=>$scol_code, 'user_id'=>$user_id));
$row= $query->row_array();
if(!$row['user_id']==$user_id && !$row['school_code']==$scol_code)
{
return TRUE;
} else {
$this->form_validation->set_message('alias_exist_check', 'Already exists.');
return FALSE;
}
}
UPDATE1 ::
i tried this but its not working me help me if i wrote any mistakes.
$this->form_validation->set_rules('school_code', 'School Name','required','callback_alias_exist_check', 'trim|xss_clean'); $where = array(
'school_code' => $this->input->post('school_code'),
'user_id' => $this->input->post('post'));
if( ! $this->lawschool_model->alias_exist_check($where))
{
$this->form_validation->set_message('alias_exist_check', 'Already exists.');
}
if ($this->form_validation->run() == FALSE)
{
$data['row']= $this->lawschool_model->Getuser($data1);
$data['row1']= $this->lawschool_model->GetData1();
$this->ag_auth->view('Home',$data);
}
else
{
$insert = $this->db->insert('user_application',$data);
if($insert==TRUE)
{
/*$idNum = $this->input->post('school_code');
$data1 = $this->lawschool_model->upddata_school();*/
$data['row'] = $this->lawschool_model->Getuser($data1);
$data['row1'] = $this->lawschool_model->GetData1();
$this->ag_auth->view('Home',$data);
}
}
UPDATE2::finaly its works fine,here is my working code
$this->form_validation->set_rules('school_code', 'School Name','required','callback_alias_exist_check1', 'trim|xss_clean');
function alias_exist_check1($scol_code,$user_id)
{
$sql = "SELECT * FROM user_application WHERE school_code = ? AND user_id = ?";
$val = $this->db->query($sql,array($scol_code ,$user_id ));
if ($val->num_rows)
{
$this->form_validation->set_message('alias_exist_check', 'Already exists.');
return TRUE;
}
else
{
return FALSE;
}
}
Model
public function alias_exist($where)
{
return $this->db->where($where)->count_all_results('user_application') > 0;
}
Controller
public function alias_exist_check()
{
$where = array(
'school_code' => $this->input->post('school_code'),
'user_id' => $this->input->post('user_id')
);
return ! $this->name_model->alias_exist($where);
}
The first function was not working because you tried to access post data from within the callback itself. This does not appear to work well with callbacks. This is because codeigniter will remove all post data from the request as soon as your run the form validator run method. It repopulates post data only when form processing is complete. Pass any extra parameters you need for you callback functions to work like this
callback_foo[bar]
How do I get CodeIgniter to run custom rules on fields which don't have the required rule but the user left empty?
The best I can come up with is to add a space to the field if the string is empty, and then add a trim rule -- but this feels hacky.
Example rule #1
Field is required only if another field has a certain value:
// depends[another_field.some_val]
public function depends($str, $field){
list($post_key, $post_val)=explode('.', $field);
if($_POST[$post_key] == $post_val){
return $str != "";
}
return true;
}
Example rule #2
Field is required only if a regex exists on the database:
// regex[table_name.col_name.some_val]
public function regex($str, $field){
list($table, $col, $post_val)=explode('.', $field);
// Grab the regex
$regex = $this->CI ->db
->limit(1)
->select($col)
->where($post_val, $_POST[$post_val])
->get($table)
->row($col);
return preg_match('/'.$regex.'/', $str) === 1;
}
Why is there a need of a different function for a simple task. Use if..else.
Assuming that if input1 has value equals value1, then only you have to set the required validation rule for the other input which is say input2.
View:
<form action="/controller_name/function_name/" method="POST">
<input type="text" name="input1" />
<input type="text" name="input2" />
<input type="submit" />
</form>
Controller:
class Controller_name extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->library('form_validation');
}
public function function_name()
{
if($this->input->is_post())
{
if($this->input->post('input1') == 'value1')
{
$this->form_validation->set_rules('input2', 'input2', 'required');
}
if ($this->form_validation->run() == FALSE)
{
// something's wrong in form!
}
else
{
// form is good, proceed!
}
}
}
}
From the code, the problem you point out is that you NEED make a field required. Well, make a kind of required field with a new rule: 'keep_checking'. This way, you force the system to check whatever you want. What I did:
A My_Form_validation class which extends system core class (so, you won't have to touch system files). NOTE: Don't forget this file goes inside of application/libraries folder
Check if the custom rule 'keep_checking' is set. That will override the behaviour of not checking the fields when 'required' rule is set (See the code below)
Last point, after extending the Form_validation class you'll have a place to put all your new custom rules you'll be using all the time, XD
class MY_Form_validation extends CI_Form_validation
{
public function __construct( $rules = array( ) ) {
parent::__construct( $rules );
}
protected function _execute($row, $rules, $postdata = NULL, $cycles = 0)
{
// If the $_POST data is an array we will run a recursive call
if (is_array($postdata))
{
foreach ($postdata as $key => $val)
{
$this->_execute($row, $rules, $val, $cycles);
$cycles++;
}
return;
}
// --------------------------------------------------------------------
// If the field is blank, but NOT required, no further tests are necessary
$callback = FALSE;
//====================================================================
// NEW ADDED RULE > 'keep_checking', will check all the rules even if
// the field is empty
//====================================================================
if ( ! in_array('required', $rules) AND is_null($postdata) AND ! in_array( 'keep_checking', $rules ) )
{
// Before we bail out, does the rule contain a callback?
if (preg_match("/(callback_\w+(\[.*?\])?)/", implode(' ', $rules), $match))
{
$callback = TRUE;
$rules = (array('1' => $match[1]));
}
else
{
return;
}
}
// --------------------------------------------------------------------
// Isset Test. Typically this rule will only apply to checkboxes.
//====================================================================
// NEW ADDED RULE > 'keep_checking', will check all the rules even if
// the field is empty
//====================================================================
if (is_null($postdata) AND $callback == FALSE && !in_array( 'keep_checking', $rules ))
{
if (in_array('isset', $rules, TRUE) OR in_array('required', $rules))
{
// Set the message type
$type = (in_array('required', $rules)) ? 'required' : 'isset';
if ( ! isset($this->_error_messages[$type]))
{
if (FALSE === ($line = $this->CI->lang->line($type)))
{
$line = 'The field was not set';
}
}
else
{
$line = $this->_error_messages[$type];
}
// Build the error message
$message = sprintf($line, $this->_translate_fieldname($row['label']));
// Save the error message
$this->_field_data[$row['field']]['error'] = $message;
if ( ! isset($this->_error_array[$row['field']]))
{
$this->_error_array[$row['field']] = $message;
}
}
return;
}
// --------------------------------------------------------------------
// Cycle through each rule and run it
foreach ($rules As $rule)
{
$_in_array = FALSE;
// We set the $postdata variable with the current data in our master array so that
// each cycle of the loop is dealing with the processed data from the last cycle
if ($row['is_array'] == TRUE AND is_array($this->_field_data[$row['field']]['postdata']))
{
// We shouldn't need this safety, but just in case there isn't an array index
// associated with this cycle we'll bail out
if ( ! isset($this->_field_data[$row['field']]['postdata'][$cycles]))
{
continue;
}
$postdata = $this->_field_data[$row['field']]['postdata'][$cycles];
$_in_array = TRUE;
}
else
{
$postdata = $this->_field_data[$row['field']]['postdata'];
}
// --------------------------------------------------------------------
// Is the rule a callback?
$callback = FALSE;
if (substr($rule, 0, 9) == 'callback_')
{
$rule = substr($rule, 9);
$callback = TRUE;
}
// Strip the parameter (if exists) from the rule
// Rules can contain a parameter: max_length[5]
$param = FALSE;
if (preg_match("/(.*?)\[(.*)\]/", $rule, $match))
{
$rule = $match[1];
$param = $match[2];
}
// Call the function that corresponds to the rule
if ($callback === TRUE)
{
if ( ! method_exists($this->CI, $rule))
{
continue;
}
// Run the function and grab the result
$result = $this->CI->$rule($postdata, $param);
// Re-assign the result to the master data array
if ($_in_array == TRUE)
{
$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
}
else
{
$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
}
// If the field isn't required and we just processed a callback we'll move on...
if ( ! in_array('required', $rules, TRUE) AND $result !== FALSE)
{
continue;
}
}
else
{
if ( ! method_exists($this, $rule))
{
// If our own wrapper function doesn't exist we see if a native PHP function does.
// Users can use any native PHP function call that has one param.
if (function_exists($rule))
{
$result = $rule($postdata);
if ($_in_array == TRUE)
{
$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
}
else
{
$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
}
}
else
{
log_message('debug', "Unable to find validation rule: ".$rule);
}
continue;
}
$result = $this->$rule($postdata, $param);
if ($_in_array == TRUE)
{
$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
}
else
{
$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
}
}
// Did the rule test negatively? If so, grab the error.
if ($result === FALSE)
{
if ( ! isset($this->_error_messages[$rule]))
{
if (FALSE === ($line = $this->CI->lang->line($rule)))
{
$line = 'Unable to access an error message corresponding to your field name.';
}
}
else
{
$line = $this->_error_messages[$rule];
}
// Is the parameter we are inserting into the error message the name
// of another field? If so we need to grab its "field label"
if (isset($this->_field_data[$param]) AND isset($this->_field_data[$param]['label']))
{
$param = $this->_translate_fieldname($this->_field_data[$param]['label']);
}
// Build the error message
$message = sprintf($line, $this->_translate_fieldname($row['label']), $param);
// Save the error message
$this->_field_data[$row['field']]['error'] = $message;
if ( ! isset($this->_error_array[$row['field']]))
{
$this->_error_array[$row['field']] = $message;
}
return;
}
}
}
}
UPDATE:
Checkbox line was avoiding keep checking. Just add the new line I added, and it'll work. You have to add the keep_checking rule to any field you want to check:
class Welcome extends CI_Controller {
/**
* Index Page for this controller.
*
* Maps to the following URL
* http://example.com/index.php/welcome
* - or -
* http://example.com/index.php/welcome/index
* - or -
* Since this controller is set as the default controller in
* config/routes.php, it's displayed at http://example.com/
*
* So any other public methods not prefixed with an underscore will
* map to /index.php/welcome/<method_name>
* #see http://codeigniter.com/user_guide/general/urls.html
*/
public function index()
{
$this->load->view('welcome_message');
}
public function test()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('name', 'Name', 'keep_checking|required');
$this->form_validation->set_rules('surname', 'Surname', 'keep_checking|is_numeric');
if ( $this->form_validation->run() ) {
} else {
$this->load->view('form');
}
}
}
View: form.php
<form action="test" method="post">
<?php echo validation_errors(); ?>
<p>
Name: <input name="name">
</p>
<p>
Surname: <input name="surname">
</p>
<p>
<input type="submit" value="Send">
</p>
</form>
After submit that form, you'll see as CI check all rules from the input fields. Last point, don't forget that MY_Form_validation goes inside of libraries folder
In my update methods I only wanted to submit fields that were dirty. Not all fields were required and validation was failing if one a field that needed no validation was sent as empty.
So if the user wanted to remove their phone it would be sent like phone:"" and the validation wouldn't see it if I tried to pass it like so.
if($this-put("phone")) $this->form_validation->set_rules('phone', 'Phone', 'trim');
So I had to use array_key_exist() for it to see it and pass it, even it it was empty.
if($this->put("description")) $this->form_validation->set_rules('description', 'Description', 'trim|required');
if(array_key_exists("phone", $this->input->post())) $this->form_validation->set_rules('phone', 'Phone', 'trim');
I think what you are looking for is callbacks
You can define callbacks in your rule
$this->form_validation->set_rules('field1', 'Field 1', 'trim|callback_field1_check');
$this->form_validation->set_rules('field2', 'Field 2', 'callback_field2_check');
And now you can have a function with boolean return value.
public function field1_check($input) {
if ($input != '') {
$this->field1Set = true;
}
}
public function field2_check($input) {
// do something on $input
$input = trim($input);
// awesome thing is, you get to access all the field variables of your control here
// so in some other function, you'll toggle a boolean to note that an optional field was filled
// that variable set by other validation callback, you can use here
if ($this->field1Set === true && $input == '') return false;
return true;
}
I've worked out a way to do this myself by editing system/libraries/Form_validation.php.
I changed $callback to TRUE on line 487:
$callback = TRUE;
And commented out lines 488 - 500:
if ( ! in_array('required', $rules) AND is_null($postdata))
{
// Before we bail out, does the rule contain a callback?
if (preg_match("/(callback_\w+(\[.*?\])?)/", implode(' ', $rules), $match))
{
$callback = TRUE;
$rules = (array('1' => $match[1]));
}
else
{
return;
}
}
The bounty still stands if someone can think of a solution without editing CodeIgniter's system files.
function add($id = '') {
$this->form_validation->set_rules('title', 'Title', 'trim|required');
$this->form_validation->set_rules('title_description', 'title_description', 'trim|required');
$this->form_validation->set_rules('color', 'color', 'trim|required');
$this->form_validation->set_rules('button', 'button', 'trim|required');
//$this->form_validation->set_rules('description', 'Description', 'trim|required');
if ($this->form_validation->run() == FALSE) {
echo "Not Valid";
} else {
echo "Valid";
}
}
You can add an hidden input in the view with permanent value and test it in validates rules.
In view:
<input type="hidden" name="id_form" value="1"/>
In model or controller (it depends of your architecture)
public function validates_rules(){
$this->form_validation->set_rules('id_form', 'Title', 'callback_values_check');
...
}
public function values_check($id_form){
if($this->input->post('other_value_to_test')){
...
}
}
I tried to validate the password field using a callback function. But when I use the following code, all validations do not work any more WHEN I TYPE 1234 (callback condition). When I remove the validation which contains the callback function, other validations work perfectly..
This is my validation rules
$crud->set_rules('password', 'Password', 'callback_valid_password');
$crud->set_rules('confirm_password', 'Password Confirmation', 'required|matches[password]');
$crud->set_rules('email', 'Email', 'trim|required|valid_email');
Here is my callback function
function valid_password($str) {
if ($str=="1234")
{
$crud->set_message('_valid_password', 'The field should be 1234');
//do some pw validation
return FALSE;
}
else
{
return TRUE;
}
}
Please help me to find what is wrong here.. Thank you in advance
p.s - I am using php 5.4 version with the latest grocery crud version
function valid_password($str) {
if ($str=="1234")
{
$this->form_validation->set_message('valid_password', 'The field should be 1234');
//do some pw validation
return FALSE;
}
else
{
return TRUE;
}
}
For those who are still struggling to find the solution, please follow the checklist.
Are you using CodeIgniter as MVC or HMVC?
1. HMVC
(A) - Check if you have updated the file (./application/libraries/Grocery_crud.php) as suggested below.
(B) - Before "__construct" inside " "class Grocery_CRUD extends grocery_CRUD_States" add "protected $hmvc;"
(C) - Update "__construct" with as below:
public function __construct($hmvc = null)
{
$this->hmvc = $hmvc;
}
(D) - Update "form_validation" with as below:
protected function form_validation()
{
if ($this->form_validation === null) {
$this->form_validation = new grocery_CRUD_Form_validation();
if ($this->hmvc) $this->form_validation->CI = $this->hmvc;
$ci = &get_instance();
$ci->load->library('form_validation');
$ci->form_validation = $this->form_validation;
}
return $this->form_validation;
}
(E) - Use "$crud = new Grocery_crud($this);" instead "$crud = new Grocery_crud();" in your Controller.
(F) - GC set_rules example:
$crud->set_rules("level_title", 'Level Title Label', 'trim|required|callback_unique_level_field_check');
(G) - Callback method example:
public function unique_level_field_check ($level_title)
{
if ( empty($level_title))
{
$this->form_validation->set_message('unique_level_field_check', "Level Title Label should be unique");
return FALSE;
}
return TRUE;
}
2. MVC
Follow F & G only (above).
GroceryCRUD Forum: See details here
I've read somewhere that is possible to use Codeigniter's Form Validation also for my own variables and not only for form's inputs.
For example I'd like to validate a url to say if it is valid but not retrieving it using POST or GET from a form.
Do you know how or have a link?
What you are looking for are the callbacks of the Form Validation Class in CodeIgniter - read the user guide for an in-depth explanation.
For PHP5 above version,you can do this
function validdate_urls($str) {
if(!filter_var($str, FILTER_VALIDATE_URL))
{
$this->validation->set_message('validate_urls', 'URL Invalid');
return 0;
}else {
return TRUE;
}
}
And call it in your validation rules :-
$rules['link'] = "callback_validate_urls";
Yes you can via set_data() method, Here you go.
$this->form_validation->set_data(array(
'cartId' => $cartId
));
$this->form_validation->set_rules('cartId', 'Card ID', 'trim|required|is_natural_no_zero');
if ($this->form_validation->run() == FALSE) {
echo 'Invalid: ' . validation_errors();
} else {
echo 'Valid';
}
How can I validate a form using regex in codeiginiter. I'd like to check the input against:
^([0-1][0-9]|[2][0-3]):([0-5][0-9])$
I'm assuming the best way is in some sort of callback. I tried a bunch of ideas on the web but I can't seem to get any working.
Old post but you can add the regex directly in the input validation rule
$this->form_validation->set_rules()
Add to function above: regex_match[your regex]
You can create a function like this:
function validateRegex($input)
{
if (preg_match('/^([0-1][0-9]|[2][0-3]):([0-5][0-9])$/', $input))
{
return true; // it matched, return true or false if you want opposite
}
else
{
return false;
}
}
In your controller, you can use it like:
if ($this->validateRegex($this->input->post('some_data')))
{
// true, proceed with rest of the code.....
}
How about using AJAX?
$("form").submit(function(e) {
e.preventDefault();
$.post("<?php echo base_url(); ?>regex_check", { username: $("#username").val() }, function (data) {
alert(data);
});
The regex_check function would have a typical regex check in it, like
function regex_check(){
$this->get->post('username');
if(eregi('^[a-zA-Z0-9._-]+#[a-zA-Z0-9-] +\.[a-zA-Z.]{2,5}$', $username)){
return TRUE;}else{return FALSE;}
}
You would only allow successful submission of form if all data is validated.
These code snippets should help you on the track to validating the data.
here's a full solution submitting to account/signup
in the account controller:
function signup(){
if($_POST){
$this->form_validation->set_rules('full_name', 'Full Name', 'required|min_length[3]|max_length[100]');
$this->form_validation->set_rules('email_address', 'Email Address', 'required|valid_email');
$this->form_validation->set_rules('password', 'Password', 'required|callback_check_password');
if ($this->form_validation->run() == FALSE){
echo validation_errors();
}
else{
// form validates, now can do stuff such as insert into database
// and show the user that they successfully signed up, i.e.,:
// $this->load->view('account/signup_success');
}
}
}
check_password callback function also in the account controller:
function check_password($p){
$p = $this->input->post('password');
if (preg_match('/(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8}/', $p)) return true;
// it matched, see <ul> below for interpreting this regex
else{
$this->form_validation->set_message('check_password',
'<span class="error">
<ul id="passwordError">
<li> Password must be at least:</li>
<li> 8 characters</li>
<li> 1 upper, 1 lower case letter</li>
<li> 1 number</li>
</ul>
</span>');
return false;
}
}