Over a million developers have joined DZone.

Implementing Sencha Touch Device Profiles

· Java Zone

Navigate the Maze of the End-User Experience and pick up this APM Essential guide, brought to you in partnership with CA Technologies

In this tutorial you will learn how to implement device profiles in a Sencha Touch application. To accomplish this, you will build an app that will display slightly different user interfaces depending on whether it is running on a mobile phone or a tablet.

The app is based on the app we created in my Sencha Touch Charts tutorial and it displays a number of charts depicting performance indicators for a hypothetical business. When run on a tablet device, the app will render a single view with two charts that depict performance indicators of the business. Here’s a screenshot:

Sencha Touch Device Profiles example

On a mobile phone, what users will see is a tabbed user interface with two tabs. Each tab contains a chart depicting a business performance indicator:

Sencha Touch Device Profiles example

Sencha Touch device profiles adapt the app experience to the different devices

A device profile is a way to define the behavior of a Sencha Touch application based on the device where the app is running. Using Sencha Touch device profiles you can control the presence or absence of entire features when the app runs on any particular device or family of devices. You can adapt the look and feel of the app to the device in question, and also take advantage of native features present on the device.

With device profiles, you place application code that is tied to a particular device into its own modules or classes. You can leave code that applies to all devices, such as data storage and access to server resources, in classes shared by all profiles. This results is less code duplication and lower development costs.

You can create as many profiles as devices or device families you would like to target. Sencha Touch offers a simple way to define them, but before we look into this subject in detail, let’s talk about the sample application.

Designing the views for the Tablet profile

As I said earlier, the app we will create in this tutorial displays a number of charts depicting performance indicators for a hypothetical business. Let’s go ahead and create a mockup of the single view that will be rendered when the application is run on a tablet device. The mockup will give us a better idea of how the view should look, and which Sencha Touch components we need to use to build it.

This is the UI that we are after:

Sencha Touch Device Profiles example

And this is the mockup:

profiles-4

The app’s tablet UI will consist of a Sencha Touch Container component that hosts a Titlebar component and two inner Containers. The Titlebar will host a Refresh button, and the two inner Containers in turn host a Container and a Chart component. The Container on top of the Chart will render the Chart’s title.

Designing the views for the Phone profile

Let’s repeat the process for the Phone UI. These are the final UI and its mockup:

profiles-1
Sencha Touch Device Profiles example

Unlike the Tablet UI, The Phone UI will not render the two charts at the same time. It uses a Sencha Touch Tabpanel component to render one or the other chart alternatively. We will use Sencha Touch Device Profiles to create these two different UIs.

Shared components

We already discussed that one of the advantages of using device profiles is that it allows us to minimize code duplication by sharing application modules or components among profiles. We are going to take this approach and define the charts used in the application as separate components that will not be tied to any profile. Each profile will instantiate and configure the charts as needed so they render as expected when the app runs on a tablet or a phone.

That is enough Ui design for now. Let’s start building the app.

Using Sencha Cmd to create an application template

First, we will generate an application template that we can use as a starting point. Let’s perform the following steps in order to create the template:

  1. Install Sencha Cmd.
  2. Install Compass.
  3. Download the Sencha Touch SDK.
  4. Open a Terminal or Command window in your Sencha Touch SDK directory.
  5. In your terminal window, run: sencha generate app -path=”c:\projects\senchatouch\profiles” -name profiles

This will produce a Sencha Touch application in the c:\projects\senchatouch\profiles directory, as depicted below:

Sencha Touch Device Profiles example

After this step, you can browse to the index.html file in your favorite Webkit browser and verify that the template app comes up on the screen.

Declaring the Sencha Touch device profiles

Next, we need to make the app aware that we intend to use device profiles. Let’s open the application’s definition and declare the profiles that we will use. In the app.js file, we will add the profiles config as follows:

Ext.application({
    name: 'dashboard',

    requires: [
        'Ext.MessageBox'
    ],

    profiles: ['Phone','Tablet'],

    icon: {
        '57': 'resources/icons/Icon.png',
        '72': 'resources/icons/Icon~ipad.png',
        '114': 'resources/icons/Icon@2x.png',
        '144': 'resources/icons/Icon~ipad@2x.png'
    },

    isIconPrecomposed: true,

    startupImage: {
        '320x460': 'resources/startup/320x460.jpg',
        '640x920': 'resources/startup/640x920.png',
        '768x1004': 'resources/startup/768x1004.png',
        '748x1024': 'resources/startup/748x1024.png',
        '1536x2008': 'resources/startup/1536x2008.png',
        '1496x2048': 'resources/startup/1496x2048.png'
    },

    launch: function() {

    },

    onUpdated: function() {
        Ext.Msg.confirm(
            "Application Update",
            "This application has just successfully been updated to the latest version. Reload now?",
            function(buttonId) {
                if (buttonId === 'yes') {
                    window.location.reload();
                }
            }
        );
    }
});

