Previous Page
Next Page

12.6. Login Component

The login component provides a login form and a logout form to the ticket manager application. This form is displayed on the sidebar and is always present. Besides providing the user interface in the sidebar, the login component provides hooks for other components to be login aware. This is done by hiding and showing elements that have specific CSS classes. Elements with the loggedOut class are shown only when the user is logged out, and elements with the loggedIn class are shown only when the user is logged in. The login user interface is shown in logged-out mode in Figure 12-8. It is shown in logged-in mode in Figure 12-9. The HTML that creates the login is shown in Listing 12-9.

Figure 12-8. User is logged out; the login component shows a login form

Figure 12-9. User is logged in; the login component shows a Logout button

Listing 12-9. Login.php

1 <div id="login">
2 <form onsubmit="return login(this)" class="loggedOut">
3   <h3>Login</h3>
4   <p id="loginMessage"></p>
5   <p><label>Username:
6   <input name="username">
7   </label></p>

8   <p><label>Password:
9   <input name="password" type="password">
10   </label></p>
11   <p><input type="submit" value="Login">
12   </p>
14   <a href="javascript:selectSection('register')"
15   >Register</a>
16 </form>
17 <form onsubmit="return logout(this)" class="loggedIn">
18   <p>Logged in as:
19   <span id="loginUsername">
20   <?php echo $app->profile('username'); ?>
21   </span>
22   </p>
23   <p>
24   <input type="submit" value="Logout">
25   </p>
27   <a href="javascript:selectSection('editAccount')"
28   >Update Account</a>
29 </form>
30 </div>

The login component is made up of two parts; the first, Login.php, provides the simple login user interface. The second, Login.js (shown in Listing 12-10), provides the JavaScript logic to power it. The entire interface is created at load time, with parts of it being shown or hidden as needed. There isn't a lot happening here; first the form for logging in is created (lines 216), and then the form for logging out (lines 1729) is created. Both forms are processed through the addition of onsubmit handles; these handles will stop the normal form submission processes and instead perform an AJAX call. The login form contains a message target (line 4) that is used with the setMessage function (from Ticket.js) to display a login failure message. The login form also contains a link to the user registration form, which uses the selectSection function (line 14), whereas the logout form contains a link to the account editing form (line 27), which also uses selectSection.

Listing 12-10. Login.js

1 var loginSetup = function() {
2   // Enable logged in sections of components
3   var li = 'none';
4   var lo = 'block';
5   if (app.isLoggedIn) {
6     li = 'block';
7     lo = 'none';
8   }
9   var els = byClass('loggedIn');
10   for(var i = 0; i < els.length; i++) {
11     if (els[i].tagName == 'SPAN' && li == 'block') {
12       els[i].style.display = 'inline';
13     }
14     else {
15       els[i].style.display = li;
16     }
17   }
18   var els = byClass('loggedOut');
19   for(var i = 0; i < els.length; i++) {
20     if (els[i].tagName == 'SPAN' && li == 'block') {
21       els[i].style.display = 'inline';
22     }
23     else {
24       els[i].style.display = lo;
25     }
26   }
27 }
28 app.setup.push(loginSetup);
30 var callback = {
31   login: function(result) {
32     loginComplete(result);
33   },
34   logout: function(result) {
35     logoutComplete(result);
36   }
37 }
38 var rLogin = new Ticket(callback);
40 // login component js
41  function login(form) {
42    var username = form.elements.username.value;
43    var password = form.elements.password.value;
45    rLogin.login(username,password);
47    var div = document.createElement('div');
48    div.className = 'overlay';
49    form.appendChild(div);
50    Element.setOpacity(div,.3);
51    positionOver(div);
52    form.overlay = div;
54    return false;
55 }
56 function loginComplete(result) {

57   var els = byClass('loggedOut',byId('login'));
58   var form = els[0];
59   form.removeChild(form.overlay);
61   if (result) {
62     app.profile = result;
63     app.isLoggedIn = true;
64     byId('loginUsername').innerHTML =
65             app.profile.username;
67     loginSetup();
68     selectSection('mytickets');
69   }
70   else {
71     setMessage(byId('loginMessage'),'Login Failed');
72   }
73   new Effect.Highlight('login');
74 }
76 function logout() {
77   rLogin.logout();
78   return false;
79 }
81  function logoutComplete(result) {
82    app.isLoggedIn = false;
83    app.profile = {};
84    loginSetup();
86    for(var i = 0; i < app.logout.length; i++) {
87      app.logout[i]();
88    }
90    selectSection('front');
91    new Effect.Highlight('login');
92 }

The Login.js file provides the functionality behind the login component, processing the forms provided by the user interface and hiding and showing elements as needed. The first part of Login.js is the setup logic; this is composed of the loginSetup function, which will be run at page load, and the creation of a remote AJAX class for accessing the back end. The Setup function (lines 127) works by checking whether the user is logged in (line 5) and setting the appropriate style.display value for the logged in case (variable li, line 6) and the logged out case (variable lo, line 7). Once these are set, it's just a matter of using the byClass function to get a list of all the elements with the loggedIn class (line 9), looping over them (lines 1017), and setting each element's style.display property. During this process, we also check for span elements because they need to be given the display property of inline, instead of the display property of block. This process is then repeated for elements with the loggedOut class (lines 1827), with the style properties being set to the opposite values. Once the setup function is defined, it is added to the app.setup array, which will run the loginSetup function on page load.

Next, the AJAX stub class is set up. This class is provided by HTML_AJAX and will call the matching callback function to the method that is called when an asynchronous request is completed. Thus, in the setup process, we define the callback functions (lines 3037) for the methods that this component needs. To increase readability, these callback functions are kept simple and just call out to other functions that do the real work. An instance of the Ticket stub class is created on line 38; this instance will be used for all AJAX access in the component.

Next, we define the two login functions. First login() is defined; it processes the form and sends an AJAX request. Then, loginComplete() is defined; it takes the results from the AJAX call and updates the user interface. The login function starts by grabbing the username and password from the form (lines 4243); it then makes an AJAX call (line 45), which performs the login on the server. The rest of the function adds loading notification; this is done by creating a semi-opaque div, which is added to the form and then positioned over it using the positionOver function defined in Ticket.js.

When the AJAX request is complete, loginComplete is run; the result is either false or an array containing the user's profile. The function removes the loading overlay (lines 5759) and then checks the value of the result. If the result is an object containing the profile, app.profile and app.login are set (lines 6263), the logout form has the user's username added to it (lines 6465), and the loginSetup function is called (line 67). The loginSetup function will show all the elements that have a loggedIn class, hiding those with the loggedOut class. The successful login is completed by showing the mytickets section of the application. If the login is unsuccessful, the only action that is taken is the showing of a Login Failed message with the setMessage function. In either case, a scriptaculous highlight effect is used to show that loading has completed and that the login component on the screen has updated its contents.

The last part of Login.js contains the logout() function and its callback function, which is logoutComplete(). The logout process is simpler than the login process because it can't fail. The logout function (lines 7679) simply calls the rLogin.logout method, making the AJAX request. It then returns false, canceling the normal form submission. LogoutComplete (lines 8192) is called when the logout is complete on the server; it clears the user's profile, marks the user as logged out, and then calls the loginSetup function to show and hide any login-driven visual elements. Next the function calls all the registered logout functions. These work much like setup functions and give the other modules a chance to run code once a logout is complete; usually this code clears data that should be accessible only when the user is logged in. The function finishes by changing the current section to the front page and highlighting the login form to show that it has been changed to a login form.

Previous Page
Next Page