Sencha Ext JS 7.7 is Here – Discover What’s New and Exciting – LEARN MORE

Tailoring Your Ext JS 5 Application for a Multi-Device World

January 28, 2015 2 Views

Introduction

Given today’s proliferation of devices and form factors, optimizing our applications for all of these possibilities has become increasingly complex. While we can use CSS to respond to some of these environmental conditions, typical Ext JS applications also contain generous amounts of JavaScript. Coding for device specifics in JavaScript may be simple in some cases, but can also quickly get out of hand. The good news is that Ext JS 5.1 gives you several powerful tools for managing this complexity.

Many of these techniques have been discussed in previous articles. It will be helpful to see them all explained together and compared to each other, so you can select the right tool for the job at hand.

Inline Techniques

The best way to understand these tools is to consider a trivial use case. Let’s say we want to have different titles for a panel for some devices. Perhaps a longer, descriptive title when there is room and an abbreviated title for smaller screens. The goal of this exercise is not to explain the best way to accomplish this particular goal, but rather to make sure the techniques we use don’t get obscured by details that might come from a more complex use case.

platformConfig

The platformConfig property is new to Ext JS 5.1 and can be used in class declarations or to configure object instances based on the current platform or device classification. We might use this in a view like so:
Ext.define(‘App.view.summary.Manufacturing’, {
extend: ‘Ext.panel.Panel’,

title: ‘Mfg Summary’,

platformConfig: {
desktop: {
title: ‘Manufacturing Summary’
}
}
});

The above has the same result as the direct approach below:
Ext.define(‘App.view.summary.Manufacturing’, {
extend: ‘Ext.panel.Panel’,

title: testForDesktop ? ‘Manufacturing Summary’
: ‘Mfg Summary’
});

The idea is not to compare the merits of platformConfig versus a ternary operator, but rather to see that platformConfig is treated as part of the class declaration. As such, this approach will work regardless of the base class. One reason to prefer platformConfig over inline logic is to keep a view as data-only which can be safely sent in JSON format.

One can also use platformConfig to configure instances:
Ext.define(‘App.view.summary.Manufacturing’, {
extend: ‘Ext.panel.Panel’,

items: [{
xtype: ‘panel’,

platformConfig: {
desktop: {
title: ‘Manufacturing Summary’
},
‘!desktop’: {
title: ‘Mfg Summary’
}
}
}] });

The best direct translation of the above would be:
Ext.define(‘App.view.summary.Manufacturing’, {
extend: ‘Ext.panel.Panel’,

items: [
Ext.merge({
xtype: ‘panel’
},
testForDesktop ? {
title: ‘Manufacturing Summary’
} : {
title: ‘Mfg Summary’
})
] });

In this use of platformConfig, however, the merging is handled by the initConfig method. In other words, providing a platformConfig property as an instance configuration is only supported for classes that call initConfig in their constructor. This is the case for Ext.Widget, Ext.Component, most of the data package classes (such as stores), and any class that uses Ext.mixin.Observable.

Similar to how using platformConfig in a class declaration modifies the class body, using platformConfig on an instance config modifies the initial configuration of the object.

responsiveConfig

Ext JS 5.0 introduced responsiveConfig and the mixin and plugin that enable it. The difference with responsiveConfig is that its rules and properties are not only evaluated when creating instances but whenever device orientation or viewport size changes. While this adds some overhead compared to platformConfig, it is likely to be more efficient than handling these yourself by listening to window resize or orientation change.

If we adjust our criteria slightly, we can make the title respond to device size instead of device classification (“deskop”).
Ext.define(‘App.view.summary.Manufacturing’, {
extend: ‘Ext.panel.Panel’,
mixins: [‘Ext.mixin.Responsive’],

responsiveConfig: {
‘width >= 600’: {
title: ‘Manufacturing Summary’
},
‘width < 600’: {
title: ‘Mfg Summary’
}
}
});

Because the above class has a responsiveConfig, we benefit from using the mixin here and avoid creating a plugin for each instance. When used on a component instance, however, we must use the responsive plugin instead:
Ext.define(‘App.view.summary.Manufacturing’, {
extend: ‘Ext.panel.Panel’,

items: [{
xtype: ‘panel’,
plugins: ‘responsive’,

responsiveConfig: {
‘width >= 600’: {
title: ‘Manufacturing Summary’
},
‘width < 600’: {
title: ‘Mfg Summary’
}
}
}] });

It is important to remember that width in the above is viewport width, not component width.

Ext.app.Profile

