Contents of document: Ø The Class System Sencha Touch 2 Ø The Component System Quick Start Ø The Event System Ø Selectors Ø Data Package Ø And more…

The Class System hondaMotercycle.isExpensive(); //returns false hondaMotercycle.getPrice(); //returns 2000 The Sencha Touch class system allows creation of new JavaScript classes, providing inheritance, dependency loading, var suzukiGSXR = Ext.create('SuperBike', { mixins, configuration options, and more. buildYear: 2015, topSpeed: 300, price: 12000, Ext.define('Motercycle', { model: 'gsxr1000', config: { brand: 'Suzuki' buildYear: null, }); topSpeed: null, suzukiGSXR.isExpensive(); //returns true price: null suzukiGSXR.getModel(); //returns "gsxr1000" }, constructor: function (config) { this.initConfig(config); You may notice the use of some functions that we have not }, explicitly defined, for example getModel(). The Sencha Touch isExpensive: function () { class system does us a favor and generates 4 types of return this.getPrice() > 2000; convenience functions: } • Getter – return current value; getName() }); • Setter – set new value; setName() Ext.define('SuperBike', { • Applier – called by setter, execute logic when extend: 'Motercycle', property changes; applyName() config: { • Updater – called by setter, execute logic when the model: null, value for a property changes; updateName() brand: null }, Please note that the applier and updater isSuzuki: function () { functions require implementation. The return this.getBrand() === 'Suzuki'; applier function requires a return of the value }, that will be set to the property. The updater isExpensive: function () { TIP gets fired after the applier and does not return this.getPrice() > 10000; handle a return, rather, it just informs of a } value change });

Let’s assume we want to round the price of the Motercycle to We defined a Motorcycle class with a Superbike subclass. The the nearest 1000. To do so we would implement the Motorcycle class has some basic properties defined in the applyPrice function in the Motercycle class: config object. Besides class properties we defined some basic class methods as well. The Superbike class extends the Motorcycle class and thereby inherits its properties and applyPrice : function (newPrice, oldPrice) { methods. In addition we are able to define a unique return Math.round(newPrice / 1000) * 1000; implementation of each method. }

We can instantiate a class by using Ext.create instead of the new keyword. Using the former leverages Sencha Touch’s Usage: dynamic dependency loader and allows for using aliases, as well as easily applying the config object. hondaMotercycle.setPrice(1995); hondaMotercycle.getPrice(); //returns 2000 var hondaMotercycle = Ext.create('Motercycle', { buildYear: 2002, topSpeed: 180, price: 2000 });

Based on: ‘Sencha Touch - Open-Source HTML5 Mobile Web Development Made Easy’ by Stan Bershadskiy Sencha Touch provides the JsonReader, JsonWriter, Data Package XmlReader and XmlWriter classes. These reader and writer types are specified on the proxy definition.

A crucial requirement for many mobile applications is to Example Store with Proxy consume data from external sources as well as maintain internal application specific data. For these situations Sencha Touch provides the Data Package, a set of classes responsible Ext.define('MyApp.store.Cars', { for loading, storing, manipulating and saving data. extend: 'Ext.data.Store', requires : [ Three types of classes generally leverage the data package: 'Ext.data.reader.Json', • Model – an entity that represents a single record, 'Ext.data.writer.Json' defining its fields, validation, associations and ], conversion parameters. config: { • Store – collection of model instances with support for model: 'MyApp.model.Car', sorting, filtering, and grouping proxy: { • Proxy – medium that interacts with the remote or type: 'ajax', local data source and performs the necessary reading url: '/cars', and writing operations. reader: { type : 'json', Models rootProperty: 'cars' Models are data objects that are managed in your application. } Models are defined by a set of data fields. Each field is defined } by its name, type, and optional defaultValue. } }); Supported field types are: • string Proxies can be attached to both Models and • int Stores. The result is the same, the Store will • float be looking for a Proxy config on itself and if • boolean none is present it will look for it on the • date Model. However, if the Proxy is defined

inside the Model, multiple Stores using the A convert function can also be implemented on the field to TIP same Model don’t have to define the config. perform processing on the field’s data. Furthermore, defining a Proxy inside a

