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>