问题
I have all my callback functions in My_Controller so that they are not repeated throughout the website. This works fine but for some reason one of my functions is not working when I am posting information using AJAX but is working on other pages. The message I get back when I use the callback is:
Unable to access an error message corresponding to your field name.
But then I've created a message for it using set_message() and it works fine on the other page without AJAX.
If you were interested in the log, here is the relevant output when entering an invalid date:
ERROR - 2013-05-24 16:03:08 --> -----Valid date format called, 223013-05-15
ERROR - 2013-05-24 16:03:08 --> -----Should be okay = , 223013-05-15
ERROR - 2013-05-24 16:03:08 --> -----Valid date format = false, 223013-05-15
And with a valid date:
ERROR - 2013-05-24 16:06:00 --> -----Valid date format called, 2013-05-24
ERROR - 2013-05-24 16:06:00 --> -----Should be okay = , 2013-05-24
ERROR - 2013-05-24 16:06:00 --> -----Valid date format = true, 05,24,2013
Here is the callback:
class MY_Controller extends CI_Controller
{
var $options;
public function __construct()
{
parent::__construct();
date_default_timezone_set('Europe/London');
$this->options->calendar = FALSE;
}
//Check date format aggainst mysql format, valid dates only, no 30-2-2010.
function _Valid_Date_Format($date)
{
log_message('error', '-----Valid date format called, '.$date);
if( empty($date) )
{
$this->form_validation->set_message('_Valid_Date_Format', 'This date is required.');
return FALSE;
}
else
{
log_message('error', '-----Should be okay = , '.$date);
}
$parsed = explode('-',$date);
if( checkdate($parsed[1],$parsed[2],$parsed[0]) )
{
log_message('error', '-----Valid date format = true, '.$parsed[1].','.$parsed[2].','.$parsed[0]);
return TRUE;
}
log_message('error', '-----Valid date format = false, '.$date );
$this->form_validation->set_message('_Valid_Date_Format', 'The Date entered is invalid.');
return FALSE;
}
}
Here is the AJAX Code:
//Submit time feature $("#submit_time").click(function() { var cct = $.cookie('csrf_simple_cookie');//Overcome ajax limitation with csrf function, see below:
$.ajax({
url: folder,
type:"POST",
context: document.body,
data: {t_id:$('#t_id').val(),
time_for:$('#time_for').val(),
hrs_spent:$('#hrs_spent').val(),
mins_spent:$('#mins_spent').val(),
timer_description:$('#timer_description').val(),
date_worked:$('#date_worked').val(),
csrf_simple_collab:cct},
dataType: "json",
error: function(XMLHttpRequest,error)
{
if(error=='parsererror')//Not logged in.
{
window.location.replace(loginFolder)//redirect to login page
}
},
success: function(data)
{
if(data.success)
{
var message=$('#message-box').html('<span>Time data added successfully.</span>').hide();
message.fadeIn("slow");
javascript:location.reload(true);
}
else
{
if(data.validation)
{
//var message=$('#message-box').html("<span>Database error</span>");
var message=$('#message-box').html(data.error);
}
else
{
var message=$('#message-box').html(data.error);
$('#time-for-error').html(data.time_for);
$('#date-worked-error').html(data.date_worked);
$('#mins-spent-error').html(data.mins_spent);
$('#hrs-spent-error').html(data.hrs_spent);
$('#timer-description-error').html(data.timer_description);
}
}
}
});
return false;
});
Here is the view:
<?
//If we are an admin we can alter the user the information is added for.
if($this->session->userdata('userType')=='admin'): ?>
<div class="form_row">
<div class="form_field">
<label for="time_for">User:</label>
</div>
<div class="form_field name_element" id="time-for-container">
<select name="time_for" id="time_for">
<?
foreach($users as $key => $u):
if($u->userId==$this->session->userdata('userId')):
?>
<option selected="selected" value="<?=$u->userId?>"><?=$u->userName?></option> <?='\n'?>
<?
else:
?>
<option value="<?=$u->userId?>"><?=$u->userName?></option> <?='\n'?>
<?
endif;
endforeach;
?>
</select>
<p id="time-for-error"></p>
</div>
</div>
<? else: ?>
<input type="hidden" id="time_for" name="time_for" value="<?=$this->session->userdata('userId')?>">
<? endif; ?>
<div class="form_row">
<div class="form_field">
<label for="hrs_spent">Hours and minutes spent:</label>
</div>
<div class="form_field name_element" id="mins-spent-container">
<input type="text" maxlength="6" name="hrs_spent" id="hrs_spent" value="" />
<span id="min-separator">:</span>
<input type="text" maxlength="6" name="mins_spent" id="mins_spent" value="" />
<p id="mins-spent-error"></p>
<p id="hrs-spent-error"></p>
</div>
</div>
<div class="form_row">
<div class="form_field">
<label for="date_worked">Date Worked:</label>
</div>
<div class="form_field name_element" id="date-picker-container">
<input type="text" name="date_worked" id="date_worked" />
<p id="date-worked-error"></p>
</div>
</div>
<div class="form_row">
<div class="form_field">
<label for="timer_description">Description:</label>
</div>
<div class="form_field name_element" id="description-container">
<textarea name="timer_description" id="timer_description" value=""></textarea>
<p id="timer-description-error"></p>
</div>
</div>
<input type="hidden" id="c_id" name="c_id" value="<?=$task->c_id ?>" />
<input type="hidden" id="p_id" name="p_id" value="<?=$task->p_id ?>" />
<input type="hidden" id="t_id" name="t_id" value="<?=$task->t_id ?>" />
<input type="hidden" name="login-folder" id="login-folder" value="<?=base_url()?>login" />
<input type="hidden" name="submit-folder" id="submit-folder" value="<?=base_url()?>times/submit_time" />
<div class="form_row">
<div id="message-box"></div>
<input type="button" name="submit" id="submit_time" class="button-styles button-three" value="Add time" />
</div>
</div>
Controller method:
class Times extends MY_Controller { var $options;
//Ajax function used to submit the time information from task page form.
function submit_time()
{
$options=array();
$this->form_validation->set_rules("time_for","Time for","trim|required|is_natural_no_zero");
$this->form_validation->set_rules("hrs_spent","Hrs spent","trim|required|is_natural|min_length[1]|max_length[5]");
$this->form_validation->set_rules("mins_spent","Mins spent","trim|required|is_natural|min_length[1]|max_length[2]|less_than[60]");
$this->form_validation->set_rules("timer_description","Description","trim|min_length[5]|max_length[1000]");
$this->form_validation->set_rules("date_worked","Date Worked","trim|required|callback__valid_date_format");
//$json->data=array('success'=>0,'validation'=>1,'error'=> validation_errors() );
//$this->load->view('data/json_encode',$json);
if($this->form_validation->run())
{
$options['hrs_spent'] = $this->input->post('hrs_spent');
$options['mins_spent'] = $this->input->post('mins_spent');
$options['timer_description'] = $this->input->post('timer_description');
$options['date_worked'] = $this->input->post('date_worked');
$options['t_id'] = $this->input->post('t_id');
$options['u_id'] = $this->input->post('time_for');//Notice time for field here.
$add = $this->time_model->add_time($options);
if(!$add):
$json->data=array('success'=>0,'validation'=>1,'error'=>'Database error');
else:
$json->data=array('success'=>1,'validation'=>1);
$this->log_model->add_log_entry( array('log_id'=>1,'item'=>'Time record "'.reduce_string($options['timer_description'],50).'" was added for user '.$options['u_id'].'.') );
endif;
$this->load->view('data/json_encode',$json);
}
else
{
$json->data = array(
'time_for' => form_error('time_for'),
'hrs_spent' => form_error('hrs_spent'),
'mins_spent' => form_error('mins_spent'),
'timer_description' => form_error('timer_description'),
'date_worked' => form_error('date_worked'),
'success'=>0,
'validation'=>0,
'error'=>'There are errors in the form.'
);
$this->load->view('data/json_encode',$json);
}
}
}
回答1:
The problem is the capitalization used in the callback method name. The method name, and all subsequent references to it as a validation rule, should be all lowercase.
To explain, this is the relevant part of the Form Validation library that causes the message:
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];
}
All of your set_message()
calls name the rule as _Valid_Date_Format
, which is the array key that exists in $this->_error_messages
.
Because your rule is defined as _valid_date_format
, and because PHP is case-sensitive most of the time, the isset()
rule fails, and you clearly don't have a language line defined for it, so it goes to the default.
In general, using capitalization in your controller methods will cause problems. So it's best to avoid doing so.
来源:https://stackoverflow.com/questions/16738179/codeigniter-2-callback-function-in-my-controller