Redirects with Ajax
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:
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 :-).
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:
Download code
<?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
Comment
1 In plain English
So for those like me, I believe it can be rewritten but still be 'terse' like:
Controller Class:
<?phpfunction 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.
Comment
2 Making it 1.2 ready
Controller Class:
<?phpfunction 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.
Comment
3 Alternative
I would suggest the following:
Or a permutation thereof.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;
}
}
Comment
4 Error
Notice: Undefined property: MyController::$RequestHandler in /home/......
Comment
5 Error Solved
Now it's working fine.....
Comment
6 update for 1.2
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!