Over a million developers have joined DZone.

How to Build a User Registration System for a jQuery Mobile Application

· Java Zone

Learn more about how the Java language, tools and frameworks have been the foundation of countless enterprise systems, brought to you in partnership with Salesforce.

User registration is the foundation that allows you to provide a personalized experience for the users of your mobile apps. In this jQuery Mobile tutorial we are going to create a user registration system for a jQuery Mobile application.

signup-flow-2

In a previous jQuery Mobile tutorial of this series we designed and created the jQuery Mobile pages that we will use in the application that is the subject of this article. In a recent NodeJs and MongoDB tutorial, we also created the backend that will perform the registrations and store the user profiles.

Now we are going to connect the two pieces and create and end-to-end system that allows users to register with the application. Let’s start by creating a few helper files.

The User Registration UI

We created the directories structure for the application in a earlier tutorial. As a reminder, the project’s directories look like this:

directories-19

In the project, the jQuery Mobile pages that we will use in the user registration process are hosted in the index.html, sign-up.html and signup-succeeded.html files.

Creating a Settings File

We are going to use a JavaScript file to store application settings. Only the settings that are not user-modifiable will go in this file. Let’s go ahead and create the settings.js file in the js directory, as depicted below.

directories-20

Now we will type the following code in the file:

var BookIt = BookIt || {};
BookIt.Settings = BookIt.Settings || {};
BookIt.Settings.signUpUrl = "http://localhost:30000/api/account/register";

For the time being we are only going to store one setting in the file. The setting is the URL for the server endpoint that will handle user registration requests made from the app. Be mindful that the value I entered is what I use in my development workstation. You will need to change this URL so it works on your own development environment.

The index.html file needs to contain a reference to the settings.js file. Let’s go to the index.html file and add the reference as depicted below:

<link href="./css/themes/1/conf-room1.min.css" rel="stylesheet" />
<link href="./css/themes/1/jquery.mobile.icons.min.css" rel="stylesheet" />
<link href="../../../lib/jqm/1.4.5/jquery.mobile.structure-1.4.5.min.css" rel="stylesheet" />
<link href="./css/app.css" rel="stylesheet" />
<script src="../../../lib/jquery/2.1.1/jquery-2.1.1.min.js"></script>
<script src="js/settings.js" type="text/javascript"></script>
<script src="../../../lib/jqm/1.4.5/jquery.mobile-1.4.5.min.js"></script>

The Api Messages File

Next we are going to create a file to store the message codes that the server will return to the application. Let’s create the api-messages.js file in the js directory:

directories-21

We are going to type the following code in the file:

var BookIt = BookIt || {};
BookIt.ApiMessages = BookIt.ApiMessages || {};
BookIt.ApiMessages.EMAIL_NOT_FOUND = 0;
BookIt.ApiMessages.INVALID_PWD = 1;
BookIt.ApiMessages.DB_ERROR = 2;
BookIt.ApiMessages.NOT_FOUND = 3;
BookIt.ApiMessages.EMAIL_ALREADY_EXISTS = 4;
BookIt.ApiMessages.COULD_NOT_CREATE_USER = 5;
BookIt.ApiMessages.PASSWORD_RESET_EXPIRED = 6;
BookIt.ApiMessages.PASSWORD_RESET_HASH_MISMATCH = 7;
BookIt.ApiMessages.PASSWORD_RESET_EMAIL_MISMATCH = 8;
BookIt.ApiMessages.COULD_NOT_RESET_PASSWORD = 9;
BookIt.ApiMessages.PASSWORD_CONFIRM_MISMATCH = 10;

Notice how the name of each variable reveals its intent. If you already read the article where we created the user registration backend, you will also notice that the values in the ApiMessages Class we just created match the values in the server-side ApiMessages Class. You can find this Class in the server/models/api-messages.js file.

The api-messages.js file also needs to be referenced from the index.html file. Let’s add the reference as depicted below:

<link href="./css/themes/1/conf-room1.min.css" rel="stylesheet" />
<link href="./css/themes/1/jquery.mobile.icons.min.css" rel="stylesheet" />
<link href="../../../lib/jqm/1.4.5/jquery.mobile.structure-1.4.5.min.css" rel="stylesheet" />
<link href="./css/app.css" rel="stylesheet" />
<script src="../../../lib/jquery/2.1.1/jquery-2.1.1.min.js"></script>
<script src="js/settings.js" type="text/javascript"></script>
<script src="js/api-messages.js" type="text/javascript"></script><script src="../../../lib/jqm/1.4.5/jquery.mobile-1.4.5.min.js"></script>

The Signup Module