Note that we will also remove the initialization code from the launch function, as we will use the launch function of each profile to initialize the profile’s views.

Now we will work on the profiles themselves. We will create a profile definition for each profile that we declared.

Adding the Tablet device profile

Normally, we place the profiles definitions in files that we save in the app/profile directory of a project. To define the Tablet profile, let’s create the tablet.js file in the app/profile directory.

Sencha Touch Device Profiles example

We will add the code below to the file:

Ext.define('dashboard.profile.Tablet', {
    extend: 'Ext.app.Profile',
    config: {
        name: 'Tablet',
        views: ['Main']
    },
    isActive: function () {
        return Ext.os.deviceType !== 'Phone';
    },
    launch: function () {
        Ext.fly('appLoadingIndicator').destroy();
        Ext.Viewport.add(
            Ext.create('dashboard.view.tablet.Main')
        );
    }
});

Associating Sencha Touch device profiles with device features

You can think of a profile as a set of application features that is only active when a certain condition or conditions are true. These conditions are generally connected to the presence or absence of certain device features.

You define these conditions through the isActive method. As you can see in the code, the tablet profile we just created will be active when the detected device is not a phone.

Note that we are not limited to detecting the device type. We can use any number of conditions inside the isActive method. For example, we could take into account the screen size, or the presence or absence of any device capabilities that Sencha Touch can detect.

Inside the profile file you can also define the views that will be active when the given profile is active, as well as a launch function that will be invoked when the profile is active. The profile’s launch function is invoked before the app’s launch function during the app’s initialization process. Normally, you want to use the profile’s launch function to generate the profile’s UI, which is what we are doing in our sample app.

For our application, we are defining a Main view, and the launch function is simply destroying the app’s loading indicator and adding an instance of the Main view to the viewport.

Note that you can still use the app’s launch function to initialize profile-independent modules of the app.

Creating the main view of the Tablet profile

Let’s go ahead and create the app/view/tablet/Main.js file, which will contain the definition of the main view associated with the Tablet profile. Note how we are placing the file in the app/view/tablet directory, in accordance with the practice of placing profile-specific views in a directory named after the profile’s name.

Sencha Touch Device Profiles example

This is the code that we will add to the file:

Ext.define("dashboard.view.tablet.Main", {
    extend: "Ext.Container",
    requires: [
        "Ext.TitleBar"
    ],
    alias: "widget.main",
    config: {
        layout: {
            type:"vbox"
        },
        items: [
            {
                xtype: "titlebar",
                docked: "top",
                title: "Executive Dashboard",
                items: [
                    {
                        iconCls: "refresh",
                        align: "right",
                        handler: function () {
                            var parent = this.up("titlebar").getParent();
                            parent.fireEvent("refreshRequestCmd", parent);
                        }
                    }
                ]
            },            
            {
                xtype: "container",
                flex: 1,
                layout: "hbox",
                items: [
                    {
                        xtype: "container",
                        flex: 1,
                        layout:"vbox",
                        items:[
                            {
                                xtype: "container",
                                docked: "top",
                                html: "Hours Worked vs. Hours Billed",
                                margin: "15 0 0 15"
                            },
                            {
                                html: "Hours Worked vs. Hours Billed chart goes here"
                            }
                        ]
                    }
                ]
            },
            {
                xtype: "container",
                flex: 1,
                layout: "hbox",
                items: [
                    {
                        xtype: "container",
                        flex: 1,
                        layout: "vbox",
                        items: [
                            {
                                xtype: "container",
                                docked: "top",
                                html: "Value Worked vs. Value Billed",
                                margin: "15 0 0 15"
                            },
                            {
                                html: "Value Worked vs. Value Billed chart goes here",
                            }
                        ]
                    }
                ]
            }                
        ]
    }
});

As we discussed when creating the mockups, the view contains a Sencha Titlebar instance and a couple of containers where we will place the charts and their titles. Since we have not created the charts, which will be shared by both the Tablet and Phone profiles, we are going to use the container’s html config to render a message indicating where the charts will be placed.

