Use custom headers for AJAX forms and redirects

The way it was done before was to load the whole redirected page, then read
from a DIV in the page and redirect to that URL. This now just sends a header
when the form was called via the JS function form_modal_dialog() and no errors
are present.
This commit is contained in:
Roland Geider
2015-01-07 22:54:19 +01:00
parent 7c515e6d31
commit 74d1944836
4 changed files with 46 additions and 31 deletions

View File

@@ -304,36 +304,30 @@ function modal_dialog_form_edit() {
jqXHR.setRequestHeader("X-wger-no-messages", "1");
},
success: function (data, textStatus, jqXHR) {
if ($(data).find('form .has-error').length > 0) {
// we must do the same with the new form as before, binding the click-event,
// checking for errors etc, so it calls itself here again.
$("#ajax-info-content form").html($(data).find('form').html());
$("#ajax-info-title").html($(data).find("#page-title").html());
modal_dialog_form_edit();
} else {
$("#wger-ajax-info").modal("hide");
// If there was a redirect we must change the URL of the browser. Otherwise
// a reload would not change the adress bar, but the content would.
// Since it is not possible to get this URL from the AJAX request, we read it out
// from a hidden HTML DIV in the document...
var current_url = $(data).find("#current-url").data('currentUrl');
// TODO: There seems to be problems sometimes when using the technique below and
// bootstrap's menu bar (drop downs won't open). So just do a normal
// redirect.
window.location.href = current_url;
var url = jqXHR.getResponseHeader('X-wger-redirect');
if (url) {
window.location.href = url;
/*
if(document.URL.indexOf(current_url))
{
history.pushState({}, "", current_url);
if(document.URL.indexOf(url)) {
history.pushState({}, "", url);
}
*/
}
else {
if ($(data).find('form .has-error').length > 0) {
// we must do the same with the new form as before, binding the click-event,
// checking for errors etc, so it calls itself here again.
$("#ajax-info-content form").html($(data).find('form').html());
$("#ajax-info-title").html($(data).find("#page-title").html());
modal_dialog_form_edit();
}
else {
console.log('No X-wger-redirect found but also no .has-error!');
$("#wger-ajax-info").modal("hide");
$("#ajax-info-content form").html(data);
}
// Note: loading the new page like this executes all its JS code
//$('body').html(data);
}
// Call other custom initialisation functions

View File

@@ -1,7 +1,7 @@
{% load i18n %}
{% if form.is_bound and not form.is_valid or form.non_field_errors or form.non_form_errors %}
<div class="alert alert-danger">
<div class="alert alert-danger has-error">
{% blocktrans %}The form contains errors. Please verify and correct the
data in the fields in red and submit the form again.{% endblocktrans %}

View File

@@ -92,6 +92,9 @@ MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
# Javascript Header. Sends helper headers for AJAX
'wger.utils.middleware.JavascriptAJAXRedirectionMiddleware',
# Custom authentication middleware. Creates users on-the-fly for certain paths
'wger.utils.middleware.WgerAuthenticationMiddleware',

View File

@@ -13,10 +13,7 @@
# You should have received a copy of the GNU Affero General Public License
'''
Custom authentication middleware.
This is basically Django's AuthenticationMiddleware, but creates a new temporary
user automatically for anonymous users.
Custom middleware
'''
import logging
@@ -107,3 +104,24 @@ class RobotsExclusionMiddleware(object):
return response
else:
return response
class JavascriptAJAXRedirectionMiddleware(object):
'''
Middleware that sends helper headers when working with AJAX.
This is used for AJAX forms due to limitations of javascript. The way it
was done before was to load the whole redirected page, then read from a DIV
in the page and redirect to that URL. This now just sends a header when the
form was called via the JS function form_modal_dialog() and no errors are
present.
'''
def process_response(self, request, response):
if request.META.get('HTTP_X_WGER_NO_MESSAGES') and b'has-error' not in response.content:
logger.debug('Sending X-wger-redirect')
response['X-wger-redirect'] = request.path
response.content = request.path
return response