A Tour of the LightSwitch HTML Client APIs (Elizabeth Maher)

A Tour of the LightSwitch HTML Client APIs (Elizabeth Maher)

Rate This
  • Comments 4

LightSwitch generates a custom API set based on project assets that developers can use when writing custom code in the HTML client. Each data source, table, query and screen causes various items to be created in the API. Even actions on each of the LightSwitch designers can have affect. This article will enumerate what actions in a LightSwitch project will affect the generated JavaScript Single Page Application programming model for the HTML Client, which is based on jQuery Mobile.

If you are not familiar with the overall architecture of the HTML Client, please see The LightSwitch HTML Client: An Architectural Overview.

Entities

 clip_image002

For each entity, there are several generated methods available via the active data workspace, which you can access from the global object "myapp". In the above picture, we have a Table1Items table, which is part of the ApplicationData datasource. The generated objects in this case would be as follows.

Method Signature

Return type

Notes

myapp.activeDataWorkspace
.ApplicationData.Table1Items
 

This member gets the Table1Item entity set. Results can be further manipulated by calling available functions like orderBy, skip, etc. The addNew function can also be called to create another Table1Item entity instance.

myapp.activeDataWorkspace
.ApplicationData.getTable1Items()

WinJs.Promise

Asynchronously gets the value of all Table1Items.

myapp.activeDataWorkspace
.ApplicationData
.Table1Items_SingleOrDefault(id)
 

Method represents a query to get a specific record from Table1Items based on the Id.  The ‘_SingleOrDefault(id)’ is available for all intrinisic or internal tables. 

Call .execute() to get the results of the query asynchronously.

Entry Point

For each entity that is created, there is a custom entry point for the created event of that entity. For an entity called Table1Items, the method signature would be as follows.

myapp.Table1Items.created = function (entity) {};

To access this entry point, open the designer for the entity, select the HTML client perspective, choose the Write Code dropdown and click created. This method is called every time a new instance of a Table1Item entity is created. The created method is an excellent place for any custom logic needed to set appropriate defaults for new entities.

Queries

Every query seen in Solution Explorer can also be accessed in code via a method off the active data workspace object. For example, a query named Query1 that belongs to the ApplicationData data source would have a signature as follows.

myapp.activeDataWorkspace.ApplicationData.Query1()

clip_image002[1]

If the query has any parameters, the generated method is changed to take the appropriate number and type of arguments. In the screen shot above, we see that Query1 takes a string parameter called Parameter1. In this case the method signature would be the following.

myapp.activeDataWorkspace.ApplicationData.Query1(Parameter1)

To asynchronously execute the query, call the execute method. A WinJS.Promise is returned by the execute method.

myapp.activeDataWorkspace.ApplicationData.Query1("parameter value")
.execute().then(
        function (results) {
            if (results.results.length >= 0) {
                msls.showMessageBox("Found some records!");
            }
        },
        function (error) {
            alert(error);
        }
    );

For more information about using Promises see: Promises in LightSwitch

Screens

The API for customizing screens is affected by everything that is contained in the screen member’s list and screen content item tree. The screen members list is the list of available data on the left hand side of the screen. A screen content item is a node in the tree view in the middle of the screen designer.

The result of the generated code depends on the type of screen member, which may be an entity collection, single entity instance, screen property or screen method. Below is a picture of a project with a screen containing all the types of screen members.

clip_image002[3]

Screen Members

For every screen member, a property accessor is created. For this screen the following screen members were created.

Member Name

Data Type

Generated API

Notes

Table1Items Query returning a set of records
screen.Table1Items
Returns msls.VisualCollection.
   
screen.getTable1Items()
Returns a WinJSPromise after getting the data for Table1Items asynchronously.
LocalProperty1 Primitive type or single entity type
screen.LocalProperty1

Get/set value of screen property. Type is same as specified by the ‘Property Type’ in the Properties windows.

Table1Item Query returning a single record
screen.Table1Item
Returns msls.application.Table1Item
   
screen.getTable1Item()

Returns a WinJSPromise after getting the data for Table1Item asynchronously.

MyMethod Screen method
screen.MyMethod();  
This will execute MyMethod.

Method Entry Points

Each screen method listed in the screen members list will have two methods available.

Method Signature

Notes

myapp.BrowseTable1Items.MyMethod_execute = 
function (screen) { };

This is the function executed when the MyMethod button is clicked or screen.MyMethod() is called.

myapp.BrowseTable1Items.MyMethod_canExecute = 
function (screen) { };

If this function returns false, the MyMethod button will be disabled. If true is returned then MyMethod button will be enabled.

Content Item Methods

clip_image001[4]

The state of screen content item affects which functions are used for manipulating the UI of that screen. Using the BrowseTable1Items as an example again, a custom control with the name of ContentItem1 method with the signature of

