Dynamics Mobile Apps introduced a data-biding concept, allowing the developer to easily “bind” user controls to data.

Each view displayed on the screen contains two basic parts:

  • Layout
  • Code

The layout of the view defines the visual appearance of the view in terms of visual components ( controls ). During the execution, the view layout is translated to HTML5 DOM tree. The developer can design the views by using the built-in layout designer. The developer can also drop the standard HTML control on the view’s surface and compose advanced UI by using pure HTML5.

Each view is rendered during runtime as div element.

However, it is not likely the developer to access the page’s DOM element directly.

The developer can drag and drop different control on the design surface. Each control dropped on the design surface will generate a corresponding HTML DOM element with the ID specified by the developer.

If the developer drops a TextBox control with id mytextbox, the system will generate input element with id equal to mytextbox.

The developer can use jQuery syntax to manipulate the DOM elements. If we want to set the text of the textbox we can use the following syntax:

$('#mytextbox').val('123-5678');

We can also make the textbox readonly like this:

$('#mytextbox').attr('readonly','readonly');

Check out the jQuery documentation for more information about how to manipulate the DOM tree.

Data binding with code

The developer will need to populate the visual elements like textboxes, lists , drop-down lists and others with the data from the mobile storage or remote services.

Let’s have have two inputs (textboxes) dropped in the view. We will want to query the local mobile storage for a particular customer and set their values to the customer’s number and title . We assume that the textboxes are given unique identifiers – textbox1 and textbox2. We will do this normally in the view’s view_Load() method by using jQuery syntax like this:

