Download Project Files:
The project files wont work unless you put your own Application ID & JavaScript key in to js/main.js.
Required Skills:
Introduction
Previously, in part 1 of this tutorial, we covered the basics of creating a Sign Up page with a simple jQuery Mobile user-interface (UI) that uses the Parse.com core service to save a users credentials to an application’s User table on the Parse.com servers. Part 2 in this tutorial builds upon our previous work by adding a Sign In page. Once the user has entered their credentials into the Sign In form the JavaScript checks the credentials against the users table and if they are correct the user is presented with a Home page where they will see dynamic content generated using information retrieved from the database.
The individual steps we need to take are:
Lets begin!
User Interface:
The Sign In form is very similar to the Sign Up form we created in part 1 except there is one less input field due to the fact that the user no longer needs to provide an email address. Because of the similarities it makes sense to duplicate the signup.html file we created in part 1 and rename the duplicate to signin.html. Now open the signin.html and modify it to match the markup below. All modifications are commented with an explanation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
<!doctype html> <html> <head> <title>My Mobile App</title> <!-- Info about view ports can be found here: https://developer.mozilla.org/en/docs/Mozilla/Mobile/Viewport_meta_tag --> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Include the javaScript and CSS files for jQuery Mobile --> <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.3/jquery.mobile.min.css" /> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.3/jquery.mobile.min.js"></script> </head> <body> <!-- create a div to contain the single page, the ID most be unique to the page --> <!-- MODIFICATION: Change id from signup to signin --> <div data-role="page" id="signin"> <!-- Create the a header and include a title --> <div data-role="header" data-theme="b"> <h1>My Mobile App</h1> </div> <!-- Create a div for content --> <div data-role="content"> <!-- Create a standard html form for the user to complete --> <!-- MODIFICATION: changed id to signinform --> <form id="signinform" method="post" action="#"> <!-- MODIFICATION: Changed headed text to Sign Up --> <h3> Sign Up: </h2> <input type="text" name="username" id="username" placeholder="User Name" required/> <input type="password" name="password" id="password" placeholder="Password"/> <!-- MODIFICATION: Deleted the email input field --> </form> <!-- Add a submit button --> <!-- MODIFICATION: Changed button id to submit-signin and the button text to Sign In --> <button id="submit-signin" class="ui-btn">Sign In</button> </div> <!-- Close the content div --> </div> <!-- Close the page div --> <!-- ADD the last two javascript files --> <script src="//www.parsecdn.com/js/parse-1.3.2.min.js"></script> <script src="js/main.js"> </script> </body> </html> </body> </html> |
Thats all we need for the Sign In page and everything else from here on goes into the main.js file that we created in part 1 of this tutorial.
Submit the form:
Now we need to hijack the Sign In button’s click event, collect the values from the Sign In form and send them off to the Parse.com servers to validate the credentials of the user. This new JavaScript will go at the very bottom of main.js below our previous JavaScript and we will start by hooking into out Sign In page’s “pagecreate” event. Add the JavaScript below to the bottom of main.js and read the comments for a better understanding of whats happening:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// ------------------------------------------------------ SIGN IN PAGE ------- // // Listen for when the signin page has been created $(document).on("pagecreate", "#signin", function () { // Hijack the submit button $('#submit-signin').on('tap', function(e){ // prevent the browser from navigating away from this page e.preventDefault(); // NEXT CODE GOES HERE }); }); |
Send the form data to the Parse.com servers:
Add the code below to our previous code where it says “// NEXT CODE GOES HERE”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// retrieve the form values var username = $('input[name=username]').val(); var password = $('input[name=password]').val(); // check log in details with parse.com Parse.User.logIn(username , password, { success: function(user) { // NEXT CODE GOES HERE }, error: function(user, error) { // The login failed. Check error to see why. console.log("fail"); } }); |
At this point we have collated the form data and sent it via AJAX to the Parse.com servers. The Parse.com servers have then checked your application’s User table for a match and sent a response of success or failure. We now have two callback functions that will execute depending on the response. You can customise the error callback function to direct the user however you like but for now we are only going to direct the user to the home page if the details they provide match a user in the database.
The code below programmatically navigates the user to the Home page. Add the code to the previous code where the comments say “// NEXT CODE GOES HERE”.
1 |
$( ":mobile-pagecontainer" ).pagecontainer( "change", "home.html" ); |
Test our progress:
We have made a lot of progress so now is a good time to test what we have done so far. Go ahead and test the form by enter a known user into the form fields and clicking the Sign In button. If all goes well then you should see an error on the screen like the one below saying “Error Loading Page”. This is absolutely fine it just means that the home.html file doesn’t exist yet so there is nothing to load.
Create the Home Page:
The user has nowhere to go so its time we made that Home page. We need to create another .html file called home.html and the simplest way to do this is to duplicate one of the other .html files. Copy and paste another version of the signup.html file into the root folder and rename it home.html. Next we need to delete the main content from the home.html page and make a few minor modifications. Edit home.html so it looks like the HTML below (all modifications are commented with a description).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
<!doctype html> <html> <head> <title>My Mobile App</title> <!-- Info about view ports can be found here: https://developer.mozilla.org/en/docs/Mozilla/Mobile/Viewport_meta_tag --> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- Include the javaScript and CSS files for jQuery Mobile --> <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.3/jquery.mobile.min.css" /> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.3/jquery.mobile.min.js"></script> </head> <body> <!-- create a div to contain the single page, the ID most be unique to the page --> <!-- MODIFICATION: Changed id to home --> <div data-role="page" id="home"> <!-- Create the a header and include a title --> <div data-role="header" data-theme="b"> <h1>My Mobile App</h1> </div> <!-- Create a div for content --> <div data-role="content"> <!-- MODIFICATION: Delete all HTML from the content div --> <!-- MODIFICATION: Two empty containers to dynamically place content --> <h3 id="welcome-msg"> </h3> <h1 id="score"> </h1> <!-- MODIFICATION: Log out button --> <button id="sign-out" class="ui-btn">Sign Out</button> </div> <!-- Close the content div --> </div> <!-- Close the page div --> <!-- ADD the last two javascript files --> <script src="//www.parsecdn.com/js/parse-1.3.2.min.js"></script> <script src="js/main.js"> </script> </body> </html> </body> </html> |
Home Page Content:
We now have a blank Home page ready for any content that your situation requires. There are two empty divs in the content container so that we can dynamically add a welcome message and the user’s score once the user has logged in. We have also included a Sign Out button to complete the secure app cycle.
Get Dynamic Content from Database:
We are almost there now! All we have to do is add a little more Javascript to the bottom of main.js. The home page takes a slightly different approach to the JavaScript than the previous pages for this app. We are still going to hook into the “pagecreate” event for the Home page but we also need to update the content every time the page is shown so we need to hook into a second event as well. This event is not specific to each page and is triggered every time any page is shown so we need to detect when this event is triggered for the Home page first. Add the code below to the very bottom of the main.js page, read the comments to get a better understanding.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// ------------------------------------------------------ HOME PAGE ------- // // Listen for when the home page has been created $(document).on("pagecreate", "#home", function () { // respond everytime the page is shown not just the first time it is loaded into the DOM. // IMPORTANT: THIS EVENT IS FIRED FOR EVERY PAGE $( ":mobile-pagecontainer" ).on( "pagecontainershow", function( event, ui ) { // get the page about to be shown var currentPage = ui.toPage[0]; // make sure that its the home page if (currentPage.id === "home"){ // NEXT CODE GOES HERE. } }); }); |
Now that we have hooked into the “pagecontainershow” event and written some code to detect when this event triggers for the Home page we are almost ready to update the content for the user but first we need to make sure that the user is actually logged in. This is just in case someone tries to navigate directly to the home page bypassing the Sign Up and Sign In page. If this happens then we can present the user with a link to the Sign In page.
When any user successfully logs into your app their information is stored locally on their device until they log out. At any time we can check whether there is an active user logged into your app. The code below checks if the user is logged in and responds accordingly. Add the code to the previous code where the comments say “// NEXT CODE GOES HERE”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// Check that the user is logged in var currentUser = Parse.User.current(); if (currentUser) { // if the user is logged in update the content. // LOGGED IN } else { // If the user is not logged in, ask them to log in. // NOT LOGGED IN } |
Next we will start by adding the code for when the user is logged into the application. We can use the same object we retrieved from local storage to check if the user was logged in to get any other information about the user saved in the database. We will use this information to update the Home page display. In the previous code, just below where the comment says “// LOGGED IN” add the code below:
1 2 3 |
$('#welcome-msg').html("Welcome back, " + currentUser.getUsername()); $('#score').html("Score: " + currentUser.get('score')); |
Now we add the code for when the user is not logged into the application. All we want to do is gently nudge the user to the Sign In page. Add the following code to the previous code where the comments say “// NOT LOGGED IN”.
1 |
$('#welcome-msg').html('Please Sign In <a href="signin.html">here</a>.'); |
Lastly, we can add the functionality to the Sign Out button so that we can test that everything has gone okay. All we need to do is hook into the button’s click event and call one line of code:
1 |
Parse.User.logOut(); |
The code for the Sign Out button goes as follows and you can see where the code is positioned by looking at the final code example that shows the whole Home page JavaScript:
1 2 3 4 5 6 7 8 9 10 11 12 |
// Sign out button $('#sign-out').on('tap', function(e){ e.preventDefault(); // log the user out Parse.User.logOut(); // navigate to the Sign In page $( ":mobile-pagecontainer" ).pagecontainer( "change", "signin.html" ); }); |
We are finished. The final Home page section of main.js should look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
// ------------------------------------------------------ HOME PAGE ------- // // Listen for when the home page has been created $(document).on("pagecreate", "#home", function () { // Sign out button $('#sign-out').on('tap', function(e){ e.preventDefault(); // log the user out Parse.User.logOut(); // navigate to the Sign In page $( ":mobile-pagecontainer" ).pagecontainer( "change", "signin.html" ); }); // respond everytime the page is shown not just the first time it is loaded into the DOM. $( ":mobile-pagecontainer" ).on( "pagecontainershow", function( event, ui ) { // get the page about to be shown var currentPage = ui.toPage[0]; // make sure that its the home page if (currentPage.id === "home"){ // Check that the user is logged in var currentUser = Parse.User.current(); if (currentUser) { // if the user is logged in update the content. $('#welcome-msg').html("Welcome back, " + currentUser.getUsername()); $('#score').html("Score: " + currentUser.get('score')); } else { // If the user is not logged in, ask them to log in. $('#welcome-msg').html('Please Sign In <a href="signin.html">here</a>.'); } } }); }); |
Test Our Handy Work:
Go ahead and test the full secure app cycle. If you sign in, sign out and then try and navigate back to the home page you should see the link back to the Sign In page. The name of the user should be displayed in the welcome button and the number zero should appear in the score. If you head over to Parse.com you can manually edit the score and when the user signs in again they will see the new number as their score. The scope of this tutorial only covers the very basic element of creating a secure app with the Parse.com core data service. There are many improvements that could be made to this example but its a solid foundation upon which to build upon. In a future post I will demonstrate how to update the score from inside the app and when I do I will link it into this tutorial.
I hope this has been useful and thanks for playing along!