views:

466

answers:

3

Hello,

I'm a heavy Codeignitor user and currently I have to build a page with extensive AJAX bits and pieces. I have been using JQuery all along the website and it's AJAX handling was perfect up until now. There is something that just doesn't feel right when i use a MVC with JQuery. For example: in Jquery I setup the callback URL easily that point to the controller, the controler then calls a view page and the AJAX is displayed but this view page is very small PHP code. So now I have about 40 ajax function to do in my page, would that mean I would have to make 40 views?? that doesn't seem right to me. Is there any better way to handle/manage the views created for the AJAX in MVC Frameworks

Thank you.

+2  A: 

You could create one view, e.g. ajax.php and set the content accordingly in the methods of the controllers. All methods can use the same view.

The above is only true for similar views, but if the methods are similar as well, then you should think about refactoring your code to using uri parameters, see my answer to a question on how to get parameters from the url.

But all that depends on the nature of the controllers, their methods and the related views.

EDIT:

I do not advise you to use HTML in the controller, but lay out your controller like this:

Class My_Controller
{
    // some other methods
    public function edit_via_ajax($type, $value)
    {
        /* do some stuff with $type and $value,
           sanitize user input etc. 
           set $status to TRUE or FALSE */
        $data['type'] = $type;
        $data['value'] = $value;
        if ($status === TRUE)
        {        
            $this->load->view('success.php', $data);
        }
        else
        {        
            $this->load->view('error.php', $data);
        }
    }
}

Create views like success.php

<?=$type;?> was successfully set to <?=$value;?>

And call it via $.get('/index.php/my_controller/edit_via_ajax/name/John_Doe'); in jquery to edit the name. In that way, lots of similar AJAX requests can share the same method and methods can share views.

Residuum
I'm somehow trying to avoid writing HTML in controllers (for a lot of reasons). For example Sajax had the ability to write all the returned AJAX in one file and they were stored in functions. It was just one page with a lot of function, so instead of having 40 PHP pages, you end up with 1 page with 40 functions.I was hoping to have something similar in CI with JQuery.
bhefny
@bhefny: See my edit for the general idea.
Residuum
A: 

There is no requirement that an AJAX request must use a view in CI. Your controller methods do not have to return a view whatsoever, merely some form of echoed data. If some of your views are very small, or only require a minimum amount of HTML (you can decide what minimum might be), you could simply do one of the following:

public function controllerMethod1() {
    $str = '<strong>some html</strong><br />';
    $str .= '<p>and some more</p>';
    die($str);
}

You can still go about your usual, handling post requests in the model and simply use string identifiers to determine whether database updates are successful or erroneous:

public function controllerMethod2() {
    if ($this->model->addToDatabase(...)) {
        die('success');
    }
    die('error');
}
cballou
die() is not a good practice in PHP, see http://stackoverflow.com/questions/1186957/common-programming-mistakes-for-php-developers-to-avoid/1187082#1187082
Residuum
@Residuum, although abrupt, die/exit is not necessarily bad in the event you use them in a manner which has no adverse affect on any remaining code that might need to be executed (AJAX being the prime example, which only wants you to spit back a string).
cballou
Yes of course but I (personally) don't want to be writing HTML in the controller, it's not a good MVC practice plus with HUGE Ajax pages there is no point writing 150 lines of HTML in <?php echo '....';?>
bhefny
A: 

This is what I have reached so far to have one controller and one view. Is there anything better that could be done?

    /*Controller*/
class C_ajax extends Controller {

    function fn_name(){
        $data['ajaxType'] = __FUNCTION__;
        // write any code here to be passed

        $this->load->view('news/v_news_ajax', $data);
    }
}
/*View*/

<?php
    switch($ajaxType):
        case 'fn_name':?>
            //write HTML here

        <?php break;?>
        <?php case '':?>
            // write HTML for another view here
        <?php break;?>

    <?php endswitch;?>
bhefny
It is a possibility, but if that is the layout for the full application, distinct views with appropriate includes would be a better approach, but you can refactor your code to that later on. I personally prefer to start with distinct views and then abstract and combine the views / controller methods.
Residuum