Redirects with Ajax

This article is also available in the following languages:
By sunertl
Redirects with Ajax are not really simple to do. When you redirect within the same controller, you can use setAction() instead but what if you want to redirect to another controller? I figured out a quite simple way using sessions, postet it - and got back the IMHO perfect solution by gwoo.
Cakebaker already wrote two times about redirecting with Ajax:
http://cakebaker.42dh.com/2006/03/15/redirect-with-ajax/ http://cakebaker.42dh.com/2006/03/28/a-simple-redirect-component/ He does it using a client-side redirect with javascript. I don't like client-side solutions as it is something I cannot controll. I figured out a way using session (storing the desired layout in a session, then redirect and load the layout according to the stored layout) but gwoo showed me a much more efficient way:

Simply override the default redirect-method in the appcontroller by using:

Controller Class:

<?php 
function redirect($url$status null){
    
$ajax = ($this->RequestHandler->isAjax())
    ? (
$url{0} != '/') ? '/ajax/' '/ajax' null;
    
parent::redirect($ajax.$url$status);
}
?>

you are done!

Be careful if this solution conflicts in any way with your custom routings. But in most cases it will work perfektly.

using this way does not even require you to change any code written already :-).

Comments

  • Posted 11/09/10 07:43:59 PM
    i fixed the () to {}, but now I get "AjaxcController could not be found"
  • Posted 08/07/07 08:13:41 AM
    i found out, that in 1.2 there are arrays use in the redirects. so i updated the function a little bit:


    function redirect($url, $status = null, $exit = false) {
        $temp = $url;
        if(is_array($url)) {
            $temp = '/';
            $temp .= isset($url['controller']) ? $url['controller'] : $this->params['controller'];
            $temp .= '/';
            $temp .= isset($url['action']) ? $url['action'] : $this->params['action'];
            $url = '';
        }
        $ajax = ($this->RequestHandler->isAjax()) ? ($temp{0} != '/') ? '/ajax/' : '/ajax' : null;
        parent::redirect($ajax.$temp, $status, $exit);
    }

    i do not know if it is a really nice solution but it works quite good for me. further improvements are welcome!
    • Posted 11/09/10 10:21:41 AM
      This ALMOST works for me in cakephp 1.2, but I get an undefined function error /users/login(). I think it's because of the trailing parantheses. Can we remove them?



      [quote] i found out, that in 1.2 there are arrays use in the redirects. so i updated the function a little bit:


      function redirect($url, $status = null, $exit = false) {
          $temp = $url;
          if(is_array($url)) {
              $temp = '/';
              $temp .= isset($url['controller']) ? $url['controller'] : $this->params['controller'];
              $temp .= '/';
              $temp .= isset($url['action']) ? $url['action'] : $this->params['action'];
              $url = '';
          }
          $ajax = ($this->RequestHandler->isAjax()) ? ($temp{0} != '/') ? '/ajax/' : '/ajax' : null;
          parent::redirect($ajax.$temp, $status, $exit);
      }

      i do not know if it is a really nice solution but it works quite good for me. further improvements are welcome!
      [end quote]
  • Posted 04/25/07 09:53:42 PM
    Sorry, i forgot to include the RequestHandler component......
    Now it's working fine.....
  • Posted 04/25/07 09:31:44 PM
    I got this error...

    Notice: Undefined property: MyController::$RequestHandler in /home/......
  • Posted 11/30/99 12:00:00 AM
    I'm easily confused by the terse language constructs when it's singular. Nest it like that and I'm really lost! :)

    So for those like me, I believe it can be rewritten but still be 'terse' like:

    Controller Class:

    <?php 
    function redirect($url$status null) {
        if (
    $this->RequestHandler->isAjax()) {
            
    $url '/ajax/'.ltrim($url'/');
        }
        
    parent::redirect($url$status);

    ?>

    And thanks for this! It's exactly what I'm looking for. Now redirect fixes happen without any change to the code.
  • Posted 11/30/99 12:00:00 AM
    Also, the api is a bit different for 1.2. It now takes a third parameter, so be sure to pass that through:

    Controller Class:

    <?php 
    function redirect($url$status null$exit false) {
    ...
        
    parent::redirect($url$status$exit);
    }
    ?>

    Since it's adding a param with a set default, it should work just fine in 1.1.x as well, but the third param will just be ignored.
  • Posted 11/30/99 12:00:00 AM
    Hi,

    I would suggest the following:

    function redirect($url, $status = null, $die = true) {
        if ($this->RequestHandler->isAjax() || isset ($this->params['requested'])) {
            echo $this->requestAction($url, array (
                    'return'
                ));
        } else {
            parent :: redirect($url, $status);
        }
        if ($die) {
            die;
        } else {
            return false;
        }
    }
    Or a permutation thereof.

Comments are closed for articles over a year old