We should be able to test this view in Google Chrome. If we fire up the app, go to Chrome’s developer tools and set the device emulation mode to any tablet device, we should be able to see the Tablet view as depicted below.

Sencha Touch Device Profiles example

Adding the Phone profile

To define the Phone profile, let’s create the phone.js file in the app/profile directory.

Sencha Touch Device Profiles example

We will define the profile like so:

Ext.define('dashboard.profile.Phone', {
    extend: 'Ext.app.Profile',
    config: {
        name: 'Phone',
        views: ['Main']
    },
    isActive: function () {
        return Ext.os.deviceType === 'Phone';
    },
    launch: function () {
        Ext.fly('appLoadingIndicator').destroy();
        Ext.Viewport.add(Ext.create('dashboard.view.phone.Main'));
    }
});

As you can see in the isActive function, the Phone profile will be active when the detected device is a phone. As in the Tablet profile, the launch function destroys the app’s loading indicator and adds an instance of the Main view to the viewport. This of course is the main view associated with the Phone profile, which we will create next.

Creating the main view of the Phone profile

Now it is the turn of the Phone view. Let’s create the app/view/phone/Main.js file. Once again, we are placing the file in a directory named after the profile’s name.

Sencha Touch Device Profiles example

The file will contain the following view definition:

Ext.define("dashboard.view.phone.Main", {
    extend: "Ext.Container",
    requires: [
        "Ext.TitleBar"
    ],
    alias: "widget.main",
    config: {
        layout: {
            type:"fit"
        },
        items: [
            {
                xtype: "titlebar",
                docked: "top",
                title: "Executive Dashboard",
                items: [
                    {
                        iconCls: "refresh",
                        align: "right",
                        handler: function () {
                            var parent = this.up("titlebar").getParent();
                            parent.fireEvent("refreshRequestCmd", parent);
                        }
                    }
                ]
            },
            {
                xtype: "tabpanel",
                tabBarPosition: "bottom",
                items: [
                    {
                        title: 'Hours',
                        iconCls: 'time',
                        layout: "vbox",
                        items: [
                            {
                                xtype: "container",
                                docked: "top",
                                html: "Hours Worked vs. Hours Billed",
                                margin: "15 0 0 15"
                            },
                            {
                                xtype: "hrschart"
                            }
                        ]
                    },
                    {
                        title: "Value",
                        iconCls: "star",
                        layout: "vbox",
                        items: [
                            {
                                xtype: "container",
                                docked: "top",
                                html: "Value Worked vs. Value Billed",
                                margin: "15 0 0 15"
                            },
                            {
                                xtype: "valuechart"
                            }
                        ]
                    }
                ]
            }
        ]
    }
});

The difference between the Table view and the Phone view that we just created is that, as described in the mockups, the Phone view contains a TabPanel component with two tabs, where each tab will render a chart.

To test this view in Google Chrome, we can go in the developer tools and set the device emulation mode to any phone device. The app should render the Phone view as depicted below.

Sencha Touch Device Profiles example

Defining the Sencha Touch data Model used by the charts

We need a Model class that defines the data fields used by the charts. We will create the HrsAndValueByYear.js file in the app/model directory. The file will contain the model definition below.

Ext.define("dashboard.model.HrsAndValueByYear", {
    extend: "Ext.data.Model",
    config: {
        fields: [
            { name: "hrsbilled", type: "int" },
            { name: "hrsworked", type: "int" },
            { name: "valuebilled", type: "int" },
            { name: "valueworked", type: "int" },
            { name: "year", type: "int" }
        ]
    }
});

Let’s not forget to declare the model in the models config of the application, in the app.js file:

models:[
"HrsAndValueByYear"
],

Adding the Sencha Touch data Store

We also need to create a data store to feed the charts. In the app/store directory, let’s create the HrsAndValueByYear.js file, and define a Sencha Touch store using the following code.

Ext.define("dashboard.store.HrsAndValueByYear", {
    extend: "Ext.data.Store",
    config: {
        data: [
            { year: "2010", hrsbilled: 130000, hrsworked: 143000, valuebilled: 475000, valueworked: 500000 },
            { year: "2011", hrsbilled: 149000, hrsworked: 158000, valuebilled: 270000, valueworked: 285000 },
            { year: "2012", hrsbilled: 153000, hrsworked: 149000, valuebilled: 325000, valueworked: 380000 },
            { year: "2013", hrsbilled: 165000, hrsworked: 171000, valuebilled: 265000, valueworked: 270000 }
        ]
    }
});

