Make HTML5 apps with Sencha, part two

In the final part of this tutorial, Sencha’s Daniel Gallo discusses mobile app development and how to connect a mobile HTML5 app to an ASP.NET Web API backend

This article first appeared in issue 236 of .net magazine – the world's best-selling magazine for web designers and developers.

When deciding how to create a mobile application, developers can be faced with a large variety of technologies to choose from. In the previous tutorial I demonstrated how a visual application builder, Sencha Architect, could be used for creating a cross-platform mobile HTML5 app built on the JavaScript framework Sencha Touch, simply by dragging and dropping components on to a canvas.

A good application framework should support a best-practice application structure. This is where Sencha’s model-view-controller (MVC) structure for building web applications helps. MVC enables the developer to separate out the application’s logic into three distinct areas:

  • Models define the data types and fields
  • Views define the visual representation
  • Controllers store all the code to connect up your views and models, plus any other application logic

There are many advantages to developing with a web app framework, such as built-in UI controls, an application pattern (such as MVC), events and objects, and more. Perhaps even more valuable is web apps’ future-proof nature and long lifespan. For instance, a website created 10 years ago is still likely to render OK in today’s modern browsers, albeit perhaps with a few minor quirks.

Unlike some cross-platform frameworks, the language you are coding with in Sencha Touch (JavaScript) is the exact same language your application executes in at runtime. This greatly enhances the developer’s understanding of the application and the underlying framework, and aids in the debugging process if things don’t quite work correctly since there is no intermediate step to look at. What you’re coding is exactly what is executing in the browser.

In part one of this tutorial, we created a mobile HTML5 app using Sencha Architect that allowed the user to view a list of Places

Another benefit of developing with Sencha Touch is the fact the code doesn’t need to be compiled before running. It can, of course, be optionally packaged before deployment, which will optimise it by minifying the contents and combining the JS into a smaller set of files.

Getting started

For this tutorial, we will be linking the Sencha Touch app that was created in part one to an ASP.NET Web API backend. ASP.NET Web API offers a great way to make RESTful applications using the .NET framework, and can be linked very easily with our Sencha Touch application.

First, create a new project in Visual Studio Express 2012 for Web. From the New Project window, select the Visual C# > Web option under the Templates node, and choose the ASP.NET MVC 4 Web Application. For the Project Name, enter a value of Places, and save this under C:\Sencha Architect Apps\, ensuring the Create directory for solution option is checked. Click OK. A pop-up will display, asking you to select a Template. Choose Web API and click OK.

Database

Now that we’ve created a .NET Web API project, we can add a database. Under the Solution Explorer, right-click the App_Data folder and select Add > New Item. Select SQL Server Database, change the name to Database.mdf, then click Add.

Double-click Database.mdf within the Solution Explorer to establish a connection to it, then right-click the database within the Database Explorer and select New Query. Create a table called Place by executing the following query:

CREATE TABLE Place(id INT IDENTITY(1, 1) PRIMARY KEY,name VARCHAR(255),location VARCHAR(255),lat DECIMAL(9, 6),lng DECIMAL(9, 6))

Then populate this table with data by executing the query below. This data will replace the hard-coded values from the previous tutorial.

INSERT INTO Place VALUES ('Alcatraz', 'California', 37.826641, -122.422855)INSERT INTO Place VALUES ('Four Corners Monument', 'USA', 36.999091,-109.045279)INSERT INTO Place VALUES ('Golden Gate Bridge', 'San Francisco', 37.816497,-122.478175)INSERT INTO Place VALUES ('Grand Canyon', 'Arizona', 36.071302,-111.874237)INSERT INTO Place VALUES ('Las Vegas', 'Nevada', 36.113749, -115.173512)INSERT INTO Place VALUES ('Monument Valley', 'Arizona', 36.996658,-110.097785)INSERT INTO Place VALUES ('New York City', 'New York', 40.726446,-74.006767)INSERT INTO Place VALUES ('Washington', 'District of Columbia', 38.895225,-77.036694)INSERT INTO Place VALUES ('Wine tasting', 'Calistoga, California', 38.578299,-122.577653)

ADO.NET Entity Data Model

To allow data to be easily retrieved from the database, we’ll add an ADO.NET Entity Data Model. Return to the Solution Explorer, and right-click the Project. Select Add > New Item and choose ADO.NET Entity Data Model. Pick a Name of Model.edmx then click Add.

This is the view that’s shown after you’ve created your new ASP.NET MVC 4 Web Application within Visual Studio

In the Entity Data Model Wizard, pick Generate from database and hit Next. The newly added database should be pre-selected in the drop-down. Set the Web.Config entity connection settings value to DatabaseEntities. Click Next.

You now need to choose which database objects to add to the model. Tick the Tables node to include all tables, change the Model Namespace to DatabaseModel, then click Finish. In a few moments the Entity Data Model will be generated. Build the project by picking Build Solution in the Build menu.

