MDrivenWiki
Log in

TurnKey web client

From MDrivenWiki

Angular implementation starting point

Please read this for a background to TurnKey-driven viewmodels and actions

http://www.capableobjects.com/2011/02/27/wecpof-getting-to-the-bottom-of-the-line-of-business-application/

Form / Viewmodel types

Seek form

The seek form that from nothing can search objects in persistent storage and show them in a list

Browser form

This is a special case of the Seek form in that it doesn’t require a search string, it shows all object of a class.

Document form

The form has a root object provided by the action showing the form (viewmodel).

Form variations

A common use case is when a viewmodel don’t require a root object, but instead uses a singleton object filter or show objects related to the logged in user.

Vocabulary

Lists can be in “single-row” or “multiple-row” mode. That is they can have only one row selected (stored in vCurrent) or multiple rows selected (stored in vSelected).

Default behaviour (mixed list)

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

Left menu moves along with scrolling down.

Styling

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.

Actions

You place actions, either class or viewmodel, on the AllCellsList or the class that makes up the AllCellsList.

Date-formatting

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 https://docs.angularjs.org/api/ng/filter/date

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 viewmodel's Style field 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

Save-state

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 

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.

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:

AlwaysShowActions

Data-validation

At the bottom of the screen, info, warning and error messages are shown.

They don’t have any effect on navigation as of today.

Language and internationalization

Don’t do any conversion in your viewmodel. If you do, you will send a string to the client, making client formatting impossible.

I.e. you viewmodel attribute should evaluate to a DateTime.

File BLOBS

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.

Layout

Applying CSS to specific a page or pages

Every page rendered includes the view name as a class on the div with ID "contentWrapper".

2018-02-11 16h02 34.png
Use this to apply specific CSS-styles to specific pages.

Class prefixes

The default Bootstrap "size" class is col-sm- which will make the UI to "collapse" to an vertical style on for example Phones.

BS3ColBreakpoints.png

Set the tagged value Bootstrap.ClassPrefix on viewmodel to change Bootstrap column class prefix from col-sm- to something else, for example col-xs- to never go into vertical style for that view.

Change Bootstrap Class Prefix

Splitters and sections

If you add splitters to you viewmodel, that creates sections.

In bootstrap (html5) you make the top and bottom sections static (non-moving) with the tagged value Bootstrap.StaticSections on the viewmodel (green ViewModel class).

Bootstap static sections in Tagged Value
Bootstap static sections in Tagged Value