 Great. Well, this is building dynamic applications using jQuery mobile. My name is Pat McLaughlin. I'm a technical architect for enterprise solutions at Cititank. We're a company in Chicago. My background is actually in services-oriented distributed web applications. I came up through the C-Sharp.net area. I got my email and blog here. Woo! Let's see here for Microsoft. I needed that, so thank you, guys. I'm going to post links to the demo application and the source code right after this, so we'll check it out. So let's get started. Originally, when I named this talk, I called it Dynamic Applications, but what I really should have called it is Dynamic Solutions. I want to distinguish between a mobile web application or a mobile application and a mobile website, because later we're going to talk about the differences. So there's four questions that I want to answer, and hopefully everyone will have the answers at the end here. That is, what is a dynamic mobile solution? How do dynamic mobile solutions fit into the enterprise? How do enterprise concerns drive the design of a mobile solution? And finally, how to build a dynamic form solution. So what is a dynamic mobile solution? Well, a general definition would be an application or website that can have content changed without reinstalling or redeploying. I think a more specific definition would be a line of business application that can adapt to configurable data models and work order processes. So in layman's terms, we're talking about a mobile solution that has configurable forms. So let's look at a real world example. I've been working on a highly configurable mobile situation for the city of Chicago for about the last year. The mobile solution is a data entry point for an enterprise-wide system that manages city data. The enterprise application is completely configurable per department for the city of Chicago. So what we're talking about is, say, for a fire inspection. A fire extinguisher inspection takes in different values in a fire exit inspection. The code violations that go with a fire tenon inspection are different than the violations that go with a fire drill inspection. And finally, the milestones needed to obtain a business license are different than the milestones we need to obtain a liquor license. So we're talking about having something configurable. So an example of use. The fire department will use a mobile solution for completing inspections. Each inspection will perform multiple, each inspector will perform multiple types of inspections at a given location. So the solution has to render each one of these forms for the inspector, validate the data and send it back to the enterprise. The mobile solution can be used for many different types of work order processes and eventually it will be rolled out to the police, the health and the water departments as well. So how does a dynamic solution fit into the enterprise? Well, the city of Chicago has approximately 2,700 mobile devices. The devices are of many different types. They're blackberries, androids, iPhones, feature phones, tablets and tough books. Any mobile solution that we provide needs to run on many of these types of devices. The enterprise system that the city uses also has approximately 3,000 different configurations based on department and entity type. So that means not only do we have to support different types of devices, but we also have to support all the different configurations. So even on the same types of device it would be impossible to redeploy a solution as configurations are changed and added. So at this point the answer to the problem is a dynamic solution. So how do enterprise concerns drive the design of a mobile solution? Well, the first decision that we have to make is should we be using a mobile website or should we be using a mobile application? Well, in the case of the city we decide we need to use both. Deployment is a large concern with so many devices at the city. So if we can use an HTML5 based online offline website that we can deliver through the mobile browser, that's the best solution. Unfortunately, some of the departments need native functionality as well. Example of this is that the city of Chicago, a demolition inspection, needs pictures with it before you can have a demolition permit. In order to achieve native functionality we use a tool called PhoneGap. Before we talk about PhoneGap though I just want to look at some of the specs of the mobile website. So it's an HTML5 based website. We make use of the offline web application API. We use the web storage API and using both of those we can create a website that can be run in connected or disconnected state. So it's very important, especially at the city of Chicago when there's inspectors going into buildings where they won't have a connection. The inspections still need to be completed. The entity data that they collect will be stored locally and then it will sync with the enterprise system as soon as a connection is available. So onto PhoneGap. We'll just do a little bit about PhoneGap. PhoneGap is a framework for building cross-platform applications. The applications are built in HTML5 and JavaScript and then they're wrapped into native applications. PhoneGap implements native functionality in a platform-specific language and exposes it via JavaScript. So if you're an iOS they'll implement an Objective-C. If you're an Android they'll implement it in Java and then your JavaScript code can call their API and that gives us a cross-platform solution. The one catch about PhoneGap is the mobile website that runs inside of PhoneGap needs to be implemented in a single page, single HTML page. That's where jQuery Mobile comes in. So jQuery Mobile allows us to build a cross-browser website that is compatible with PhoneGap. We are able to keep one code base for both the mobile applications and the mobile websites. So what we do at the city is we check to see are we running inside a browser, we're running inside PhoneGap and we have differences in the code. jQuery Mobile also gives us the ability to render input forms dynamically so redeployment is not necessary. And finally it allows us to create a mobile site based on configurations that has the look and feel of mobile. This is very important because we're using the enterprise site to give us form configurations but we don't want them to look like how they look inside the enterprise application. We want them to have a mobile feel. Now we're under the phone stuff. So how to build a dynamic form solution? So our dynamic form solution has three goals. First of which is create a mobile solution that inputs data based on the configurations in the core enterprise application. Provide offline and online access to the application on device. Finally validate inputs against business logic stored in the core enterprise system. All right. So I've created a demo application to show how we're going to render dynamic forms. This is the first screen. This is a login. So this would act like an inspection app, an inspection application. We pass in a username and password. We would log in. If we're authenticated it would return all the information we need to render dynamic forms. This screen here is a static page. Inside of here we just have a bunch of entities and as you click on one it leads us to a dynamic form. This is the actual dynamic form here. So what we're looking at here is a form that we created on the fly using a form template that we downloaded. So the form template includes information about what kind of controls to render. So we have the text boxes and then we have the drop down list. Also tells us what's required and also what labels to attach. So what are the challenges for building a dynamic form solution? So we need to get all the entity and form data to the mobile solution so that it can be used in online and offline mode. We need to render unique forms for each entity type and assign values. Finally we need to validate and save the dynamic data back to the core enterprise system. So there's two things I want to define before we start looking at the actual code. The first thing I want to define is an entity. So when we speak of entity we're going to be talking about an object that represents an actual data item in the system. So the examples here are inspections, permits, licenses, or any item that can be bound to a form. Then we have the form templates. Form templates provide us the metadata that describes how to render a dynamic form. So now we're going to look at the dynamic form again here. So on the screen we can see we have three controls. Those controls would come to us in the form template and then we're bound to the entity. As you can see here we have height, 100 feet, so that was bound to the entity using a property. So how does the mobile solution get its data? After we log in we download the entity data and form templates via JSON-based web service. The data that is downloaded specifically for the user that's logged in. The reason we only bring back that data is because we have size issues when we're storing on the device. So we only want to bring back just the necessary amount of information. So for instance we might bring back 50 entities because there's 50 inspections we want to perform, but we might only need two form templates since all the entities might be similar. So after each successful save the web service is called again to update any new data. The reason we do this is to save space as well. So if an inspection passes we don't need to have it on the device anymore and that will save us some space. So now we're going to look at a snippet of JSON. Can everyone see it all right? Fair enough. Excuse me. So we're going to look at some of the properties on this JSON object. So we have the control ID and that's the ID we're going to render the control with. We have the control type. In this case it's a drop-down list. We have default checked. This one only matters when we're rendering a check box. And we have enabled. That tells us whether or not the control is read only. We have the entity. The entity is what we're going to bind the values back to. And then we have the items. So in this list of items these will be all the items that will go into the drop-down list. We have the label. This just tells us what text to render with. We have the property. The property is very important as well because that's the property on the entity we're going to assign the value of this control to. And finally whether it's required or not. So how does the mobile solution render the custom forms? Each entity has a corresponding form template that describes the form. The form template contains a title, description, and a list of controls. And the jQuery mobile page is created in code then added to the container. So we use string templates to render each control. So we're going to look at a code snippet here. What we see here is how to render a text box. So we have the jQuery mobile markup. We have the dig tab, the div tag. We have the label, and then we have the input. Inside of there we have placeholders for all the attributes. We then use regular expressions to assign the control ID and the label. Finally we check if it's required, and then we also add some markup, giving a red asterisk to let the user know that it's required. Finally we close out the div tag and we return this back. Here we're looking at how to render a check box. So the code is very similar, except in this case we have an extra attribute that we use to decide whether or not this should be checked by default. Once again here we use regular expressions to fill in the attributes. One important thing that I want to mention is when we're rendering these controls, the control IDs have to be unique. So the underlying enterprise system that we get the form configurations from takes care of that force in this example. But if it didn't you would have to attach name spaces in order to make each control unique. As we look at some more of the code you're going to see that the control IDs are very important to getting values back out. How does the mobile solution render the custom forms? Well after each page is created it's added to the jQuery mobile page container. So this really is the magic of jQuery mobile when you're making dynamic forms. The first line of code here removes any old pages that have a class of dynamic data page. We then call render.get page template. This is a function that we've created that creates an entire page and this includes looping through the form template control list in order to render each control. And finally we take the entire page as HTML and we append it to the jQuery mobile page container. This is where jQuery mobile does its work. It enhances the page, adds it to the DOM, and that we have an extra page. So once we've created the page we then use an array to keep references to all the controls. As the control is added to a page an entry is also added to the control array and looping through the control array gives us a programmatic way to access each control to retrieve and assign values. So right here I got a JavaScript object that I've created. It's called control and it takes in the ID of the control the property whether it's required, the type, and then the control name which is the label. We don't set the value when we put this control in the array so we have a helper method that allows us to set the value. Now we have the control array here. We have the control array and then we have two helper methods. We can add a control and get a control. Once again when we get the control it's using the control ID so it has to be unique. Also code would break. So how does the mobile solution validate and save data? Well the control array is used to access controls and retrieve values, a required field attribute is part of the configuration of each control. Finally the values are assigned back to the entity and uploaded to the enterprise application via web service. So we're going to look at a snippet of code where the control array is looped through and all the controls are accessed using helper methods. So the code here, you can see here I'm looping through the control array right here and I'm checking the type of the control and then using a helper method based on the type to get the value back out and add that value back into the control array. We do this for check boxes and drop down lists. So this is the way we're able to loop through the form and get the values out without actually knowing what controls are on the page. We're going to take a look at the helper methods too. These all use jQuery selectors, pass in the control ID and then if it's a text box we retrieve it in this manner and so forth for the select value and the check box value. We've got the final save method here. All we do is validate and then we loop through the control array and then we assign the values. So this is the actual demo application. It's a live application and up until about an hour ago it has worked perfectly for about two weeks. So I think everyone can relate to that. So I'm going to give it a shot here and maybe loosen up the talk a little bit here. Normally this would be on a tablet, but unfortunately I don't want to make the screen any smaller. So I'm going to go ahead and log in. And when I log in, the first thing that's going to happen is we're going to call a web service using a jQuery Ajax call. If we're authenticated it's going to return back form templates and all the entities we need. Excellent. So we can see we have three entities here and each entity has an address and that's how I've organized it. This page right here is completely static except for the list view where I've just appended a couple list items. So we're going to click on the first one here and we're going to see this as a fire building inspection. We have three controls. We have the height, the width, and the inspection result. And inside the inspection result we have three values. The height's already been assigned because a property matched from the entity. So I'm going to go ahead and try to save this. We're going to loop through the control array right now and it's going to find that we don't have a value for the width. So I'm going to go ahead and fill that in. I'm going to save it. So now I'm going to go to 3503 North Racine. At a 35 North Racine we're going to render a completely different form using the metadata. So neither of these pages existed before they're rendered. See we have checkboxes, we have sprinklers, fire extinguishers, and then one thing to note here is this dropdown list, although it resembles the other dropdown list, it actually has four items in it. So the form template controls what goes in the dropdowns as well. I'm going to save that and we can go back in and we can see all the items are still bound. What happened there when I went back in is we actually rendered the form again. So we're going to be one of the things we're going to look at to speed up the application. So I'm going to go back to the code for a second or to the presentation. So what improvements can we make to that demo app? Well, performance for one. So we can cache each page after it's rendered so it doesn't need to be recreated. We can add validation. We can provide different types of field validation. Right now we're just doing required fields so that we could have the form template tell us that the type of data it's expecting is an email or a phone and create JavaScript functions to validate it without attaching them to a specific control. One of the main things we need to do, and this is what we do at the city, is we support multiple pages. So we wouldn't just be assigning one dynamic page. We'd be assigning multiple, and with that comes navigation. So we'd be dynamically adding to the nav bar at the bottom so that we can move through all the different pages. So at this time, I'm going to just open up Visual Studio and we're going to look at the code a little bit. As we saw earlier, I'm a Microsoft guy, so I actually build the applications in Visual Studio and see how this looks. Is that readable at all? Nope. Anybody? That's going to take one second. Any better? Great. All right, I want to look at the demo application now and show you, connect all the dots, because I don't know if I explained it well enough how this application is working. So we're going to start at the index page. So the index page is the application. And we'll notice we have two pages in it. We have the login page, then we have the assignments page. What you will notice is we don't even have a placeholder for the dynamic forms. We create the entire page and then we append it to the container. Now we're going to look at the render class. Start at the top. So the render class has a bunch of properties that allow us to create the HTML for the pages. We start with the page template here. So right now we're getting away with having the ID just called dynamic data page. But if we had multiple pages here, we'd have to assign a unique ID to it, or else we wouldn't be able to navigate between the pages. We've got the template here. This is where we have the buttons for saving and canceling. Then we have the start of the form right there. So get page template is what organizes all the code. So we call the property methods here, but then we call render controls. Render controls takes a list of controls from the form template. It loops through and it renders each control right here. So we check the type, and then we call the render method for that type. We got render text box, which we've already looked at, check box. And then we also have render dropdown list. What makes a render dropdown list different is the fact that we're adding items in. And finally, we're going to look at the app code. So the app code starts right here and initializes. We just have some wire up stuff here. And then we have the code for logging in the user. We have a bit of validation code here, and then we have the Ajax call. The Ajax call returns to us a list of entities and form templates, and we pass it into app.load addresses. So right here, I'm taking the entities and the form templates, and I'm storing them in just a variable in the DOM. So I've created a class called state to store those. We then loop through the list of addresses. Sorry, the placeholder for it. We insert the code, and then we refresh the code and enhance it. And that's how we get the address list. And finally, we have the load form function. So whenever you click on an address, I fill in, in the state variable, the current entity and the current form template. We then clear the controls, and then we render the form. After that, we change page to dynamic data page. The rest of the code here is for loading the entity values. We already looked at that. We're looping through the control array, and for each type, we're setting a property value. And then finally, the save. So we validate the values, we loop through, and then we assign the properties, and then we clean up controls.clear controls, and then we empty out the state. So that's about it for me. If anyone has any questions, I'm going to have all the code up. Thanks.