Model allows you to save and load an Here is a sample model: instance of that Model without needing a

Store Ext.define('MyApp.model.Car', {

extend: 'Ext.data.Model', To access a store from anywhere in the application you can config : { use the Ext. getStore() function and pass in either a defined fields : [ storeId or the store’s classname, excluding namespace. { name: 'make', type: 'string' },

{ name: 'model', type: 'string' }, Example of loading data into a store: { name: 'topSpeed', type: 'int' },

{ name: 'price', type: 'float' }, { name: 'options', type: 'auto' } Ext.getStore("Cars").load();

] } });

Data Proxies There are four proxies provided by Sencha Touch that can be used in a Store or Model. • LocalStorage – saves data to localStorage • Memory – saves data in memory, extremely volatile • Ajax – communicates with a RESTful resource on the same domain • JsonP – communicates with a service on an external domain using JSON-P

Each proxy type implements four basic operations create, read, update, and destroy.

When interacting with Server Proxies, there is a need for serializing the data sent and retrieved from the server. For this

Based on: ‘Sencha Touch - Open-Source HTML5 Mobile Web Development Made Easy’ by Stan Bershadskiy

The Component System

Common Components Useful Properties Component Purpose & Functions The Sencha Touch Component system is the foundation of all the visual elements in the framework. The Component system Component Basic Visual Class xtype Ext.Component cls makes full use of the Class system’s dependency injection and xtype: component hierarchical support. Every Sencha Touch view class is a tpl subclass of Ext.Component, and thus follows its lifecycle. data show() / hide() Components are generally defined by an xtype. An xtype is a /destroy() shortcut for the full component Class name allowing for lazy instantiation. Using xtypes to instantiate components allows Container Manages Component layout Ext.Container rendering and items the creation of the object to be deferred to when it’s actually xtype: container arrangement scrollable needed, thus saving resources. add(component) / remove(component) There may be times when you want to display multiple components, either all at once or individually. The Panel Ext.Panel Container designed showBy(component) xtype: panel to float as overlays Ext.Container class exists for these situations. Containers provide functionality for adding child Components, removing Toolbar Ext.Toolbar Docked containers title Components and specifying a Layout that determines how xtype: panel that generally hold left / right these components are displayed. Buttons and a Title ui Button Ext.Button Basic tappable text xtype: button component ui iconCls iconAlign

Based on: ‘Sencha Touch - Open-Source HTML5 Mobile Web Development Made Easy’ by Stan Bershadskiy Tab Panel Container that allows tabBarPosition Ext.create('Ext.Container', { Ext.tab.Panel user to easily switch fullscreen: true, xtype: tabpanel between components using a Toolbar layout: 'hbox', items: [ MessageBox Modal Container for Ext.Msg.alert(title, { Ext.Msg displaying alerts and msg, callback) xtype: 'panel', Ext.MessageBox notifications. Ext.Msg Ext.Msg.confirm(titl html: 'message list', is a singleton that e, msg, callback) flex: 1 allows for creation of Ext.Msg.prompt(titl }, predefined e, msg, callback) { MessageBox xtype: 'panel', instances. html: 'message preview', flex: 2 Carousel Container that allows ui Ext.Carousel user to switch active direction } xtype: carousel components by indicator ] swiping next() / previous() });

List Container of store Vbox layout Ext.dataview.List dynamically rendered itemTpl xtype: list components from a itemCls Data Store onItemDisclosure grouped indexBar

Form Panel Panel that contains a getValues() / Ext.form.Panel set of form fields to be setValues(data) xtype: displayed submit(options, formpanel params, headers)

Form Fields Base class for all data name Ext.field.Field input form fields label / labelCls / xtype: field labelAlign inputCls required

Card layout Sometimes you want to show several information screens Layouts information on a small device screen. TabPanels and Carousels both enable you to see one screen of many at a Layouts describe the sizing and positioning time, and underneath they both use a Card Layout. on Components inside your app. For example, an email client might have a list of messages pinned to the left, taking up one Card Layout takes the size of the Container it is applied to third of the available width, and a message viewing panel in the and sizes the currently active item so as to completely fill the rest of the screen. Container. It then hides the rest of the items, allowing you to change which one is currently visible, but only showing one We can achieve this using an hbox layout and its ability at once: to ‘flex’ items within it. Flexing means that we divide the available area based on the flexof each child component, so to achieve our example above we can set up flexes like shown in the following image:

Fit layout The Fit Layout is probably the simplest layout available. All it does is make a child component fit the full size of its parent Container.

In the code for this layout we need to specify the ‘hbox’ layout on any Container, then supply a flex parameter for each of the child components (Panels in this case) as follows: Docking

Based on: ‘Sencha Touch - Open-Source HTML5 Mobile Web Development Made Easy’ by Stan Bershadskiy Every layout is capable of docking items inside it. Docking Conditional Processing enables you to place additional Components at the top, right, XTemplate supports 4 basic comparison operations: if, else- bottom, or left edges of the parent Container, resizing the other if, else, and switch. items as necessary. Examples:

{make} {model} is ridiculously fast somewhat fast ridiculously slow
XTemplate
{make} is

Template based components have been the norm in many web luxurious applications thanks to frameworks like Mustache, Handlebars, Closure, and more. Sencha Touch provides first class economical functionality for templating through the Ext.XTemplate class.

The Ext.XTemplate class supports not only simple data identifiers but also: Math Support • Array traversal The following math operators are supported: + - * / • Conditional processing • Basic math functionality Example: • Execute arbitrary code • Execute custom template functions When defining an XTemplate, the tpl tag is reserved for

Top Speed in km/h is {topSpeed * 1.6}
template commands.

Array Traversal Executing Arbitrary Code Looping through an array is done with the tpl for keyword with It is possible to execute JavaScript code while in the scope of the value being either "." or a property path. the template by using [] inside an expression.