myapp.BrowseTable1Items.ContentItem1_render = 
function (element, contentItem) {};

The element is simply the root HTML element for the control. The contentItem parameter is a customized object allowing access to ContentItem1’s value, data bindings and validation results.

Most content items, that are not custom controls, may be modified by adding code to their post render function. For example, if the ContentItem2 content item is displayed as textbox, then the post render function signature would look like the following.

myapp.BrowseTable1Items.ContentItem2_postRender = 
function (element, contentItem) {};

You will notice that the method arguments are the same. The main difference is the timing when these methods are called. As the name suggests, the postRender function is called after the HTML elements used to display the content item are created.

Here's a rule of thumb on when to use these events:

- If you need to insert new elements into the DOM, use the render event. The render event allows you to programmatically create and insert an arbitrary set of DOM elements. For example, if you want to use a control from jQuery UI, use the render event to instantiate the control and insert it into the DOM.

- If you need to augment or otherwise modify DOM elements created by LightSwitch, use the postRender event. The postRender event is commonly used to add a CSS class or DOM attribute to existing DOM elements: for example, you may want to add a jQuery Mobile class to a DOM element created by LightSwitch.

For examples see Custom Controls and Data Binding in the LightSwitch HTML

Screen Entry Points

It should also be noted that each screen has customized entry points. For the screen shown above, the entry points would be as follows.

Entry Point

Notes

myapp.BrowseTable1Items.created 
= function (screen) {}

This method is called each time BrowseTable1Items screen is created. This is an excellent place to put defaulting logic for the screen.

myapp.BrowseTable1Items.beforeApplyChanges
= function (screen) {};

This method is called each time before a save operation is executed for BrowseTable1Items. If true is returned, save proceeds. If false is returned, the operation is canceled. If a WinJs.Promise is returned, the operation waits for the promise to complete (or fail) before continuing.

Screen-level validation logic should be put here.

Global Screen Methods

clip_image002[5]

For each screen, a method is generated to asynchronously navigate to that screen. For each local property marked as a parameter, a method argument will be generated. In the example above, if LocalProperty1 is marked as a screen parameter, then the generated method would be

myapp.showBrowseTableItems(localProperty1, options)  

If LocalProperty1 is not marked as a screen parameter, then

myapp.showBrowseTable1Items(options) 

would be available.

Two options can be specified when navigating to another screen.

Option Signature

Example

beforeShown (screen) {}
//This would set the default value for  
//Property1 text box to 'default value'
//when navigating to a the 
//BrowseTable1Items screen
myapp.showBrowseTable1Items({
  beforeShown: function (newScreen){
    newScreen.Property1 =
     "default value";
  }
});
afterClosed (screen, 
action: msls.NavigateBackAction)
{}
myapp.showAddEditTable1Item(null, {
  afterClose: function (addEditScreen,
    navigationAction) {
    //If the user commits change,
    //show the view detail.
    if (navigationAction === 
    msls.NavigateBackAction.commit) {
      var newTable1Item = 
        addEditScreen.Table1Item;   
      myapp.showViewTable1Item(
        newTable1Item);
      }
    }
  });

Conclusion

The article has given an overview of the generated portions of the JavaScript API for LightSwitch HTML clients. Many actions in the designers affect the API you see when writing code to customize entity behavior or customize your screen UI.

For examples on how to use the API in a variety of ways, see How to: Modify an HTML Screen by Using Code

-Elizabeth Maher, Software Tester, LightSwitch Team

Leave a Comment
  • Please add 3 and 5 and type the answer here:
  • Post
  • Thanks for this.  Very nice article, Elizabeth.  Keep them coming!  

    Suggestion for next post:  How to use Client Query on HTML Client to filter data and load the results into a visual collection on the screen.  Like this unanswered forum post:

    social.msdn.microsoft.com/.../html-client-javascript-apply-filter-to-screen-data-collection

    We been shown how to execute queries .then handle results and we've been shown how to use the screen.EntityName to get the visual collection.  But we know not how to load query results into the visual collection on a screen.  I know it's not this simple, if even possible, but how do we do something like this:

    myapp.activeDataWorkspace.ApplicationData.Query1("parameter value")

    .execute().then(

           function (results) {

                   screen.Table1Items.load(results);

      });

    An example use-case is to enable client-side dynamic filter and sort at runtime.

    Thanks again!

  • This is great! Every application that I have been contracted to build requires more code than one might expect (or hope for) behind the screen. Articles and examples like this are quite invaluable. Thanks.

  • Thanks very much for this post.  I know I will be referring to it quite often!

  • Thanks for the excellent post.  How can screen parameters be passed into the following (i.e. instead of static values):

    myapp.activeDataWorkspace.ApplicationData.Query1("parameter value")

Page 1 of 1 (4 items)