Log in

TurnKey web client

From MDrivenWiki

Angular implementation starting point

Please read this for a background to TurnKey-driven viewmodels and actions Getting to the bottom of the Line of Business Application

Default behaviour (mixed list)

Loading shows an animated “loading image” on the top.

Left menu moves along with scrolling down.


ValueFormatFilterName  is the most interesting, because it allows you to put Javascript on your client to parse the value you send. You can then make it as complex as you like. The default ValueFormatFilter accepts a JSON object and converts it to a real typed value on the client. Why is this important? Because your cells are different, and if you can’t send a date as a JS date value, your client can’t format it correctly.

In the example above, all values are included in a JSON “frame”. In the case of a date, the value OCL is self.Day.Date.formatDateTime('yyyy-MM-ddTHH:mm:ssZ'), which is a valid JSON date as a string. This will be handled by the client and formatted using the Format attribute with an OCL 'dd, EEE', which is a short date format, “day and month”.

If you create your own Angular filter you can render any complex values into a cell.


You set date and time format in the Style attribute enclosed in { }.

For example, for dates and time, {short} will show date and time in compact format. The default date format is {shortDate}. Please refer to the Angular guide for formatting dates

The date and time format are automatically localized depending on the browser.

Decimal Number formatting

Decimals pose a special problem in a web client because of the lack of the Decimal type in JavaScipt. Only floating point numbers are available in JS. Therefore, Decimals can easily be mangled and get to many decimal positions in a web browser.

One way to handle this is described below

Showing numbers

You can simple add number:2 in the tagged value for field as described here Text_formatting according to the AngularJS documentation: Number filter

Entering numbers

Using Derived settable class attributes you can add round-trip conversion from an "internal" type of data to for example a string value.

This gives you a lot of control and might be very helpful in providing a good user interface. It also make it possible to handle "user shortcuts".

See the example for Derived settable attributes


When an attribute or link changes, the ECO-space state is changed which is signaled in the GUI with Save, Undo, Redo and Cancel buttons in the left menu. In addition to this, a “Save and Cancel-bar” is displayed at the top when in “small mode”

Each viewmodel holds a separate save-context.

If not saved, the user can’t go back and forward with the browser buttons without asking “Save or Cancel?”, preventing abandoned save-states.

If creating a new object and showing that in a viewmodel, pressing Cancel shows a confirm dialog. If Ok, cancels changes and navigates back to the previous page.

Ways to navigate (GUI use cases)

Select MainMenu in large and small mode and selecting an item.

This loads or reloads the Angular “app” with the new page.

Select an item in the visible left menu

Executes the action picked.

If this navigates to a new page, that Angular-page is loaded out of band and inserted in the DOM.

Left menu button is clicked and item in the visible left menu is selected

This has the exact same effect as when the menu is visible. It hides the menu, even if the action doesn’t navigate.

Navigation use-cases

  • Using model action to navigate with unsaved data Yes, ask first.
  • Browser forward in history with unsaved data No
  • Browser backward in history with unsaved data No
  • Leave to another page with unsaved data Warning (not possible to stop)
  • Close page with unsaved data Warning (not possible to stop)
  • Cancel on newly created object Automatic back navigation
  • Own deletion of root object in view Inform and then automatic back (automatic?)
  • Others deletion of root object in view Inform and then automatic back 
  • Automatic navigation (redirect) 

Selecting a row in “single row” mode

For a master-detail use-case, i.e. letting vCurrent in one list affect another list. Set “Always show actions” on the viewmodel class that should be selectable without prompting the pop-up menu.This will create a master-detail style operation. If you don’t want any actions visible - opt them out.

Creating a Wizard (one ViewModel)

Here a Wizard means a viewmodel that changes based on state

HOW? _____________

Creating a Wizard (multiple ViewModels)

Here a Wizard means several viewmodels linked with actions

HOW? _____________

Modal windows

Modal windows shares save-context with it “parent”, non-modal viewmodel. The modal window is not part of the back-forward navigation scheme.

Navigating in a modal window

  • Pressing OK or Cancel button will return success and failure to the action opening the modal window.
  • Actions shown in a modal window works in two ways
    • They act without navigation, i.e. act on the objects with the save-context
    • If they navigate, it will open a new browser tab and “spawn” a new browser-session.

Modal windows uses the same Angular-mechanism as the pop-up menu for actions.


Click on lists

Single-row handling

Default for lists is to show a pop-up menu or perform the default action if it’s the only one. Usually this is for a “Show”-action navigating to the object clicked.

If you select “Always show actions” for a ViewModel class in the designer (i.e. a list), it will be rendered in “select one” mode and with the actions for the current row in the left menu. Clicking on the list/row will NOT show the pop-up menu or perform the default action if it’s the only one.

If the list don’t have any actions “opted-in”, the list should also be rendered in”select one” mode.

Multi-row handling

You can turn on multi-select for lists by adding the tag “MultiSelect” with the value True (no quotes) on the viewmodel class.

  1. Select viewmodel class, click on “TV and Attributes”.
  2. Add the MultiSelect value to the Value Store.
  3. Add the Value Store value to the viewmodel.

This will make selecting and deselecting individual rows possible and update the vSelected variable.

You then make actions acting on the vSelected collection in the server action.

Dragging and DragDrop actions

Drag-Drop angular code is generated for lists by adding the tags DragSource or DropTarget with the value True (no quotes) on the viewmodel class.

Swipe action

To activate an action to trigger when the user swipes, add tagged values on the viewmodel class. The value should be the action name you want to execute. For different swipe actions, add;

  • Left-swipe: Tag SwipeLeft
  • Right-swipe: Tag SwipeLeft

Swipe both ways: Tag SwipeLeft and SwipeRight

Action directly on first click

The default behavior is to execute the action directly if there is only one available. If there are many to choose from a modal action-pane is shown.

To change the default to execute single action directly you can check the AlwaysShowActions checkbox on the nesting in the view model as shown in this picture:


Making a button the default for a page when pressing Enter on the keyboard

If you add the style 'seekeraction' to a button it will be clicked when the user presses Enter.


Tag BlobDownloadLink on a ViewModelColumn will render a download link for the attribute. Add Attribute “FileName” next to blob in the viewmodel class if you wish to databind to that FileName attribute.

Tag DataIsLink on a string ViewModelColumn will render the string asi an link-URL.