Attached is a patch that enables client-side full-page redirects from Ajax 
requests. It alters the redirect() function in http.py as well as adding an 
event handler in web2py.js. With it, in a function called via Ajax, you can 
do:

def my_ajax_function():
    if some_condition:
        redirect(URL('default', 'other_function', extension=False), type=
'client')
    return dict()

In that case, redirect does not raise an HTTP(303). Instead, it raises an 
HTTP(200) and sets a special "web2py-redirect-location" response header 
with the redirect URL. On the client side, a jQuery.ajaxSuccess event 
handler checks for that header on every successful Ajax request, and if the 
header is there, it sets window.location to that URL, which loads the full 
page in the browser window. Note, if redirecting from a function called 
with the .load extension, you probably want to set extension=False when 
constructing the redirect URL so the .load extension is not propagated to 
the redirect.

Eventually, we might consider adding a type='internal' option to the 
redirect() function, which could generate a new internal request to the 
redirect URL rather than sending a 303 to the server (this would have 
nothing to do with Ajax -- just a way of speeding up regular server-side 
redirects when you don't need the browser to receive a new URL with the 
redirect).

Anthony

On Wednesday, August 8, 2012 4:58:44 AM UTC-4, mweissen wrote:
>
> Any solution so far?
>
> 2012/7/29 Martin Weissenboeck <mwei...@gmail.com <javascript:>>
>
>> Thank you!
>>
>>
>> 2012/7/28 Massimo Di Pierro <massimo....@gmail.com <javascript:>>
>>
>>> I will take a patch. ;-)
>>>
>>>
>>> On Friday, 27 July 2012 16:54:51 UTC-5, mweissen wrote:
>>>>
>>>> Hallo Johann,
>>>>
>>>> I have tried your proposal - yes, this "workaround" does the job and I 
>>>> think I will use it.
>>>> But I am surprised that there is not simple solution. Or does nobody 
>>>> else want to get rid the "load"?
>>>>
>>>> 2012/7/27 Johann Spies <johann...@gmail.com <javascript:>>
>>>>
>>>>> Hallo Martin, 
>>>>>
>>>>> In stead of redirecting, I am using this script in the view:
>>>>>
>>>>> <script type="text/javascript">
>>>>>     jQuery(document).ready(**function() {
>>>>>                           
>>>>> jQuery($(":input:submit:last")**.addClass('gaanvoort'));
>>>>>
>>>>>                           jQuery($("input.gaanvoort").**click(
>>>>>                               function() {
>>>>>                                   window.location = 
>>>>> "/init/articles/add_article";
>>>>>
>>>>>
>>>>>
>>>>>                                   }));
>>>>>
>>>>>
>>>>>
>>>>>                            });
>>>>>  </script>
>>>>>  
>>>>> and then use session variables on the destination.
>>>>>
>>>>> Regards
>>>>> Johann
>>>>>
>>>>> -- 
>>>>> Because experiencing your loyal love is better than life itself, 
>>>>> my lips will praise you.  (Psalm 63:3)
>>>>>
>>>>

-- 



diff -r 1166e3cd410d applications/welcome/static/js/web2py.js
--- a/applications/welcome/static/js/web2py.js	Tue Aug 07 19:53:42 2012 -0500
+++ b/applications/welcome/static/js/web2py.js	Wed Aug 08 09:00:05 2012 -0400
@@ -44,6 +44,12 @@
   doc.on('keyup', 'input.double, input.decimal', function(){this.value=this.value.reverse().replace(/[^0-9\-\.,]|[\-](?=.)|[\.,](?=[0-9]*[\.,])/g,'').reverse();});
   var confirm_message = (typeof w2p_ajax_confirm_message != 'undefined') ? w2p_ajax_confirm_message : "Are you sure you want to delete this object?";
   doc.on('click', "input[type='checkbox'].delete", function(){if(this.checked) if(!confirm(confirm_message)) this.checked=false;});
+  doc.ajaxSuccess(function(e, xhr) {
+    var redirect=xhr.getResponseHeader('web2py-redirect-location');
+    if (redirect != null) {
+      window.location = redirect;
+    };
+  });
 };
 
 jQuery(function() {
diff -r 1166e3cd410d gluon/http.py
--- a/gluon/http.py	Tue Aug 07 19:53:42 2012 -0500
+++ b/gluon/http.py	Wed Aug 08 09:00:05 2012 -0400
@@ -119,13 +119,16 @@
         return self.message
 
 
-def redirect(location, how=303):
+def redirect(location, how=303, type='http'):
     if not location:
         return
     location = location.replace('\r', '%0D').replace('\n', '%0A')
-    raise HTTP(how,
-               'You are being redirected <a href="%s">here</a>' % location,
-               Location=location)
+    if type == 'client':
+        raise HTTP(200, **{'web2py-redirect-location': location})
+    else:
+        raise HTTP(how,
+                   'You are being redirected <a href="%s">here</a>' % location,
+                   Location=location)
 
 
 

Reply via email to