Introduction

Openbravo Mobile Core Infrastructure UI components are based on Enyo's component concept. A component can be the representation of either a Collection or a Model, or a stand-alone UI widget (e.g. Button).

This article aims to be an introduction/overview on the main development concepts behind Openbravo Mobile and how are related to each other.

Prerequisites

You should be proficient in JavaScript programming language. More info at Openbravo Developer's Guide prerequisite article.

Acknowledgments

As Enyo and Backbone.js are technologies used by Mobile Core, you will find code and information extracted from their sites.

Code

Part of the code in this article is available from the Mercurial repository web-pos-doc:

$ hg clone https://bitbucket.org/iperdomo/web-pos-doc

What's Enyo?

Enyo is a cross-platform framework that provides powerful features to build complex Web applications in a modular way:

What's Backbone.js?

Backbone.js is a library that "gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions".

Note: Openbravo Mobile Core doesn't use the concept of View in Backbone.js

Kinds, Components and Controls

The Enyo building blocks for writing applications are Kinds, Components and Controls:

Kind: Is a constructor-with-prototype (like a class) that has advanced features like prototype-chaining (inheritance)

Component: The enyo.Component, is the basic building block of Enyo, is a kind that can publish properties, expose events, and contain other components

Control:enyo.Control is a component that controls a DOM node (i.e., an element in the user interface). Controls are generally visible and the user often interacts with them directly. Things like buttons and input boxes are obviously controls, but in Enyo a control may become as complex as an entire application

Kind

You can think of a kind like a class in Java. Using the enyo.kind function you can define your own kinds e.g.

enyo.kind({name: 'OB.MyKind', // name of the kind you're defining
kind: enyo.Component// reference to the parent kind from which will inherit all properties});
var x = new OB.MyKind(); // a new constructor function OB.MyKind is available, you can create an instance using the new operator

Notes:

You can omit the kind attribute when defining a new kind, Enyo will default it to enyo.Control

Is a best practice to namespace your code. The name attribute supports using 'DBPrefix.KindName', and will create the DBPrefix object if is not available

Remember that OB and OBPOS are reserved namespace objects, you must not define new kinds inside this objects as it may collide with Openbravo code

More info on the special attributes in the enyo.kind function at Enyo documentation: Creating Kinds

Component

"A component is an Enyo kind that can publish properties, expose events, and contain other components. It may be useful to think about components as owning a set of content (other components) and providing inputs (methods and property setters) and outputs (events and property getters). A component controls the content it owns and sends messages to its owner in the form of events."

Published Properties

A Component can publish properties. "For convenience, published properties are automatically provided with setter, getter, and changed methods."

enyo.kind({name: 'OB.MyComponent',
kind: enyo.Component,
active: false,
published: {
count: 0},
countChanged: function(oldValue){// this function will get called when the setCount() finishes
console.log('countChanged: ' + this.count);
}});
var comp = new OB.MyComponent();
comp.setCount(2); // a setCount is now available since the count property is a published one
comp.setCount(comp.getCount() + 1); // using the provided getter and setter, will trigger the countChanged
comp.count = 1; // will not trigger the countChanged since is not using setter

Notes:

When publishing a property a setter is created using the CamelCase version of the property name, e.g. count -> setCount

You can define a propertyNameChanged (e.g. countChanged) method that will get executed after the setter finishes. Notice that if someone modifies directly then count property, this method will not get executed

Not all properties of your kind/component/control needs to be a published property, e.g. active property in the previous example is not a published property

Components in Components

A Component can contain another component(s)

enyo.kind({name: 'OB.MyComp1',
kind: enyo.Component});
enyo.kind({name: 'OB.Main',
kind: enyo.Component,
components: [// defining the components attribute (an Array) you can append child components within a kind{name: 'c1', kind: 'OB.MyComp1'},
{name: 'c2', kind: 'OB.MyComp1'}// each nested component requires a name and the kind attribute]});
var main = new OB.Main();
console.log(main.$.c1); // You can access the contained components using the $ hash and the component name