view_Load:function(){
//query local storage by using ORM style query
$ma.bo.SLA.Customer.fetch('CU00123',function(customer){
if(customer){
$('#textbox1').val(customer.number);//set the text
$('#textbox1').val(customer.title);//set the text }
}

We may want to give the user the ability to change the values of the text boxes and then saving them into the mobile database. You will do this in the view_Commit() method like this:

view_Commit:function(){
var customer = $ma.bo.SLA.Customer.fetch('CU00123');//query local storage by using ORM style query
if(customer){
customer.number = $('#textbox1').val(); //read the textbox value
customer.title=$('#textbox2').val(); //read the textbox value
customer.update(); // persist into the mobile storage
}
}

This approach works just fine, but is too verbose when dealing with bigger number of UI elements. It is also quite a challenge to populate a list of elements on screen. In order to solve this challenge, the developers can use a declarative data binding.

Declarative Data Binding

The declarative data binding approach eliminates the need to populate the visual element with code and allows the developer to directly “embed” data-binding expressions into the view’s layout.

Here comes the need to use the dataModel() method of the view.

Each view can have a dataModel() method. This method(or func) is executed once during the lifecycle of the view. You can think of it like we’re creating a single class instance (if you come from the Object Oriented Programming world ) of the dataModel class. The instance is assigned to the view’s _dataModel member.

Let’s see the way we can implement the upper mentioned example using declarative data binding:

We will create the view and will drop two textboxes – one for the customer’s number and one for the customer’s title.

We will declare the view’s data model in the view’s code section:

dataModel:function(){
var me = this;
$ma.bo.SLA.Customer.fetch('CU00123',function(cust){
me.customer=cust;
}); }

This way we have declared that view’s dataModel has one member called customer. We also perform ORM-style a database query to assign the member with a specific customer business object.

We have to switch to the view layout in MACloud Studio click over the first textbox and click then over the Props button to open the controls’s properties window.
We have to find the Data-Binding box in the properties window and enter the following:

text:customer.number

This way we instruct the textbox to get its value( e.g. to perform binding ) from the number member of the customer member of the view’s data model. In other words it assumes that we have declared a member in our dataModel called customer and then it assumes that our customer member has member with name number

We have to open the properties of the other textbox and entering the following:

text:customer.title

Here we instruct the textbox to get its value from the customer.title member declared in our dataModel.

We can run our application and see the two textboxes populating properly with the number and title of our customer object.

Well the code example given above has a small defect – the customer will be fetched only once during the task lifecycle and the data binding procedure will be executed only once. If we have a task where the customer can select a customer and then the UI navigates to this view, so the user can see and edit the details of the customer we have to modify the view’s code a bit to react to the data model changes:

dataModel:function(){
var me = this;
this.customer = undefined;
this.load= function(completed){
$ma.bo.SLA.fetch('CU00123',function(cust){
me.customer=cust;
completed();
});
}
}
view_Load:function(completed){
self._dataModel.load(completed);
}

The change includes the following:

  • we have declared a local variable me to hold a reference to the dataModel object
  • we have declared a load() method and moved the customer fetching logic inside it.
  • we have called the load() method inside our view_Load() method to make sure that a fresh customer is fetched on each view loading

Each control dropped over the view’s layout in the MACloud Studio layout designer has a property called Data-Bindin. You can use this property to write data-binding expressions. The whole view is binded to the view’s dataModel(), so you have to use expressions, which binds the DOM elements to members and methods of the view’s dataModel. You can bind the element’s html, values , attributes, events and others.

NOTE:

The default data-binding expression syntax and runtime is based on knockoutjs – a third party javascript library. You can read the knockoutjs documentation about the various data binding expressions here.

You can package other javascript/HTML based data binding engine as MACloud library and use it instead.

Data bind list views

Sometimes the developer will need to display a number of objects ( like customers ) in a list view on the screen. This can be achieved easily by using the declarative data binding features provided by knockoutjs engine.

Let’s have a list if customers fetched from the mobile storage. Let’s say that we want to display their titles and numbers in a list view. We will also need to allow the user to delete customer by clicking the delete icon next to the customer and open the customer details by clicking over the customer’s title.

We will start coding our view’s data model first:

dataModel:function(){
var me = this;
this.customers = ko.observableArray();
this.load = function(completed){
$ma.bo.SLA.Customer.fetchAll("","",function(tempArray){
me.customers.fromArray( tempArray );});
completed;
};
this.selectCustomer=function(customer){
$ma.uiManager.context.set('customer',customer,function(){
$ma.uiManager.navigate('next');
});
};
this.deleteCustomer = function(){
me.customers.remove(customer);
};
},
view_Load:function(completed){
self._dataModel.load(completed);
}
view_Show:function(){
$ma.uiManager.hideNextButton();
}

Our data model has:

  • a member customer, which is of type ko.observableArray() – it is a special type provided by knockoutjs and provides observable features. It means that if we delete a customer from the list , the bound DOM elements will be automatically refreshed.
  • a load() method to populate our customer member with a list of customers fetched from the mobile storage. We use an extension method fromArray() of the ko.observableArra to load the observable array from our customer array.
  • we have selectCustomer method to navigate the UI to the next view if a customer is clicked
  • we have a deleteCustomer method to handle cusomer deletions

We have to bind our dataModel to the view’s layout, e.g. to the DOM elements. We will switch to Layout ,first. We have to drop a ListView control over the view’s layout and open the properties of the ListView control. We will check the Inset property of the ListView. We will enter delete in the Split icon property.
We will enter customers in the Data Source property to bind the List View to the customers member of the dataModel. We have to place the following code into the Template property:

This way we specify the appearance of each list item(e.g. each customer) within the List View control.In this particular case, we will have the title of the customer rendered on screen because,e we have used the text:title data-binding expression. We’re also using the click:$parent.selectCustomer data-binding expression to attach the click event of the title to the selectCustomer method of our dataModel. It means that if the user clicks the title of the customer , the dataModel’s selectCustomer method will be invoked and the associated customer object will be passed as argument.

We have also second link , which is bound to the dataModel’s deleteCustomer method to handle customer deletions. The second link(anchor) is styled as delete image ,because we have specified the Split icon property to delete.

NOTE:

The user interface styling and animation is based on Mobile jQuery. The List View template definition in this case is based over the Mobile jQuery ListView documentation.

If the user clicks over the title of the customer, the dataModel().selectCustomer method will fire and the UI will navigate to the route with name ‘next’. The actual view displayed will depend on the task definition.

If the user clicks over the delete icon, the dataModel().deleteCustomer method will fire and the customer will be removed from the osbervableArray ( e.g.the dataModel().customers member ). Because the customers member is declared as ko.observableArray, the List View will be notified about the change and will automatically redraw.

Last Updated: Dec 1, 2015

We provide public releases of our products once a year or more and commit to 12 months support for all public releases. We also provide releases to support the new versions of Microsoft Dynamics NAV and Microsoft Dynamics AX within 12 months after a new version of the ERP is released.

We envision the support as a major component of our effort to provide our customers with mission critical software solutions. We provide support services to customers in order to guarantee their business continuity. Our customer shall report issues or other cases, which requires support. The reporting is performed by authorized personnel from the Customer’s side via the standard support channels described below.

The support is provided in order to:

  • Solve current problems reported by authorized representatives of the Customer on occasion and in connection with Dynamics Mobile
  • Diagnose problems in connection with the standard system functionality
  • Diagnose problems in connection with the functionality customized by Dynamics Mobile team
  • Analyze and eliminate of any “defect” – a mistake in the program code of functionality, whcih affects the Client’s operations

The support services are only provided in response to a support request submitted by authorized personnel from the Customer’s side via any of the support channels:

  • -e-mail: support@dynamcsmobile.com
  • -phone: 00359 2 817 33 63

We provide different response times to support requests based on the request priority as follows:

Priority Reaction time Description
Critical to 2 hour Causes business process block.
Medium up to 8 hours Affects the business process as there are no work around actions.
Low up to 2 business days Low impact issues and requests, which does not affect the system.