From the user interface perspective, the signup process involves the signup and the signup-succeeded jQuery Mobile pages:

signup-flow-3

The signup module is where we will place the code to capture the user’s name, email and password and send it to the server. When a user visits the signup page and taps the Submit button, the signup module will perform the following operations.

First, it will validate the name, email address and password entered by the user. If any of the fields is invalid, the module will alert the user. If the fields are valid, the module will send a request to register the user over to the server.

Finally, the module will process the server’s response and either activate the signup succeeded page or show an error message to the user.

signup-flow-4

Let’s create the sign-up.js file in the js directory:

directories-22

Now we will add an empty module to the file:

(function () {




})();

Before moving on with the module’s code, let’s jump to the index.html file and add a reference to the sign-up.js file:

<link href="./css/themes/1/conf-room1.min.css" rel="stylesheet" />
<link href="./css/themes/1/jquery.mobile.icons.min.css" rel="stylesheet" />
<link href="../../../lib/jqm/1.4.5/jquery.mobile.structure-1.4.5.min.css" rel="stylesheet" />
<link href="./css/app.css" rel="stylesheet" />
<script src="../../../lib/jquery/2.1.1/jquery-2.1.1.min.js"></script>
<script src="js/settings.js" type="text/javascript"></script>
<script src="js/api-messages.js" type="text/javascript"></script>
<script src="js/sign-up.js" type="text/javascript"></script>
<script src="../../../lib/jqm/1.4.5/jquery.mobile-1.4.5.min.js"></script>

Adding Validation Functions

Back in the sign-up.js file, the first items that we will add are three helper functions. The first function will allow us to validate the format of the email address entered by the user that is trying to sign up:

var emailAddressIsValid = function (email) {
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
};

Next, we will add a function that to check if the values entered in the password and password confirm fields match.
We want to make sure that these values are equal so we can send the registration data to the server.

var passwordsMatch = function (password, passwordConfirm) {
return password === passwordConfirm;
};

Last, a function to validate that the user’s password is sufficiently complex:

var passwordIsComplex = function (password) {
// TODO: implement password complexity rules here. There should be similar rule on the server side.
return true;
};

I provided an implementation without any complexity rules. I will let you decide what rules make sense for your particular application and environment. For example, you could check that the password length is greater than a certain number of characters, or that the password contains numbers and symbols.

Capturing Taps on the Submit Button

With the validation functions in place, we can move on to capturing the data entered by the user. Our goal is to validate and submit the data when the user taps the Submit button. This means that we need to create a tap handler for the button before the jQuery Mobile page is shown to the user.

jQuery Mobile provides hooks into the events in the lifecycle of a jQuery Mobile page. We will use the page’s beforecreate event to wire our tap handler for the submit button. This event triggers before the jQuery Mobile page has been created. We want the tap handler to be already wired when the page is created and shown to the user.

Let’s add the following code to the sign-up.js file:

$(document).delegate("#page-signup", "pagebeforecreate", function () { 




var $signUpPage = $("#page-signup"),
$btnSubmit = $("#btn-submit", $signUpPage);




$btnSubmit.off("tap").on("tap", function () {








});
});

We just set up a handler function for jQuery Mobile’s Page Widget’s beforecreate event, which is triggered before a page is created. As we want to hook the beforecreate event of the signup page, we use the #page-signup selector when creating the handler.

Inside the handler function, we obtain a reference to the Submit button and create a handler for its tap event. Notice how we first use the jQuery’s off function to remove any previous handlers for the tap event.

Next we want to create some variables that will allow us to capture the data typed by the user in the name, email and password fields of the signup page. Inside the Submit button’s tap handler, type the following code:

var $ctnErr = $("#ctn-err"),
$txtFirstName = $("#txt-first-name"),
$txtLastName = $("#txt-last-name"),
$txtEmailAddress = $("#txt-email-address"),
$txtPassword = $("#txt-password"),
$txtPasswordConfirm = $("#txt-password-confirm");




var firstName = $txtFirstName.val().trim(),
lastName = $txtLastName.val().trim(),
emailAddress = $txtEmailAddress.val().trim(),
password = $txtPassword.val().trim(),
passwordConfirm = $txtPasswordConfirm.val().trim(),
invalidInput = false,
invisibleStyle = "bi-invisible",
invalidInputStyle = "bi-invalid-input";

The first five variables are references, to the div element that will help us display error messages to the user, as well as to the input controls where the user will type their profile data.

The firstName, lastName, emailAddress, password and passwordConfirm variables store the actual values entered by the user.

The invalidInput variable is a helper variable that we will use when validating user input. The invisibleStyle and invalidInputStyle variables will hold the names of the CSS classes that define the styles of invisible elements and invalid controls respectively.