.NET Web API Controller

We’ve added the database and the Entity Data Model, but now we’re going to need a way of rendering this data to our frontend Sencha Touch application – and we’re going to achieve this via a .NET Web API Controller. Within the Solution Explorer, right-click the Controllers folder and select Add > Controller. This will launch the Add Controller window.

The ADO.NET Entity Data Model provides a representation to the underlying database. Each database table is shown on the diagram as an Entity

Specify a Controller Name of PlaceController, and choose API controller with read/write actions, using Entity Framework from the Template dropdown. Select Place within the Model class drop-down, and DatabaseEntities from the Data context class drop-down. Click the Add button to create this new Controller.

A new Controller class will be shown on screen, and this has a number of pre-built methods for adding, updating and deleting Place records. Extra logic can be added in here if needed, such as validating the data being sent from the client, but for this tutorial we will just use the controller as-is.

Launch the .NET project by pressing F5, or by choosing the Start Debugging option within the Debug menu. We’ll now explore how all of this is going to work in practice. When the web browser launches, we want to fire off a request to this new Place Controller. Do this by appending the following on to the URL: /api/place – so, for example http://localhost:55434/api/place, where 55434 is the port number of your particular instance of IIS Express.

You should now see an XML file displayed in the browser, and this contains the contents of the database Place table. The reason for this is because the .NET Web API has routed the request based on the URL path and sent it to the Place controller.

In the browser, a GET request is sent to the server when calling this URL, which by default will get routed to the GetPlaces method inside the Place controller. This in-turn gets the Entity Data Model to retrieve all Place records from the database.

This same basic URL will also be used to add, update and delete records, and this works based on the type of HTTP request that’s sent to the server, and operates in the same way by the .NET Web API routing the request based on its type to the appropriately named controller method:

  • POST request to /api/place – a new record is created (PostPlace)
  • PUT request to /api/place – an existing record is updated (PutPlace)
  • DELETE request /api/place – an existing record is deleted (DeletePlace)

The generated Place Controller uses pre-built methods to add, update and delete records. It uses the Entity Data Model to query the database

We can’t test out the different request types directly in the browser, because navigating to the URL will simply fire off a GET request. So instead we’ll need to do this within the Sencha Touch project we created in part one of this tutorial.

Sencha Touch project

Before loading the PlacesTouchApp within Sencha Architect, move the folder from its current location to within the .NET project’s folder, so it should now reside within C:\Sencha Architect Apps\Places\Places\PlacesTouchApp\. Then load the PlacesTouchApp from this directory within Sencha Architect.

The first thing to do within the project is remove the hard-coded data from the Places Store. To do that, click the Clear button next to the data property on the Places Store, from within the Config panel.

Next, select the Store’s Ajax proxy, and set the URL to http://localhost:55434/api/place. Right-click on the Store and select the Load Data option. The data should be loaded from the .NET app, and because it’s being requested as part of an Ajax request, the JSON format is requested, instead of XML. You should see all the Places displayed in the List.

To ensure the Store loads its data automatically when the application starts, set the autoLoad property to true on the Store.

REST proxy

To allow instances of our Place records to be managed via RESTful calls to the server, drag a REST proxy from the Toolbox on to the Place Model in the Project Inspector. This will handle the create, read, update and destroy calls and pass them on to our .NET Web API project.

Set the url property on the Rest Proxy accordingly; for example. http://localhost:55434/api/place.

Form buttons

We’re going to enable existing records to be edited and deleted. For that, we’ll need to add two new buttons on to the PlaceDetail form. To begin with, drag a new Panel inside of the PlaceDetail form, just below the View on Map button. Now drag and drop two Buttons inside this Panel, and set the text of the first button to Save, and the other to Delete. Add a custom attribute to the Save button by typing the following inside of the Filter or Quick Value Set field:

action:”Save”

Then click the Add button. Add a similar custom attribute to the Delete button:

action:”Delete”

Set the ui property of the Save button to confirm, and the ui property of the Delete button to decline.

On the Panel containing the buttons, set the layout property to hbox, so the buttons are positioned horizontally inside the Panel, and set the flex property of both buttons to 1. This specifies the aspect ratio of each button’s width.

Adding a REST Proxy to the Model and setting its url property allows the app to easily send RESTful calls to the server to create, read, update and delete records

Finally, on the same Panel, set the margin property to 20 0 0 0. This specifies the margin that’s applied to the four sides of the Panel, with the first value (20) relating to the top margin.

Data validation

Before saving a record, we want to make sure that all the required fields are populated. Sencha Touch has built-in Validators, which can be assigned to a model so that when a record is saved we can check on the validity of the record’s values.

Drag and drop a Presence Validation on to the Place Model. Set both the displayName and field properties on the Presence Validation to name. Add an extra Presence Validation to the Place Model, this time for the location field.

Controller actions

