Mercurial > public > sg101
changeset 500:886cc99e8406
For #240, add an "ajaxy" login via a jQuery UI pop-up dialog to streamline the login process.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sat, 03 Dec 2011 02:48:18 +0000 |
parents | 1a09a7bea000 |
children | 0ac39f006eb2 |
files | gpp/accounts/static/js/ajax_login.js gpp/accounts/urls.py gpp/accounts/views.py gpp/templates/accounts/ajax_login_form.html gpp/templates/base.html gpp/templates/navbar.html |
diffstat | 6 files changed, 134 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpp/accounts/static/js/ajax_login.js Sat Dec 03 02:48:18 2011 +0000 @@ -0,0 +1,54 @@ +$(function() { + var loginError = $('#login-error'); + var loginDialog = $('#login-dialog').dialog({ + autoOpen: false, + height: 355, + width: 380, + modal: true, + buttons: { + "Login": function() { + loginError.text('').hide(); + $.ajax({ + url: '/accounts/login/ajax/', + type: 'POST', + data: { + username: $('#id_username').val(), + password: $('#id_password').val() + }, + dataType: 'json', + success: function(data, textStatus) { + if (data.success) { + loginDialog.dialog("close"); + if (window.location.pathname == "/accounts/logout/") { + window.location.replace("/"); + } + else { + $('#header-nav').html(data.navbar_html); + } + } + else { + loginError.text(data.error).show(); + } + }, + error: function (xhr, textStatus, ex) { + if (xhr.status == 403) { + loginDialog.dialog("close"); + alert("Oops, we are detecting some strange behavior and are blocking this action. If you feel this is an error, please feel free to contact us. Thank you."); + } + else { + loginError.text('Oops, an error occurred. If this problem persists, please contact us.').show(); + } + } + }); + }, + "Cancel": function() { + loginDialog.dialog("close"); + } + } + }); + $('#login-link').click(function() { + loginError.text('').hide(); + loginDialog.dialog("open"); + return false; + }); +});
--- a/gpp/accounts/urls.py Wed Nov 30 02:41:18 2011 +0000 +++ b/gpp/accounts/urls.py Sat Dec 03 02:48:18 2011 +0000 @@ -3,6 +3,7 @@ from django.conf import settings urlpatterns = patterns('accounts.views', + url(r'^login/ajax/$', 'login_ajax', name='accounts-login_ajax'), url(r'^register/$', 'register', name='accounts-register'), (r'^register/thanks/$', 'register_thanks'), (r'^register/confirm/(?P<username>[\w.@+-]{1,30})/(?P<key>[a-zA-Z0-9]{20})/$', 'register_confirm'),
--- a/gpp/accounts/views.py Wed Nov 30 02:41:18 2011 +0000 +++ b/gpp/accounts/views.py Sat Dec 03 02:48:18 2011 +0000 @@ -1,14 +1,20 @@ -"""views for the accounts application""" +""" +Views for the accounts application. +""" import datetime import logging from django.shortcuts import render_to_response from django.template import RequestContext +from django.template.loader import render_to_string from django.contrib.auth.models import User -from django.http import HttpResponseRedirect +from django.http import HttpResponse, HttpResponseRedirect from django.core.urlresolvers import reverse from django.conf import settings +from django.contrib.auth.forms import AuthenticationForm +from django.contrib.auth import login +from django.utils import simplejson from accounts.models import PendingUser from accounts.forms import RegisterForm @@ -78,3 +84,33 @@ 'username': username, }, context_instance = RequestContext(request)) + +####################################################################### + +@rate_limit(count=10, interval=datetime.timedelta(minutes=1)) +def login_ajax(request): + """ + This view function handles a login via AJAX. + + """ + if not request.is_ajax(): + return HttpResponseRedirect(reverse('accounts-login')) + + response = { + 'success': False, + 'error': '', + 'navbar_html': '' + } + + if request.method == "POST": + form = AuthenticationForm(data=request.POST) + if form.is_valid(): + login(request, form.get_user()) + response['success'] = True + response['navbar_html'] = render_to_string('navbar.html', + {'user': request.user}, RequestContext(request)) + else: + response['error'] = 'Invalid username or password' + + return HttpResponse(simplejson.dumps(response), + content_type='application/json')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpp/templates/accounts/ajax_login_form.html Sat Dec 03 02:48:18 2011 +0000 @@ -0,0 +1,17 @@ +{% load url from future %} +<div id="login-dialog" title="SurfGuitar101 Login"> + <p id="login-error" class="error"></p> + <form> + <fieldset> + <label for="id_username">Username:</label> + <input id="id_username" type="text" name="username" maxlength="30" class="text" /><br /> + <label for="id_password">Password:</label> + <input type="password" name="password" id="id_password" class="text" /> + </fieldset> + </form> +<ul> +<li>Forgot your password? You can reset it <a href="{% url 'accounts-password_reset' %}">here</a>.</li> +<li>Don't have an account? Why don't you <a href="{% url 'accounts-register' %}">register</a>?</li> +<li>Having problems? Please <a href="{% url 'contact-form' %}">contact us</a>.</li> +</ul> +</div>
--- a/gpp/templates/base.html Wed Nov 30 02:41:18 2011 +0000 +++ b/gpp/templates/base.html Sat Dec 03 02:48:18 2011 +0000 @@ -9,7 +9,6 @@ {% load shoutbox_tags %} {% load irc_tags %} {% load potd_tags %} -{% load messages_tags %} {% load script_tags %} {% load poll_tags %} {% load core_tags %} @@ -35,6 +34,10 @@ <script type="text/javascript" src="{{ STATIC_URL }}js/jquery.cycle.all.min.js"></script> <script type="text/javascript" src="{{ STATIC_URL }}js/shoutbox.js"></script> <link rel="shortcut icon" type="image/vnd.microsoft.com" href="{{ STATIC_URL }}favicon.ico" /> +{% if not user.is_authenticated %} +{% script_tags "jquery-ui" %} +<script type="text/javascript" src="{{ STATIC_URL }}js/ajax_login.js"></script> +{% endif %} </head> <body>{% block begin_body %}{% endblock %} <div id="page" class="container"> @@ -42,18 +45,7 @@ <p><a href="/" title="SG101 Home"><img src="{{ STATIC_URL }}themes/kds/sgLogo.png" alt="SurfGuitar101.com Logo" width="446" height="103" /></a></p> </div> <div id="header-nav" class="span-24"> - <ul> - {% if user.is_authenticated %} - <li>Welcome, <a href="{% url 'bio-me' %}">{{ user.username }}</a></li> - <li><a href="{% url 'forums-index' %}">Forums</a></li> - <li>{% unread_messages user %}</li> - <li><a href="{% url 'haystack_search' %}">Search</a></li> - <li><a href="{% url 'accounts-logout' %}">Logout</a></li> - {% else %} - <li><a href="{% url 'accounts-login' %}">Login</a></li> - <li><a href="{% url 'accounts-register' %}">Register</a></li> - {% endif %} - </ul> + {% include "navbar.html" %} </div> <div id="content-secondary" class="span-4 append-1"> @@ -120,6 +112,10 @@ music alive.</p> </div> -</div>{% block end_body %}{% endblock %} +</div> +{% if not user.is_authenticated %} + {% include "accounts/ajax_login_form.html" %} +{% endif %} +{% block end_body %}{% endblock %} </body> </html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpp/templates/navbar.html Sat Dec 03 02:48:18 2011 +0000 @@ -0,0 +1,14 @@ +{% load url from future %} +{% load messages_tags %} +<ul> + {% if user.is_authenticated %} + <li>Welcome, <a href="{% url 'bio-me' %}">{{ user.username }}</a></li> + <li><a href="{% url 'forums-index' %}">Forums</a></li> + <li>{% unread_messages user %}</li> + <li><a href="{% url 'haystack_search' %}">Search</a></li> + <li><a href="{% url 'accounts-logout' %}">Logout</a></li> + {% else %} + <li><a id="login-link" href="{% url 'accounts-login' %}">Login</a></li> + <li><a href="{% url 'accounts-register' %}">Register</a></li> + {% endif %} +</ul>