Let’s quickly open the app.css file and add the following styles:

.bi-invalid-input {
background-color:#fffacd!important;
}




.bi-invisible {
display:none;
}




.bi-ctn-err {
background-color:#ffe1cd;
padding:0 .5em;
margin-bottom:.5em;
border: 1px solid #e9cfbd;
border-radius:3px 3px;
}

When these styles are applied, the invalid fields will look as depicted below.

signup-invalid-scrn-1

Resetting Styles

Let’s jump back to the sign-up.js file. After declaring our variables, we want to remove any of the “invalid input” styles from the login page’s error container and input fields that might remain in place from the last time the user opened the page:

// Reset styles.
$ctnErr.removeClass().addClass(invisibleStyle);
$txtFirstName.removeClass(invalidInputStyle);
$txtLastName.removeClass(invalidInputStyle);
$txtEmailAddress.removeClass(invalidInputStyle);
$txtPassword.removeClass(invalidInputStyle);
$txtPasswordConfirm.removeClass(invalidInputStyle);

Highlighting Empty Fields

Next, we want to check that none of the fields that are required, which in this case is all the fields, are empty. This is how we are going to do it:

// Flag each invalid field.
if (firstName.length === 0) {
$txtFirstName.addClass(invalidInputStyle);
invalidInput = true;
}
if (lastName.length === 0) {
$txtLastName.addClass(invalidInputStyle);
invalidInput = true;
}
if (emailAddress.length === 0) {
$txtEmailAddress.addClass(invalidInputStyle);
invalidInput = true;
}
if (password.length === 0) {
$txtPassword.addClass(invalidInputStyle);
invalidInput = true;
}
if (passwordConfirm.length === 0) {
$txtPasswordConfirm.addClass(invalidInputStyle);
invalidInput = true;
}




// Make sure that all the required fields have values.
if (invalidInput) {
$ctnErr.html("<p>Please enter all the required fields.</p>");
$ctnErr.addClass("bi-ctn-err").slideDown();
return;
}

If any required field is empty, we apply the “invalid input” style and set the invalidInput variable to true. If, after checking each field, the invalidInput variable is set to true, we make the error message at the top of the page visible and let the user know that they have to enter values for all the fields.

Email Address Validation

The next validation applies to the email address field. In this case we want to make sure that the user typed a value that is formatted as an email address:

if (!emailAddressIsValid(emailAddress)) {
$ctnErr.html("<p>Please enter a valid email address.</p>");
$ctnErr.addClass("bi-ctn-err").slideDown();
$txtEmailAddress.addClass(invalidInputStyle);
return;
}

In the code above we invoke the emailAddressIsValid function, which we created earlier in this article, to check the format of the text in the email address field. If the function returns false, we activate the error message at the top of the page and highlight the email address field using the “invalid input” style.

Confirming the Password

Now we are going to move on to the client-side validation of the password, which we will accomplish in two steps. First, we want to make sure that the values in the password and password confirm match. We will use the passwordsMatch function that we created earlier to perform the check. Let’s add the following code:

if (!passwordsMatch(password, passwordConfirm)) {
$ctnErr.html("<p>Your passwords don't match.</p>");
$ctnErr.addClass("bi-ctn-err").slideDown();
$txtPassword.addClass(invalidInputStyle);
$txtPasswordConfirm.addClass(invalidInputStyle);
return;
}

The second step is a check for the complexity of the password:

if (!passwordIsComplex(password)) {
// TODO: Use error message to explain password rules.
$ctnErr.html("<p>Your password is very easy to guess. Please try a more complex password.</p>");
$ctnErr.addClass("bi-ctn-err").slideDown();
$txtPassword.addClass(invalidInputStyle);
$txtPasswordConfirm.addClass(invalidInputStyle);
return;
}

Here we perform the validation by invoking the passwordIsComplex function that we created earlier. Remember that I left the implementation of the validation rules inside the function up to you.

Sending the Signup Data to the Server

We are at a point where we’ve performed all the validations that we intended to do on the client side. All that’s left is to send a request to register the user to the server. Let’s add the following code to the module:

