I was happily coding, thinking I'd not run into problems anymore (for now, at least), until I came to the AJAX part of my application.
First, a bit of background. I'm working on a calendar/planner app. My controller loads data (a rather complex array) from a model and passes it to a view in my index() function. All good till there. Now, I want to update my data through ajax. I'm showing a bunch of dates, and when the user clicks on the 'previous' or 'next' buttons, I want to show the previous/next month.
I've been able to do this in the past with super-messy and plain bad code. I rewrote my code from scratch now, but now I'm stuck. I have an AJAX call to the following function:
public function change_dates()
{
$month = $this->input->post('month');
$year = $this->input->post('year');
$dates = $this->planner_model->create_date_list($month, $year);
// echo $dates back to ajax? :(
}
I take the post values, send them to my model, save the data in an array and then I'm stuck. Because the data array is complex, I have a foreach loop, among other things, in my view. If I j开发者_JS百科ust echo it back to my view's ajax call, I can't really do anything with it. It's not like I can use .html()
here to get my data in my view. I need a way to update the whole array in my view with the new values, if that makes sense? I tried stuff like $this->load->vars()
but I'm a bit of a newbie and I don't even know if that's the right way of doing this, haha.
Thanks in advance.
The easy, reliable way:
Make sure your page uses $this->load->view()
to load a view fragment (the html that creates the calendar) separately from your header, footer, etc.
When you make the AJAX call to change_dates()
, have it do it's thing, then load only that view file, passing the new data with $this->load->vars()
or $this->load->view('calendar', $data)
. If you need to only load the view if it is an AJAX request, just detect the AJAX call:
public function change_dates()
{
$month = $this->input->post('month');
$year = $this->input->post('year');
$dates = $this->planner_model->create_date_list($month, $year);
if ($this->input->is_ajax_request()) // Available as of CI 2.0
{
$data['dates'] = $dates;
$this->load->view('calendar', $data);
// You may need to load other data here, If so, consider a common function that
// can be shared with your main view to render the calendar
}
}
In your jQuery, you will be expecting html as a return value. Simply take the value and load it into your div or wherever the calendar is shown with the html() or load() jQuery functions. You're basically just reloading the entire thing, which ensures you are getting the correct output.
$.get(url, function(response) {
$('#main_content').html(response);
}, 'html');// will usually use auto detection
// Or when you KNOW you're expecting HTML
$('#main_content').load(url);
// Or without the ajax detect (slower, less recommended)
$('#main_content').load(url + ' #main_content');
The precise, difficult way:
Use above methods, but echo/exit json_encode() the data into whatever form you need, then make sure to expect a json return value from your jQuery. You will now get an array that you can manipulate the document with however you choose.
If you are on an older version than 2.0 - It's time to upgrade!, but here is the function they use for ajax detection (not much to it):
public function is_ajax_request()
{
return ($this->server('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest');
}
精彩评论