Using platformConfig and responsiveConfig, we have made surgical adjustments to configurations. Using profiles, we can manage much larger differences. Profiles were added to Ext JS 5.1 and are part of the Application Architecture originally introduced by Sencha Touch.

We typically use a profile to switch out the top layers of the application via the mainView (or Viewport). This means we can create an entirely different view for the application as determined by the active profile.

Profiles are only available to applications that use Ext.app.Application, which must list its desired profiles like so:
Ext.define(‘App.Application’, {
extend: ‘Ext.app.Application’,

profiles: [
‘Desktop’,
‘Mobile’
] });

In each Profile class the isActive method determines whether that particular profile should be the active profile:
Ext.define(‘App.profile.Desktop’, {
extend: ‘Ext.app.Profile’,

mainView: ‘App.view.desktop.Main’,

isActive: function () {
return Ext.os.is.Desktop;
},

launch: function () {
console.log(‘Launch Desktop’);
}
});

You can try this fiddle from a tablet or desktop and see a very basic use of profiles. You can also look at the code here.

Profiles do not have to use the mainView config and may instead choose to provide a launch method to do whatever custom processing is required. Only the active profile’s launch method will be called.

Sencha Cmd Build Profiles

If you are using Sencha Cmd to build your application, there are also build profiles, which were introduced with Sencha Cmd 5.0. Build profiles allow you to have a single HTML page (the “application”) and multiple built versions that are selected at load time. This is similar to how an Ext.app.Profile instance is selected, but instead selects the build that should be loaded. The basis for this selection could be environmental, based on a stored cookie, or perhaps even saved on the server in the user’s account.

Regardless of how the determination is made, only the code and CSS needed for the selected build will be loaded. This is again unlike Ext.app.Profile which must include in the build all of the code necessary for all profiles.

The Ext JS Kitchen Sink example uses multiple build profiles to enable theme and locale switching. These two build-time selections are adjusted for each build profile, and the query parameters in the URL are used to select the desired build profile. This is done in the “index.html” file like so:
var Ext = Ext || {};
Ext.beforeLoad = function(tags){
var theme = location.href.match(/theme=([w-]+)/),
locale = location.href.match(/locale=([w-]+)/);

theme = (theme && theme[1]) ||
(tags.desktop ? ‘crisp’ : ‘crisp-touch’);
locale = (locale && locale[1]) || ‘en’;

Ext.manifest = theme + “-” + locale;
};

Conclusion

With all these tools at hand, it is just a matter of picking the right tool for the particular situation. For simple tuning at load time, there is platformConfig. For more dynamic conditions, there is responsiveConfig. To change things on a larger scale, there is Ext.app.Profile.

And if you need an application that looks completely different on tablets than it does on desktop (or perhaps even based on user authorization), you could consider Sencha Cmd build profiles. Build profiles can remove the tablet overhead from the desktop build and vise versa.

Since there cannot be a “one size fits all” solution, Ext JS provides different tools that combine efficiency and flexibility. They each work together to help ensure that your application will be a natural fit for the widest possible range of devices.

Leave a Reply

Your email address will not be published. Required fields are marked *

Ready to get started?

Create an account now!

Latest Content
Highlights of Virtual JS Days 2024

Highlights of Virtual JS Days 2024 From February 20-22, 2024, we held the third Virtual…

From the GM’s Desk 2023: An Exciting Year for Sencha & Ext JS 7.7

We are past the midpoint of 2023 and we are very proud of what we…

Sencha MVP Spotlight: Animap - The Historical Research Tool with Andy Allord

Welcome to our Developer Spotlight Series, where we showcase the remarkable talents and achievements of…

See More

Hi,
We have released Architect 3.5 supporting Ext JS 6 classic. Please use the architect forum for discussing specific requests. Thanks.

by Sandeep on April 27, 2016

Hi Josue,

Also apologies for not seeing your question sooner. I think the best way to understand the “better” choice is to consider what is being adjusted. Profiles are high level things and adjust views or launch the application. Whereas platformConfig is more surgical and allows you to tune things inside class declarations or when creating instances. So really both are useful because they solve things the other is not particularly good at. You cannot use platformConfig to do view alias mappings like you can in a Profile, for example.

Hopefully that helps clear things up a bit. :)

Good luck!

by Don Griffin on April 13, 2016

Hi Shreeraj,

Sorry for not noticing the question earlier. I wish I could give you some insight on Architect futures. Have you tried using mixins to share code between controllers?

by Don Griffin on April 13, 2016

Leave a Reply

Your email address will not be published. Required fields are marked *

coming soon

Something Awesome Is

COMING SOON!