$.ajax({
type: 'POST',
url: BookIt.Settings.signUpUrl,
data: "email=" + emailAddress + "&firstName=" + firstName + "&lastName=" + lastName + "&password=" + password + "&passwordConfirm=" + passwordConfirm,
success: function (resp) { 




if (resp.success === true) {
$.mobile.navigate("signup-succeeded.html");
return;
} else {
if (resp.extras.msg) {
switch (resp.extras.msg) {
case BookIt.ApiMessages.DB_ERROR:
case BookIt.ApiMessages.COULD_NOT_CREATE_USER:
// TODO: Use a friendlier error message below.
$ctnErr.html("<p>Oops! BookIt had a problem and could not register you. Please try again in a few minutes.</p>");
$ctnErr.addClass("bi-ctn-err").slideDown();
break;
case BookIt.ApiMessages.EMAIL_ALREADY_EXISTS:
$ctnErr.html("<p>The email address that you provided is already registered.</p>");
$ctnErr.addClass("bi-ctn-err").slideDown();
$txtEmailAddress.addClass(invalidInputStyle);
break;
}
}
}
},
error: function (e) {
console.log(e.message);
// TODO: Use a friendlier error message below.
$ctnErr.html("<p>Oops! BookIt had a problem and could not register you. Please try again in a few minutes.</p>");
$ctnErr.addClass("bi-ctn-err").slideDown();
}
});

In the code we send a POST request via Ajax to the url that we stored in the Settings.signUpUrl variable. This is the url of the server endpoint tutorial of this series. We use the data variable to send a url-encoded string with the user profile attributes that the server needs to perform the user registration.

In the request’s success callback, we inspect the success property of the response sent by the server. If success is set to true, meaning that the signup succeeded, we navigate to the “signup succeeded” page. We will create this page in a couple of minutes.

If the success property is not set to true, meaning that the request failed, we inspect the extras.msg property of the response. The value of this property describes the reason why the request failed.

We use this value to show the appropriate error message to the user at the top of the form. You can refer to the server endpoint tutorial of this series for more details about how the error conditions are handled on the server side.

In the Ajax request’s error callback, we display an error message to the user.

The Signup Succeeded Page

The last piece that we need to put in place is the “signup succeeded” page. We originally didn’t create this page in the article where we designed the user interface for the user registration process.

Let’s create the signup-succeeded.html file in the project’s root directory.

directories-19

In the file, add the following code.

<!DOCTYPE html>
<html>
<head>
<title>BookIt</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="./css/themes/1/conf-room1.min.css" rel="stylesheet" />
<link href="./css/themes/1/jquery.mobile.icons.min.css" rel="stylesheet" />
<link href="../../../lib/jqm/1.4.5/jquery.mobile.structure-1.4.5.min.css" rel="stylesheet" />
<link href="./css/app.css" rel="stylesheet" />
<script src="../../../lib/jquery/2.1.1/jquery-2.1.1.min.js"></script>
<script src="js/sign-up.js" type="text/javascript"></script>
<script src="../../../lib/jqm/1.4.5/jquery.mobile-1.4.5.min.js"></script>
</head>




<body>
<div data-role="page" data-bookit-page="index">
<div data-role="header" data-theme="c">
<h1>Book It</h1>
</div><!-- /header -->
<div role="main" class="ui-content">
<h2 class="mc-text-center">Registration Succeeded</h2>
<p class="mc-top-margin-1-5">Congratulations! You are now registered with BookIt.</p>
<a href="sign-in.html" class="ui-btn ui-btn-b ui-corner-all">Sign In</a>
<p></p>
</div><!-- /content -->
</div><!-- /page -->
</body>
</html>

This is how the pages looks in the browser:

signup-succeed-scrn-1

Now you can go ahead and test the app. Fire up your node.js backend, open the app in a browser and try signing up with the app. Make sure to test all the error conditions as well.

Summary and Next Steps

Many of today’s mobile applications aren’t functional if you first don’t register with the app. In this jQuery Mobile tutorial we learned how to create a user registration system in a jQuery Mobile application.

The user registration system is made of three distinct pieces:

  • A jQuery Mobile page where users type their registration data.
  • A JavaScript module that validates the data entered and sends it to the server.
  • The server-side endpoint that receives the registration data and registers the user with the backend database.

In this tutorial we built the first two pieces. We had already built the third piece aprevious article of this series of mobile application development tutorials.

In the next chapter of this series we will learn how to use Cordova to package and deploy the jQuery Mobile application we are working on. Make sure to sign up for my newsletter so you can be among the first to know when the next tutorial is available.

Download Source Code

Download the source code for this tutorial here: jQuery Mobile User Registration Tutorial on GitHub

All the Chapters of this Series

You can find all the published parts of this series here: The Meeting Room Booking App Tutorial.

Stay Tuned

Don’t miss out on the updates! Get MiamiCoder’s new articles and updates sent free to your inbox.

Discover how the Force.com Web Services Connector (WSC) is a code-generation tool and runtime library for use with Force.com Web services, brought to you in partnership with Salesforce.

Topics:

Published at DZone with permission of Jorge Ramon, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}