I have checked all the questions of similar kind, and none of them are solving my problem, using CI 2.1.3, and HMVC from Wiredesignz.
I have in my form_validation.php config file the following rule:
array(
'field' => 'eta-renpal-1',
'label' => 'Renpal number (1)',
'rules' => 'required|callback_check_eta_group'
),
And in my ETA controller, I have this function (currently set to ALWAYS be invalid while testing):
public function check_eta_group($reference)
{
// Internal function for use by form validation system to check if the ETA group requirements are met.
$this->form_validation->set_message('check_eta_group', 'Other values in the group ' . $reference . ' are also required.');
return false;
}
For some reason, the "required" function works, but the callback does not. I have tried all other similar suggested solutions, and can't get them to work. Please help?
Edit: The callback does not appear to be called at all. I even did var_dump() in the callback to see if there is output on the screen - none...
Edit2:: See last comment by myself - using that work-around solves the problem, but it is not exactly what I wanted. So - if you have a better solution, please share :-)
See my last comment under the question
(Using a workaround explained here, stackoverflow.com/questions/3029717/…, it works. It is not the way I want it to work with callbacks, but as long as it works, it is probably alright. Thanks anyways.)
Thanks Frosty for your comments.
make sure your function checks are inside the same controller that you are actually running the custom checks in (i.e. it should be able to be called with self::check_eta_group)
I had trouble getting validation working with my checks inside of MY_Controller for instance.
But when i moved them into the extended controller it worked fine.
here are two checks and how I called them (all within the same controller)
// custom form validators for datepicker and timepicker
public function date_valid($date){
$month = (int) substr($date, 0, 2);
$day = (int) substr($date, 3, 2);
$year = (int) substr($date, 6, 4);
$this->form_validation->set_message('date_valid', 'The %s field is not a valid date');
return checkdate($month, $day, $year);
}
public function time_valid($time){
$this->form_validation->set_message('time_valid', 'The %s field is not a valid time');
if (preg_match("/^(1[0-2]|0?[1-9]):[0-5][0-9] (AM|PM)$/i", $time)) {
return TRUE;
} else {
return FALSE;
}
}
public function create_custom(){
// load models and libraries
$this->load->helper(array('form', 'url'));
$this->load->library('form_validation');
// set form validation rules
$this->form_validation->set_rules('schedule_date', 'Schedule Date', 'required|callback_date_valid');
$this->form_validation->set_rules('schedule_time', 'Schedule Time', 'required|callback_time_valid');
....
if ($this->form_validation->run() == FALSE) { // failed validation
error_log("validation_errors: ".validation_errors());
}
Related
I have a form that asks a user how long they are planning to stay. I have two fields: number of the stay and the unit of this number i.e. 5 days, 1 week and so on.
I pass two variables: value_stay and unit_stay.
I want to validate them with the special business rules such as "maximum of 3 months of stay is allowed":
$this->form_validation->set_rules('unit_stay', 'stay unit', 'trim|required');
if(isset($_POST['unit_stay'])) {
if($_POST['unit_stay'] === 'month') {
$this->form_validation->set_rules('value_stay', 'stay value', 'less_than_equal_to[3]');
}
}
$this->form_validation->set_rules('value_stay', 'stay value', 'trim|required|integer|greater_than_equal_to[1]');
My problem is that I have redundant check for value_stay. And the second set_rules() overrides the one in the conditions.
In the CI Form Validation documentation there is no recommendation for such dependencies.
Do you guys have special tricks to refactor this kind of special validation? Specifically if the validation for value_stay that depends on value_unit can be shortened into a more compact and un-redundant hack compared to what I did.
You can use a callback function:
http://www.codeigniter.com/user_guide/libraries/form_validation.html#callbacks-your-own-validation-methods
Your callback function might be something like:
$this->form_validation->set_rules('value_stay', 'stay value', 'trim|required|callback_stayToUnitCheck')
Then in the same controller:
private function stayToUnitCheck($stay)
{
$results = FALSE;
// get the units
// you have to get this additional one from the post variable
if(!empty($_POST['unit_stay']))
{
$unit = $_POST['unit_stay'];
switch ($stay)
{
case 'month':
// do your test on stay and unit
if ($unit <= 3) $result = TRUE;
break;
case 'week':
// more tests
}
return $result;
}
Callbacks are very powerful when you get the hang of them. You can even set different messages for the callback error too:
$this->form_validation->set_message('stayToUnitCheck', 'For a stay of months you can only book a maximum of three months at a time.');
Which you can set within the switch for each different kind of stay, or use a default message when a case is not matched.
Hope that helps,
Paul.
After abusing Google for over an hour, I've found no answers to this question :
When using form_validation.php to your validation rules, Is it possible to pass a dynamic value to the callbacks?
array(
'field' => 'passwordrepeat',
'label' => 'סיסמא חוזרת',
'rules' => 'passwordsMatch['myDynamicValue']'
),
This clearly doesn't work as it passes "myDynamicValue" as a string.
Now, because this config file is loaded so early, this only available resource in it is CI_Loader, which doesn't help much, So I can't access the input class.
So my question:
Can a dynamic value pass to the config file, Or should that rule be written inline in the controller itself?
$this->form_validation->set_rules('password1', 'Password', 'trim|required|matches[password2]');
$this->form_validation->set_rules('password2', 'Verify Password', 'trim|required');
This is what I have for setting form validation on two passwords. This is what is what comes after you set all of your rules
if ($this->form_validation->run() == FALSE)
{
//Validation failed
}
else
{
//Validation suceeded carry on
}
Here is a link to some documentation
http://ellislab.com/codeigniter/user-guide/libraries/form_validation.html#validationrules
The answer to this question is a bit embarrassing.
The solution to this is that you can pass other field names to your callbacks.
However, remember that what you're passing is the field and not the actual value.
To get the actual value you'll need to access it through $_POST['field'].
For example the built in Matches function
public function matches($str, $field)
{
if ( ! isset($_POST[$field]))
{
return FALSE;
}
$field = $_POST[$field];
return ($str !== $field) ? FALSE : TRUE;
}
I feel a bit silly :)
The answer to the question is little tricky but it's easy to understand.
The solution for the asked question is here.
Create a form_validation.php file under the application/config/folder.
and past the code as bellow.
$config = array(
array(
'field' => 'passwordrepeat',
'label' => 'סיסמא חוזרת',
'rules' => 'passwordsMatch['myDynamicValue']'
),
);
the rules will loaded automatically available to the $this->form_validation->run(); this method.
Also you can append more array, I mean more rules for the different controller.
Hope this will help you.
I have a controller which I use for a login form. In the view, I have a {error} variable which I want to fill in by using the parser lib, when there is an error. I have a function index() in my controller, controlled by array $init which sets some base variables and the error message to '':
function index()
{
$init = array(
'base_url' => base_url(),
'title' => 'Login',
'error' => ''
);
$this->parser->parse('include/header', $init);
$this->parser->parse('login/index', $init);
$this->parser->parse('include/footer', $init);
}
At the end of my login script, I have the following:
if { // query successful }
else
{
$init['error'] = "fail";
$this->parser->parse('login/index', $init);
}
Now, of course this doesn't work. First of all, it only loads the index view, without header and footer, and it fails at setting the original $init['error'] to (in this case) "fail". I was trying to just call $this->index() with perhaps the array as argument, but I can't seem to figure out how I can pass a new $init['error'] which overrides the original one. Actually, while typing this, it seems to impossible to do what I want to do, as the original value will always override anything new.. since I declare it as nothing ('').
So, is there a way to get my error message in there, or not? And if so, how. If not, how would I go about getting my error message in the right spot? (my view: {error}. I've tried stuff with 'global' to bypass the variable scope but alas, this failed. Thanks a lot in advance.
$init musst be modified before generating your view.
To load your header and footer you can include the following command and the footer's equivalent into your view.
<?php $this->load->view('_header'); ?>
to display errors, you can as well use validation_errors()
if you are using the codeigniter form validation.
if you are using the datamapper orm for codeigniter you can write model validations, and if a query fails due to validation rule violation, you get a proper error message in the ->error property of your model.
Code for your model:
var $validation = array(
'user_name' => array(
'rules' => array('required', 'max_length' => 120),
'label' => 'Name'
)
);
You might try this:
function index() {
$init = array(
'base_url' => base_url(),
'title' => 'Login',
'error' => ''
);
$string = $this->parser->parse('include/header', $init, TRUE);
$string .= $this->parser->parse('login/index', $init, TRUE);
$string .= $this->parser->parse('include/footer', $init, TRUE);
$this->parser->parse_string(string);
}
In parse()you can pass TRUE (boolean) to the third parameter, when you want data returned instead of being sent (immediately) to the output class. By the other hand, the method parse_string works exactly like `parse(), only accepts a string as the first parameter in place of a view file, thus it works in conjunction.
my CakePHP (1.2.5.) doesn't validate my form correct.
$this->UserData->save($this->data);
gives me always a true value back. I can't find the problem. The label for UserData.nichname works.
That's the View:
<?php
echo $form->create('UserData');
echo $form->error('UserData.nick_name');
echo $form->input('UserData.nick_name', array('id' => 'UserDatanick_name', 'rule' => 'alphaNumeric', 'label' =>'Nickname:', 'error' =>'false'));
echo $form->end( array( 'label' => ' Save ') );
?>
Here is my Controller:
class UserDatasController extends AppController {
var $name = 'UserDatas';
function add(){
if (!empty ($this->data)){
$this->UserData->create();
if ($this->UserData->save($this->data)){
$this->Session->setFlash('input is valid');
} else {
$this->Session->setFlash('input is not valid');
}
}
}
}
The rules for are not in the model, that's the reaseon i don't post it.
What else is necessary for a validation?
Thanks in advance
Steve
The validation rules have to be defined in the model, not in the view, see also the chapter about data validation in the cakebook.
^^ also check what your files are called.
you have named your model file user_data.php right? and your controller user_data_controller.php?
Note the underscores because of your CamelCasing. If you get the model file name wrong, it wont complain but will instead use a default magic model - which could be why your validation rules within the model didnt get picked up.
I believe you only specify the rules in the model, but the label would be kept in the $form->input() function
Using the Kohana framework, how would you validate a date of birth given 3 separate drop downs? If an error occurs, only one error should show.
you can setup additional custom prefilters and callbacks http://docs.kohanaphp.com/libraries/validation http://docs.kohanaphp.com/libraries/validation are you using ko3 or ko2?
<?
// somewhere in your controller
$form = $_POST;
$form['b_day'] = $form['year'].'-'.$form['month'].'-'.$form['day'];
unset($form['year'], $form['month'], $form['day']);
$orm->validate($form);
// somewhere in your model
public function validate(array & $array, $save = FALSE)
{
$array = Validation::factory($array)
->pre_filter('trim')
->add_rules('b_day', array($this, 'is_good_date'))
;
return parent::validate($array, $save);
}
private function is_good_date($day)
{
return (bool) ($day === 'is ok')
}
Without knowing the Kohana framework, I would probably not validate the first two drop downs, only the third which would take all of the values into consideration.