Using custom login page with Worklight and JQuery Mobile

In the How to enable form based authentication in worklight application entry i talked about the steps that you must follow to enable the Form based authentication in the Worklight application, so that as soon as user logs in he gets prompted for the user name and password and once he logs in then he sees the application page. I wanted to try this with jQuery Mobile, basic idea is that i will have multi page application with jQuery Mobile and then it will also have a login page, so when user visits the application for the first time he see's the login page and after login user can go to the Home page and traverse across different pages. This is how my login page looks like
Once user is logged in he will see the application page like this, there is logout button in the footer that let's user go back to login page. I followed these steps to build my application
  1. First i did follow the steps described in the How to enable form based authentication in worklight application entry to enable the Form based authentication for the user.
  2. Then i did change my html page to look like this, I am using CDN version of the jQuery Mobile so i dont have to manually add the necessary css and JavaScript in my project
    
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport"
      content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0" />
    <title>JQMLogin</title>
    <link rel="shortcut icon" href="images/favicon.png" />
    <link rel="apple-touch-icon" href="images/apple-touch-icon.png" />
    <link rel="stylesheet" href="css/reset.css" />
    <link rel="stylesheet"
      href="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.css" />
    </head>
    <body onload="WL.Client.init({})" id="content" style="display: none">
    
      <div data-role="page" id="page1">
        <div data-theme="a" data-role="header">
          <h3>Autenticated Page - Page1</h3>
        </div>
        <div data-role="content">
          <h3>You are logged in -Page1</h3>
          <a href="#page2">Go to page2</a>
        </div>
        <div data-theme="a" data-role="footer">
          <input type="button" value="Logout" 
          onclick="WL.Client.logout('SampleAppRealm', {onSuccess:  WL.Client.reloadApp});" />
        </div>
      </div>
      <div data-role="page" id="page2">
        <div data-theme="a" data-role="header">
          <h3>Autenticated Page - Page2</h3>
        </div>
        <div data-role="content">
          <h3>You are logged in -Page2</h3>
          <a href="#page3">Go to page3</a>
        </div>
        <div data-theme="a" data-role="footer">
          <input type="button" value="Logout" 
          onclick="WL.Client.logout('SampleAppRealm', {onSuccess:  WL.Client.reloadApp});" />
        </div>
      </div>
      <div data-role="page" id="page3">
        <div data-theme="a" data-role="header">
          <h3>Autenticated Page - Page3</h3>
        </div>
        <div data-role="content">
          <h3>You are logged in -Page3</h3>
          <a href="#page1">Go to page1</a>
        </div>
        <div data-theme="a" data-role="footer">
          <input type="button" value="Logout" 
          onclick="WL.Client.logout('SampleAppRealm', {onSuccess:  WL.Client.reloadApp});" />
        </div>
      </div>
      <div data-role="page" id="loginPage">
        <div data-theme="a" data-role="header">
          <h3>Hello JQuery Mobile</h3>
        </div>
        <div data-role="content">
          <div id="loginForm">
            Username:<br/>
            <input type="text" id="usernameInputField" autocorrect="off" autocapitalize="off" /><br />
            Password:<br/>
            <input type="password" id="passwordInputField" autocorrect="off" autocapitalize="off"/><br/>    
            <input type="button" id="loginButton" value="Login" />
          </div>
        </div>
        <div data-theme="a" data-role="footer">
          <h3>Copyright stuff</h3>
        </div>
      </div>
      
    
      <script src="js/JQMLogin.js"></script>
      <script src="js/messages.js"></script>
      <script src="js/auth.js"></script>
      <script
        src="http://code.jquery.com/mobile/1.1.0/jquery.mobile-1.1.0.min.js"></script>
    
    </body>
    </html>
    
    The .html page has 4 div's representing 4 jQuery Mobile pages they are page1, page2, page3 and loginPage, the first 3 pages are pretty simple all they do is display link to other page and there is a logout button in the footer. The loginPage is used to display login page to the user, it is set as 4th page so that it does not get displayed to the user by default, instead we use the logic in auth.js to manually display and hide the login page.
  3. This is how the auth.js file for my application looks like
    
    var Authenticator = function() {
      var LOGIN_PAGE_SECURITY_INDICATOR = 'j_security_check';
      var USERNAME_INPUT_ID = '#usernameInputField';
        var PASSWORD_INPUT_ID = '#passwordInputField';
      var LOGIN_BUTTON_ID   = '#loginButton'; 
      function onFormSubmit() {
            console.log("Entering auth.js.onFormSubmit()");
              var reqURL = './' + LOGIN_PAGE_SECURITY_INDICATOR;
              var params = {
                  j_username : $(USERNAME_INPUT_ID).val(),
                  j_password : $(PASSWORD_INPUT_ID).val()
              };
              onSubmitCallback(reqURL, {parameters:params});
          }
      return {
        init : function() {
          console.log("Inside auth.js.init");
          $(LOGIN_BUTTON_ID).bind('click', onFormSubmit);
        },
        isLoginFormResponse : function(response) {
          console.log("Inside auth.js.isLoginFormResponse " + response.responseText);
          if (!response || response.responseText === null) {
            console
                .log("Entering auth.js.isLoginFormResponse (), return false");
            return false;
          }
          var indicatorIdx = response.responseText
              .search(LOGIN_PAGE_SECURITY_INDICATOR);
          console.log("Entering auth.js.isLoginFormResponse (), return "
              + (indicatorIdx >= 0));
          return (indicatorIdx >= 0);
        },
        onBeforeLogin : function(response, username, onSubmit, onCancel) {
          console.log("Inside auth.js.onBeforeLogin");
          onSubmitCallback = onSubmit;
                onCancelCallback = onCancel;            
                if (typeof(username) != 'undefined' && username != null){
                    $(USERNAME_INPUT_ID).val(username);
                }
                else {
                    $(USERNAME_INPUT_ID).val('');
                }
                $(PASSWORD_INPUT_ID).val('');
        },
        onShowLogin : function() {
          console.log("Inside auth.js.onShowLogin");
          $.mobile.changePage("#loginPage");
        },
        onHideLogin : function() {
          console.log("Inside auth.js.onHideLogin");
          $.mobile.changePage("#page1");
    
        }
      };
    }();
    
    
    Most of the code in auth.js is same as that of How to enable form based authentication in worklight application, but changes are in two functions onShowLogin and onHideLogin() In the onShowLogin() function i am using jQuery Mobile javaScript code to change the page to loginPage and in the onHideLogin() method i am resetting the page back to page1, but once the user is logged in you can move between page1, page2 and page3 and it works.

1 comment:

isaac said...

Nice article. I have a question for you though as it pertains to using JQuery mobile and worklight to make a multipage app. The problem is that I am making a complex app and having all of the data in file is not good. So to compensate, i'm using the main.html file to populate the content. Then using basic worklight functionality to switch the content in the div. Everything works great until I use the JQuery transitions (slide, pop, etc...) After that, the links quit working. I am pasting some samples. Maybe you have a solution:

The code:


http://jsfiddle.net/tz57y/

As I said, everything works fine but I have a button in the header (not shown here) and when I attach a data-transition to it, the links that are being defined in the Worklight JS quit working.

Obviously, this has to do with the Ajax probably hijacking the link, but I specifically gave worklight the JQuery/JQueryMobile files at the start of the project. So in my mind, the Ajax functionality should not break it.

Any ideas? Besides loosing the Ajax animations/transitions and using static HTTP request.