Initially we will not use the model or a proxy in the store. We will simply hardcode some data using the data config, which makes it easier to test the charts. Once we are sure that the charts are correctly displaying the store’s data, we will stop using the data config, and define a proxy so the store can retrieve its data from the server.

The store also needs to be declared in the stores config of the application:

stores:[
'HrsAndValueByYear'
],

Creating the “Hours” chart

The first chart that we will add to the app is the “Hours Worked” chart. Let’s create the HrsChart.js file in the app/view directory, containing the following definition:

Ext.define("dashboard.view.HrsChart", {
    extend: "Ext.chart.CartesianChart",
    requires: [
        "Ext.TitleBar",
        "Ext.chart.CartesianChart",
        "Ext.chart.series.Line",
        "Ext.chart.axis.Numeric",
        "Ext.chart.axis.Category",
        "Ext.draw.sprite.Circle"
    ],
    alias: "widget.hrschart",
    config: {
        flex: 1,
        xtype: "chart",
        store: "HrsAndValueByYear",
        cls: "chart",
        innerPadding: 20,
        animate: true,
        series: [
            {
                type: "line",
                xField: "year",
                yField: "hrsworked",
                title: "Hours Worked",
                style: {
                    stroke: "#003366",
                    lineWidth: 3
                },
                marker: {
                    type: "circle",
                    stroke: "#003366",
                    radius: 5,
                    lineWidth: 3
                },
                label: {
                    field: "hrsworked",
                    color: "#000",
                    display: "over",
                    font:"10px Helvetica"
                }
            },
            {
                type: "line",
                xField: "year",
                yField: "hrsbilled",
                title: "Hours Billed",
                style: {
                    stroke: "#6d0060",
                    lineWidth: 3
                },
                marker: {
                    type: "circle",
                    stroke: "#6d0060",
                    radius: 5,
                    lineWidth: 3
                },
                label: {
                    field: "hrsbilled",
                    color: "#000",
                    display: "over",
                    font: "10px Helvetica"
                }
            }
        ],
        axes: [
            {
                type: "numeric",
                position: "left",
                title: {
                    fontSize: 15,
                    text: "Hrs"
                },
                minimum: 130000,
                maximum: 180000,
                grid: {
                    even: {
                        fill: "#f9f9f9"
                    }
                }
            },
            {
                type: "category",
                position: "bottom"
            }
        ]
    }
});

This chart is an instance of the CartesianChart Class. Pay attention to is the requires object, where you need to list the classes that you will use to define the series, axis, and sprites you will use for the chart’s markers.

Note also the store, series and axes configs. While the store config is self explanatory, I would recommend that you review the Sencha Touch Charts documentation for the series and axes config so you are aware of the multiple ways to configure these chart features.

For example, in the series config, the most important properties are the xField and yField, which should match the model’s fields you want to display on the chart.

We should now add the chart to the views config of the application, in the app.js file:

views: [
    "HrsChart",
    "Main"
]

Creating the “Value” chart

The second chart is the Value chart. In the app/view directory, let’s create the ValueChart.js file. This is the code that goes in the file:

Ext.define("dashboard.view.ValueChart", {
    extend: "Ext.chart.CartesianChart",
    requires: [
        "Ext.TitleBar",
        "Ext.chart.CartesianChart",
        "Ext.chart.series.Line",
        "Ext.chart.axis.Numeric",
        "Ext.chart.axis.Category",
        "Ext.draw.sprite.Circle"
    ],
    alias: "widget.valuechart",
    config: {
        flex: 1,
        xtype: "chart",
        store: "HrsAndValueByYear",
        cls: "chart",
        innerPadding: 20,
        animate: true,
        series: [
            {
                type: "line",
                xField: "year",
                yField: "valuebilled",
                title: "Value Billed",
                style: {
                    stroke: "#789700",
                    lineWidth: 3
                },
                marker: {
                    type: "circle",
                    stroke: "#789700",
                    radius: 5,
                    lineWidth: 3
                },
                label: {
                    field: "valuebilled",
                    color: "#000",
                    display: "over",
                    font: "10px Helvetica"
                }
            },
            {
                type: "line",
                xField: "year",
                yField: "valueworked",
                title: "Value Worked",
                style: {
                    stroke: "#9d5d00",
                    lineWidth: 3
                },
                marker: {
                    type: "circle",
                    stroke: "#9d5d00",
                    radius: 5,
                    lineWidth: 3
                },
                label: {
                    field: "valueworked",
                    color: "#000",
                    display: "over",
                    font: "10px Helvetica"
                }
            }
        ],
        axes: [
            {
                type: "numeric",
                position: "left",
                title: {
                    fontSize: 15,
                    text: "Value"
                },
                minimum: 250000,
                maximum: 500000,
                grid: {
                    even: {
                        fill: "#f9f9f9"
                    }
                }
            },
            {
                type: "category",
                position: "bottom"
            }
        ]
    }
});