While iterating the array, there are two special While executing code inside a template expression there are variables {#} and {.}. {#} represents the current several special values available: TIP index of the array + 1. {.} represents the value • out – output array of the template of the element at the current index • values – values in the current scope • parent – values of parent data object • xindex – if in looping template, then the 1-based Example assuming the data is an array of Car objects: index

• xcount – if in looping template, then the total length of array

{make} {model}
Example: Example assuming the data is an object with a cars property
{[values.make.toUpperCase() + " - " + that holds arrays grouped by make: values.model.toLowerCase()]}
{#} {.}
Custom Template Function
When defining our Ext.XTemplate instance, we can implement functions that will be executed by the template.

Example: (See next page)

Based on: ‘Sencha Touch - Open-Source HTML5 Mobile Web Development Made Easy’ by Stan Bershadskiy var tpl = new Ext.XTemplate ( '', The Event System '

{make} is', '', A crucial part of the Component and Application life cycle in 'fast!', general are the events that are fired at different stages. These '', events can be triggered from some interaction with a 'slow', component or be fired after some arbitrary business logic is '', executed. Most importantly, for each event we can configure '', simple listeners to handle these events. { isFast : function (make) { We react to events by attaching event listeners on a given return (make === "Ferrari"); component through the listeners property or the on() } function where we pass in an object where the event name } maps to a callback. When we define the listeners, we can also ); attach the context that the callback gets executed in via the scope property.

Theming myButton.on({ tap : function () { console.log("button tap"); An important aspect of any application is styling and theming. }, Sencha Touch applications are styled using SASS and compiled scope : this with Compass. });

Compass requires Ruby to be installed on your computer and can be installed using rubygems. Common Events Fired by Components More information can be found here: • painted – fires when element becomes rendered on TIP http://compass-style.org/ More information on the screen SASS can be found at: http://sass-lang.com/ • show / hide – fires when view component, generally a modal, is shown or hidden using show() and hide() Common Global SASS Variables • updatedata – fires when data of component is updated

Variable Description Common Events Fired by Containers $base-color Primary color that most elements • activate / deactivate – fires when an item in the reference container is activated or deactivated $base-gradient Primary gradient color most elements • activeitemchange – (card layout only) fires when reference the actively visible item is changed by setActiveItem() $font-family Font family used throughout the theme add / remove – fires when components are added $page-bg-color Background color of fullscreen • or removed from container components

Sencha Touch allows us to also manage events that are fired Common Global SASS Mixins by the DOM elements that these components render. These DOM elements are of type Ext.dom.Element. The elements Mixin Description fire events for native browser gesture interactions. pictos- Include a base64-encoded icon to be iconmask($name) used with Tab Buttons. Name must Here is an example of attaching event listeners for both match icon‘s file name in component and element events. You can also see some resources/themes/images/ simple event handler implementation as well as firing of default/pictos without extension custom events. @include pictos-iconmask(‘wifi2‘); bevel-text($type) Add text shadow or highlight. $type is Ext.define("MyApp.view.tooltip.Tooltip", { either shadow or highlight. extend: "Ext.Panel", stretch() Stretch an element to parent‘s xtype: "tooltip", bounds config: { ellipsis() Apply element text-overflow to use /* ... */ ellipsis }, initialize : function () { var me = this; me.element.on({ tap : me.onTap, touchstart : me.onTouchStart, /* Continued on the next page */

Based on: ‘Sencha Touch - Open-Source HTML5 Mobile Web Development Made Easy’ by Stan Bershadskiy Selector touchend : me.onTouchEnd, Purpose Example Type scope : me xtype Select component Ext.ComponentQuery.que }); based on its xtype ry(‘. formpanel‘); myContainer.down(‘.butt me.on({ on‘); show : me.onShow, itemId / id Select component Ext.ComponentQuery. hide : me.onHide, based on its itemId query(‘#myFirstPanel‘); scope : me or id property myContainer.down(‘#sub }); mit‘); Attribute Select a component myFormPanel.down("fiel me.callParent(); based on its xtype [name= userName]); }, and some property value that is set on it onTap : function (evtObj) { Nested Select a child of a Ext.ComponentQuery.que this.fireEvent('close'); Selector matched selector ry(‘panel > toolbar‘); }, Multiple Select children that Ext.ComponentQuery. onTouchStart : function (evtObj) { Selector match multiple query(‘formpanel, var closeButton = evtObj.getTarget(".close-button"); selectors carousel‘); if (closeButton) { Ext.fly(closeButton).addCls('pressed'); } We can also query on DOM Elements. The }, Ext.dom.Element class provides query() and onTouchEnd : function (evtObj) { down() functions. Here however we use CSS var closeButton = evtObj.getTarget(".close-button"); TIP selectors. More information on CSS Selectors closeButton && can be found here: Ext.fly(closeButton).removeCls('pressed'); http://www.w3.org/TR/selectors/ }, onShow : function () { /* ... */ }, onHide : function () { this.destroy(); } });

Common Events Fired by Elements • tap - fires for every tap • doubletap - fires for a double tap • taphold / longpress - fires for when you hold a tap for > 1 second • touchstart / touchend - fires for when the touch starts and finishes • drag - continuously fires for dragging • dragstart / dragend - fires when dragging begins and finishes • pinch / rotate - continuously fires for pinch and rotate gestures swipe - fires when there is a swipe; the event property holds the swipe direction

Selectors

One of the most useful functionalities of Sencha Touch and ExtJS as well is the support for finding the instance of a component or DOM element. Similar to jQuery’s $ selector, Sencha Touch provides the child(), up(), down() and query() functions to each Container class. These functions take in a ComponentQuery Selector and return either the first component (child(), up(), down()) or an array of all matching components (query()). You can also query for components on a global scope by using the Ext. ComponentQuery singleton, which has a query() method.

Based on: ‘Sencha Touch - Open-Source HTML5 Mobile Web Development Made Easy’ by Stan Bershadskiy List of pictos icon set available in Sencha Cheat Sheet

List of Sencha defined xtypes xtype Class ------actionsheet Ext.ActionSheet audio Ext.Audio button Ext.Button component Ext.Component container Ext.Container image Ext.Img label Ext.Label loadmask Ext.LoadMask map Ext.Map mask Ext.Mask media Ext.Media panel Ext.Panel segmentedbutton Ext.SegmentedButton sheet Ext.Sheet spacer Ext.Spacer title Ext.Title titlebar Ext.TitleBar toolbar Ext.Toolbar video Ext.Video carousel Ext.carousel.Carousel carouselindicator Ext.carousel.Indicator navigationview Ext.navigation.View datepicker Ext.picker.Date picker Ext.picker.Picker pickerslot Ext.picker.Slot slider Ext.slider.Slider thumb Ext.slider.Thumb tabbar Ext.tab.Bar tabpanel Ext.tab.Panel tab Ext.tab.Tab viewport Ext.viewport.Default

DataView Components ------dataview Ext.dataview.DataView list Ext.dataview.List listitemheader Ext.dataview.ListItemHeader nestedlist Ext.dataview.NestedList dataitem Ext.dataview.component.DataItem

Form Components

------checkboxfield Ext.field.Checkbox By default Sencha Touch 2 does not include datepickerfield Ext.field.DatePicker the full icon list to keep the Stylesheet emailfield Ext.field.Email lightweight. If you wanted to include an icon field Ext.field.Field hiddenfield Ext.field.Hidden TIP that is not available in the default list below, input Ext.field.Input you would have to add the following to your numberfield Ext.field.Number .SCSS file: passwordfield Ext.field.Password @include icon('network'); radiofield Ext.field.Radio searchfield Ext.field.Search selectfield Ext.field.Select Default included pictos iconCls list (see icons above) sliderfield Ext.field.Slider spinnerfield Ext.field.Spinner action maps textfield Ext.field.Text add more textareafield Ext.field.TextArea arrow_down organize textareainput Ext.field.TextAreaInput arrow_left refresh togglefield Ext.field.Toggle arrow_right reply urlfield Ext.field.Url arrow_up search fieldset Ext.form.FieldSet bookmarks settings formpanel Ext.form.Panel compose star delete team download time favorites trash home user info locate

Based on: ‘Sencha Touch - Open-Source HTML5 Mobile Web Development Made Easy’ by Stan Bershadskiy stores : [ MVC 'Cars', 'Users' ], Previously we introduced Views and Models. Now, it’s time to views : [ connect them together to form a full-fledged application by 'LoginPanel', adding in a Controller concept. 'CarDetailView' ], Controller controllers : [ Sencha Touch implements the Controller through the 'Main' Ext.app.Controller class. The Controller is responsible for ], responding to events that your components may fire. There are launch : function () { two core configuration properties of the Controller: ref and Ext.fly('appLoadingIndicator').destroy(); control. } }); • refs – execute ComponentQuery to locate first component instance to match selector and generate getter function • control – listen to events from ComponentQuery Packaging / Deploying selectors or refs and attach listeners

Controller Example: Since Sencha Touch is a full-fledged application framework it is only fitting that there exists a tool supporting the application’s entire life cycle. Ext.define('MyApp.controller.Main', { extend: 'Ext.app.Controller', Sencha Cmd is a command line utility that provides config: { automated tasks from generating a new application to refs: { generating components of an existing application to loginPanel: 'loginpanel', loginButton: 'loginpanel button[text="login"]' preparing an application for production deployment. }, control: { Sencha Cmd contains the following major features: loginpanel: { • Code generation validate: 'onLoginPanelValidate' • Optimized Sencha specific JavaScript minifier }, and obfuscator loginButton: { • Native Packager to wrap mobile web tap: 'onLoginButtonTap' application as a native hybrid application using } Phonegap/Cordova } • Workspace management allows sharing code }, between applications onLoginPanelValidate : function () { this.getLoginPanel().validate(); }, You may notice that when we specify the onLoginButtonTap : function () { models, stores, views, and controllers we do this.getLoginPanel().submit(); not include the necessary namespaces. You } can also specify models, stores and views in }); TIP Controllers. In the Ext. app.Application and Ext.app.Controller class, Sencha Touch’s Application loader looks up the dependency based on the context provided in the configuration. Now that we have Models, Views, and Controllers defined we need a way to connect them together so that they can coexist and work with each other. For this we have the Example Usage Ext.app.Application class that connects Models, Controllers, Profiles, Stores and Views together by instantiating them through the dependency loader. Generate New Application Sencha generate app MyApp /path/to/MyApp All Sencha Touch applications begin with a call to the Ext.application function that creates an Application instance. Generate Models, Controller and Views Example Application instance: cd /path/to/MyApp sencha generate model Car make:string,model:string,price:float sencha generate controller Main Ext.application({ sencha generate view CarDetailView name: 'MyApp', models : [ 'Car', Generate New Application 'User' ], sencha app build [-d ‘testing’|’production’|’package’|’native’] /* Continued on the right */

Based on: ‘Sencha Touch - Open-Source HTML5 Mobile Web Development Made Easy’ by Stan Bershadskiy Be careful of spaghetti Code/Scope Sencha Best Practices Don’t define all your components in one big file or all inline – it will be a nightmare to debug and your scope will be all over the place. Make things easy and split each component Avoid hardcoded ids and Ext.getCmp definition into its own file and extend the base class to add Sencha Touch generates a unique random id and registers it your configuration and extra methods and behavior. This with the ComponentManager. It is possible to force a static id way you can simply instantiate these components where you for your component and retrieve it using the Ext.getCmp(id) need them keeping things nice and tidy and loosely coupled. function. However, as your project and number of developers grow, the chance that the static ID that you thought would stay Make sure you use Namespaces unique diminishes. Thus, it is recommended to use either Again, it’s all about organization. Utilize the built-in itemId, which assigns a pseudo-id and is scoped locally to the namespace capabilities of Sencha Touch to organize your Container, or to use ComponentQuery. components and classes so it’s easy to navigate later. Typically you would want to do this by functional module, for Useful References: example, MyApp.Users for all the User management code. I • http://extjs.eu/writing-a-big-application-in-ext/ like to mirror this namespace structure with the folder structure so everything is dead easy to find. Avoid Controller refs with multiple instances Generally, it is a good practice to make your components Use Get/Set methods or Static references generic enough to be reusable or extensible throughout your Don’t be tempted to delve into a component’s items or application. Often, when defining a Controller ref, it is forgotten toolbar collections to get a reference to a particular button or that it only returns the first instance that matches the panel using ‘comp.get(0)’ or comp.getTopToolbar().get(1)’ ComponentQuery selector. Thus, it is recommended to use a syntax. If you ever add items to these collections the ComponentQuery inside your event listener to determine the references will be broken and you will have to track them proper instance of the desired Component you need. down. In a big application this becomes a mammoth task, which will introduce bugs. Avoid over-nesting Containers Sencha Touch Containers do an excellent job in maintaining Save yourself some hassle and, in the extended class, create a their child components and making sure they are displayed get method for the necessary components, which delves into properly. To accomplish this task, there is a lot of calculation the collection, so when you do add more items you know and manipulation of the DOM involved in the layout managers there is only one method to be updated. Or, if you aren’t of these containers. It is easy to begin carelessly nesting these concerned about lazy instantiation, define your buttons and containers inside of each other. When the containers are nested items as class variables and reference them that way so you it becomes much more processor intensive to calculate how to won’t need to make any updates when new items are added. display the components and their underlying DOM elements properly. Name your xtypes carefully Name your xtypes the same as your class, including Reduce reliance on built-in Components namespaces, so you can track down the actual class Many of Sencha Touch’s components are designed to be definition very easily. Additionally, it is recommended to widgets that are meant to be items of a Container and arranged write your xtypes with lowercase letters only. by the layout manager. While this is acceptable in certain simple situations, it often results in unnecessary utilization of Always have the Docs open the DOM. Sencha Touch allows us to create custom views by The API documentation is your best friend – it should be leveraging XTemplate and controlling the markup of our your first port of call when running into problems or when component to be as minimal as necessary. trying something new. Intellisense for Ext JS isn’t quite up to the standards of Visual Studio for .NET so we can’t get away Do not edit the Framework code with being so lazy – the docs are the answer to this. They are Yes, delve into it, read it, test it, learn from it – but don’t edit it! well laid out and easy to navigate, so make use of them! If you start making changes to the core library, whether it is the JS or CSS, you are planting a ticking time-bomb into your Use Plugins and User Extensions application. When you come to upgrade to a newer version all If you want a component to do something that is fairly those changes will be lost and you will have to traipse through generic and a common functional requirement it is likely that trying to figure out where things are broken! someone has already coded it and released it as a Plugin or an Extension. Take some time before coding it from scratch If you want to alter the behavior/look of the framework then go (unless you have the time – it’s a great way to learn!) to for it but do it by overriding the class (be it a JS class or a CSS search the forums and the web for a pre-made solution class) or method in a separate script file. By doing this you can (Sencha marketplace). remove it if necessary and keep track of it when it comes to reviewing those changes when new versions are released.

References • http://www.swarmonline.com/technology/articles-and-videos/20-things-to-avoiddo-when-getting-started-with-ext-js-and-sencha-touch/ • Sencha Touch - Open-Source HTML5 Mobile Web Development Made Easy’ by Stan Bershadskiy

Based on: ‘Sencha Touch - Open-Source HTML5 Mobile Web Development Made Easy’ by Stan Bershadskiy Always have a Utility file We keep all the html fragments inside SCRIPT tag, so these It is recommended to always maintain a Utility file in your html elements are not added in the DOM and you can access application. Here we can manage all general information like the data simply by accessing innerHTML of the Script tags. API url details, function to handle errors, showing alert This works perfectly fine while creating builds and template messages etc. You can make a class with a statics object and codes in Views become easy to maintain. put it in a separate “util” folder under the “app” folder. Sample tpl

Utility.js var touchTeam = Ext.create('Ext.DataView', { store: 'MyStore', Ext.define('MyApp.utils.Utility', { itemTpl: document.getElementById('tpl_sales_rep_input').innerHTML statics: { }); BASE_URL: 'http://example.com/API/' } }); Recommended debugging chain How you should go about fixing a problem…

Some where in the application 1. Check your Code (it’s easy to misspell config options, miss commas etc) // Use properties and methods as follows

var url = MyApp.utils.Utility.BASE_URL 2. Refer to the Documentation (you might be missing console.log(url) // returns "http://example.com/API/" a related config option)

Maintain all templates inside index.html 3. Step into the Framework’s Source Code (break In almost all the examples and tutorials you will see people add into the code around the error and try to see what’s tpl or itemTpl with lots of html tags as strings. It becomes very going wrong, you’ll likely discover a config option irritating to debug, change and format because most of us use you’ve missed, or realize something you expected IDEs and html inside Javascript files. One way to solve this is by to be there isn’t instantiated yet) adding the templates inside the index.html file like this: 4. Search the Forum (it’s almost a guarantee that Templates inside index.html someone will have had the same problem and posted a question about it) Build and load Widgets on Demand When possible, build and load widgets on demand. Don’t in the app.

References • http://www.innofied.com/sencha-touch-coding-guidelines-you-should-follow-part-1/ • http://miamicoder.com/2015/sencha-touch-best-practices-for-user-interface-development/

Based on: ‘Sencha Touch - Open-Source HTML5 Mobile Web Development Made Easy’ by Stan Bershadskiy Design for Offline Mode and Optimize Access to Local Data Your application should function without having to talk to the server all the time, unless there are very specific requirements to connect frequently. This approach has implications for your UI design. Your data-bound widgets should read data cached in local storage, local files or local databases that you refresh as needed when there is a connection with the server. Get only the data needed, cache it locally, and perform fast reads and writes.

Avoid Tight Coupling of UI Elements Don’t make a widget be aware or depend on the existence of another widget. For those widgets that react to events triggered by other widgets, use controllers to handle the events. If two widgets are governed by different controllers, don’t let controller A be aware of widget B that’s under controller B. Use controller to controller links via events.

With this approach it’s easier to modify parts of the UI without impacting other UI elements or application modules.

Don’t Block the UI Don’t make your users wait. Prevent the UI from becoming unresponsive when the app is executing long-running operations, such as server calls and local data loading and filtering. Trigger long running operations and use callbacks to be notified upon completion. Use timeouts to limit wait periods. Be mindful of timers and functions that execute on intervals and might block the UI. Avoid complex drawing and animations, they affect UI performance.

Well formed code Use tools like JSLint, JSHint, Esprima, etc. to help you detect errors and potential problems in your JavaScript code. These tools also help you structure your JavaScript code to increase readability and maintainability.

References • https://speakerdeck.com/arthurakay/best-practices-for-enterprise--applications

Based on: ‘Sencha Touch - Open-Source HTML5 Mobile Web Development Made Easy’ by Stan Bershadskiy