Now we’re ready to add the Save and Delete functionality to the frontend app. Select the Place Controller within the Project Inspector and select the option to add a new Controller Action.

For the new Action, set the Target Type to Ext.Button, and the Event Name to tap. This will add a new Controller Action within the Place Controller.

Rename the Controller Action by setting the fn (shorthand for function) value to onSaveTap, then set the controlQuery to [action=Save], which will associate this Action with the Save button created earlier. Double-click on the Controller Action and populate the code:

var me = this;var form = this.getPlaceDetail();var values = form.getValues();var record = form.getRecord();record.beginEdit();record.set(values);if (record.isValid()) {record.endEdit();record.save({success: function() {me.getMainView().pop();}});}else {record.cancelEdit();Ext.Msg.alert("Error", "There are errors with the record.");}

In the code above, we’re getting a reference to the Place Detail form, along with the values from the form, and the instance of the Record. A type of clientside transaction is then commenced by calling beginEdit on the record, and this stops any changes being relayed to the Store. The values from the form are then applied to the Record, and we check to ensure it’s valid.

If the data in the record is valid we call endEdit, and the values are applied to the Store, then we call the save method on the record and this fires off a request to our .NET Web API controller.

If the data isn’t valid (for instance, an empty field value) then we call cancelEdit on the record, which cancels any changes and reverts the record back to its original state, and finally we show a validation message to the user.

This shows the ultimate configuration of the Place Controller within Sencha Architect. There should now be 5 Actions and 3 References within the Controller

Add another Controller Action, this time for the Delete button. Again, set the Target Type to Ext.Button, and the Event Name to tap. Set the fn value to onDeleteTap, then set the controlQuery to [action=Delete]. Add the following code to the Delete Controller Action:

var me = this;var form = this.getPlaceDetail();var record = form.getRecord();record.erase({success: function(){me.getMainView().pop();}});

This code fires off a DELETE request to the .NET Web API controller, and on success will return the user to the list of places.

We’ll add one final Controller Action, and this will be for when the user changes the centre position of the Map. We want to capture the new latitude and longitude coordinates, and apply these values to the hidden fields in the Place Detail form.

First, select the PlaceMap in the Project Inspector, and set the userAlias property to placemap. Then select the Place Controller and add a new Controller Action, with a Target Type of Ext.Map, and an Event Name of centerchange. Set the controlQuery of this new Controller Action to .placemap. Add the following code to this Controller Action:

var form = this.getPlaceDetail();form.setValues({lat: center.lat(),lng: center.lng()});

Whenever the user moves the map around, the above code will fire. This will get the latitude and longitude from the centre of the map using some Google Maps API calls, and these values will be applied to the hidden fields in the form.

Finish

There – that’s the application finished. Next, launch your WebKitbased browser – such as Google Chrome – and navigate to the Sencha Touch application’s URL within the .NET project: http://localhost:55434/PlacesTouchApp/app.html. You should now have the capability to update and delete records, as well as updating the position of places by moving the centre point of the map around.

During development, .NET applications run much more easily when using the built-in IIS Express server. By default, this only allows connections from the local machine, so to test your mobile app from a physical device you’ll need to tweak a few IIS Express settings to enable remote connections. There is a short tutorial on how to do that here.

By viewing the Network tab within Google Chrome’s Developer Tools, it’s possible to see the requests being sent off to the .NET Web API Controller

Once you’ve enabled remote connections, the URL of the .NET Web API Place controller will need to be updated on the Model and Store proxies, by replacing localhost with either an IP address or a host name.

Application packaging

Although in these tutorials we’ve produced a pure web application, Sencha also offers the Sencha Mobile Packager, which provides a way to package your web app in a native shell, instantly making it app-store ready, and allowing it to access additional device capabilities, such as in-app purchases and searching a user’s contacts.

Conclusion

This two-part tutorial should have helped reinforce the benefits of working with the Sencha Touch framework, and using Sencha Architect to aid in the application design and development process. Data can be seamlessly loaded from and submitted to a remote data source without having to worry about manually handling Ajax requests and responses – for instance just specify a URL on the Store, and the framework does all the magic work for you.

HTML5 clearly has a long future ahead of it, with new features being added regularly, such as the addition of new APIs for accessing device capabilities that were traditionally only available to native apps. In iOS 6 for instance, Apple introduced the capability within Safari to directly upload files and add camera access without the need for packaging the web app as a native app. Other improvements in iOS 6 included a faster JavaScript engine, and a Remote Web Inspector for remote debugging of web apps using Safari 6 on a Mac, making debugging even easier.

According to Strategy Analytics, sales of mobile devices featuring a HTML5 capable browser should triple in 2013 to reach 1 billion devices, compared with 336 million devices in 2011. With figures such as this, releasing your mobile application via the HTML5 route using Sencha’s frameworks and tools clearly offers a fast and practical way to target different mobile platforms with ease.

How to build an app: discover 35 great tutorials at Creative Bloq.