Now, let’s add the chart to the views config of the application in the app.js file.

views: [
'HrsChart',
'ValueChart',
'Main'
],

Adding the charts to the Tablet view

Next you will add an instance of each chart to the Tablet view of the app in the view/tablet/Main.js file:

Ext.define("dashboard.view.tablet.Main", {
    extend: "Ext.Container",
    requires: [
        "Ext.TitleBar"
    ],
    alias: "widget.main",
    config: {
        layout: {
            type:"vbox"
        },
        items: [
            {
                xtype: "titlebar",
                docked: "top",
                title: "Executive Dashboard",
                items: [
                    {
                        iconCls: "refresh",
                        align: "right",
                        handler: function () {
                            var parent = this.up("titlebar").getParent();
                            parent.fireEvent("refreshRequestCmd", parent);
                        }
                    }
                ]
            },            
            {
                xtype: "container",
                flex: 1,
                layout: "hbox",
                items: [
                    {
                        xtype: "container",
                        flex: 1,
                        layout:"vbox",
                        items:[
                            {
                                xtype: "container",
                                docked: "top",
                                html: "Hours Worked vs. Hours Billed",
                                margin: "15 0 0 15"
                            },
                            {
                                xtype: "hrschart"
                            }
                        ]
                    }
                ]
            },
            {
                xtype: "container",
                flex: 1,
                layout: "hbox",
                items: [
                    {
                        xtype: "container",
                        flex: 1,
                        layout: "vbox",
                        items: [
                            {
                                xtype: "container",
                                docked: "top",
                                html: "Value Worked vs. Value Billed",
                                margin: "15 0 0 15"
                            },
                            {
                                xtype: "valuechart"
                            }
                        ]
                    }
                ]
            }                
        ]
    }
});

To add the charts we made changes in two places in the Main.js file. We replaced the placeholder for the Hours chart, which looked like this:

{
html: "Hours Worked vs. Hours Billed chart goes here"
}

With the following config:

{
xtype: "hrschart"
}

We also replaced the placeholder for the Value chart, which looked like this:

{
html: "Value Worked vs. Value Billed chart goes here",
}

With the following config:

{
xtype: "valuechart"
}

Another quick check in the browser with device emulation set to a Tablet should show that both charts are in place:

Sencha Touch Device Profiles example

Adding the charts to the Phone view

We will take the same approach to add the charts to the Main view of the Phone profile, replacing the charts’ placeholders with instances of each chart:

Ext.define("dashboard.view.phone.Main", {
    extend: "Ext.Container",
    requires: [
        "Ext.TitleBar"
    ],
    alias: "widget.main",
    config: {
        layout: {
            type:"fit"
        },
        items: [
            {
                xtype: "titlebar",
                docked: "top",
                title: "Executive Dashboard",
                items: [
                    {
                        iconCls: "refresh",
                        align: "right",
                        handler: function () {
                            var parent = this.up("titlebar").getParent();
                            parent.fireEvent("refreshRequestCmd", parent);
                        }
                    }
                ]
            },
            {
                xtype: "tabpanel",
                tabBarPosition: "bottom",
                items: [
                    {
                        title: 'Hours',
                        iconCls: 'time',
                        layout: "vbox",
                        items: [
                            {
                                xtype: "container",
                                docked: "top",
                                html: "Hours Worked vs. Hours Billed",
                                margin: "15 0 0 15"
                            },
                            {
                                html: "Hours Worked vs. Hours Billed chart goes here",
                            }
                        ]
                    },
                    {
                        title: "Value",
                        iconCls: "star",
                        layout: "vbox",
                        items: [
                            {
                                xtype: "container",
                                docked: "top",
                                html: "Value Worked vs. Value Billed",
                                margin: "15 0 0 15"
                            },
                            {
                                html: "Value Worked vs. Value Billed chart goes here",
                            }
                        ]
                    }
                ]
            }
        ]
    }
});

Let’s go back to Chrome’s dev tools and set device emulation to a phone, which should show the Main phone view with the two charts in place:

Sencha Touch Device Profiles example

Defining the Sencha Touch controller

In good MVC fashion, we will use a controller to refresh the data for the charts. Let’s create the Main.js file in the app/controller directory, and add the code below:

Ext.define("dashboard.controller.Main", {
    extend: "Ext.app.Controller",
    config: {
        refs: {
            mainTabletView: "mainTablet",
            mainPhoneView: "mainPhone"
        },
        control: {
            mainTabletView: {
                refreshRequestCmd: "onRefreshRequestCmd"
            },
            mainPhoneView: {
                refreshRequestCmd: "onRefreshRequestCmd"
            }
        }
    },
    onRefreshRequestCmd: function (view) {
        Ext.getStore("HrsAndValueByYear").load();
    }
});

The first thing that we do in the controller is to declare the mainTabletView and mainPhoneView references in the refs config. Then, in the control config, we use these references to set up an event handler for the refreshRequestCmd event. We called this event handler onRefreshRequestCmd.

Inside the onRefreshRequestCmd method, all we need to do is call the load method of the HrsAndValueByYear store. We can obtain a reference to the store using the Ext.getStore() method.

This is another example of how to take advantage of device profiles to promote code re-use in an application. We are using a single controller, and a single function to refresh the charts in both the Tablet and Phone profiles.

Finally, we need to declare the controller in the controllers section of the app.js file:

controllers: [
'Main'
],

Adding a proxy to the store

There is a small change you need to make before taking care of the server-side code – You need to add a proxy to the store so we can pull data from the server. Let’s jump back to the store/HrsAndValueByYear.js file in the app/store directory, and modify its code as follows.

Ext.define("dashboard.store.HrsAndValueByYear", {
    extend: "Ext.data.Store",
    config: {
        proxy: {
            type: 'ajax',
            url: '../../services/dashboard.php?metric=hrsandvaluebyyear',
            model: 'dashboard.model.HrsAndValueByYear',
            reader: {
                type: "json",
                rootProperty: "items"
            }
        },
        autoLoad: true
    }
});

We just removed the store’s data config and added the proxy config, which defines an ajax proxy with its url, model and reader properties. Note that the url property refers to a dashboard.php page, and it contains the “metric” query string parameter to tell the page what data it needs to send to the client.

The server-side code that feeds the Sencha Touch charts

You will use PHP as the language for the server-side page that will provide the data for the HrsAndValueByYear store. The code is so simple that you will not have any difficulties translating it to your preferred server-side language if PHP is not what you normally use.

Let’s create the dashboard.php file in the services directory. This is the code that we will add to the file:

$metric = $_GET["metric"];
$result = "";

switch ($metric) {

case "hrsandvaluebyyear":
$result = "{success:true,items:[{ year: '2010', hrsbilled: '130000', hrsworked: '143000', valuebilled: '475000', valueworked: '500000' },{ year: '2011', hrsbilled: '149000', hrsworked: '158000', valuebilled: '270000', valueworked: '285000' },{ year: '2012', hrsbilled: '153000', hrsworked: '149000', valuebilled: '325000', valueworked: '380000' },{ year: '2013', hrsbilled: '165000', hrsworked: '171000', valuebilled: '265000', valueworked: '270000'}]}";
break;
}

header('Cache-Control: no-cache, must-revalidate');
header("content-type:application/json");
echo($result);

For the purposes of this tutorial we are simply hardcoding the data in the server-side page. In a production-grade app we will probably need to make a database call in order to obtain this data. I will not go that far in this tutorial, but you should try it as soon as you have an opportunity.

After this round of changes we can go in the browser and check that the application working as originally designed.

Sencha Touch Device Profiles example
Sencha Touch Device Profiles example

Conclusion

In this tutorial you learned how to use Sencha Touch Device Profiles while putting together an application that adapts its user interface to the device it is run on.

You can use this a powerful feature to optimize the user’s experience on the different devices that you target, and to reduce your development and maintenance costs by reusing modules and codes that can be shared across different devices.

Download the source code

Download the source code for this Sencha Touch tutorial here:

Want to learn more about mobile web apps?

Check out my books and tutorials, which cover interesting subjects related to Sencha Touch and jQuery Mobile.

Thrive in the application economy with an APM model that is strategic. Be E.P.I.C. with CA APM.  Brought to you in partnership with CA Technologies.

Topics:
java ,php ,mobile ,javascript ,tips and tricks ,tools & methods ,sencha touch ,device profiles

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 }}