Grid Bound to Custom Model Data (non-Entity)

You can use the Grid component in a form that can be edited by the end-user. The grid can contain customized data rather than Anthology entity data.

The Model Data grid property is applicable for a grid that is bound to a non-entity. The Model Data property is not applicable for a grid that is bound to an entity.

Control Property Settings

Grid Properties with Model Data

Rendered Component

Rendered Grid with Model Data

Workflow Argument

Workflow argument type SerializableDynamicObject

Note: The argument name "healthHistory" is derived from the Model value in the Property Settings (vm.models.healthHistory). The argument type "SerializableDynamicObject" is found in the FormsBuilder.Entities namespace.

Column Specifications for an Editable Grid with Model Data

Column specifications

Model Property 

All contents of the grid should be bound via the Model property to a SerializableDynamicObject so that it will be displayed correctly when converted to PDF. This applies to a PDF file saved as attachment to a document tracking record or a PDF file displayed in e-sign processes. You can configure the grid to show specific columns and perform sorting, paging, and filtering operations via its built-in property settings.

In our example, the Model is specified and a workflow argument with a type of SerializableDynamicObject[] is used. Data in row 2 of the grid for the property Frequency can be accessed in the workflow with myarg(1).DataDictionary(“Frequency”).ToString.

Model Data Property

The grid property Model Data defines the initial data as a JSON string. If specified, it will initialize the grid by updating the Model value on grid load.

To display the label <Select> in a drop-down list, the Model Data value must be initialized as “” (empty).

The Model Data JSON string is passed to the workflow as an argument of type SerializableDynamicObject[]. This argument type will hold the data entered in the grid.

If the Model has been initialized in the workflow to a non-empty array, this data will be used. If an OData query has been specified, this data will not be used.

Example

[
    {
    "Question": "What is my question",
    "Checkbox": "false",
    "Frequency": "never",
    "Note": "My note"
    },
    {
    "Question": "What is my question 2",
    "Checkbox": "false",
    "Frequency": "never",
    "Note": "My note2"
    },
    {
    "Question": "What is my question 3",
    "Checkbox": "false",
    "Frequency": "never",
    "Note": "My note3"
    }
]

Data Types

In our example, the Question column uses a String data type. The Model Data JSON string initializes the strings in each row as What is my question, What is my question 2, and What is my question 3. The Editable setting in the column specification is cleared (false) because we don't want the end user to modify the questions.

The Checkbox column uses a Boolean data type which is rendered as a check box. The Model Data JSON string initializes the check box with the value false, i.e., the check box is cleared.

The Frequency column uses a Dropdown List data type with the values never, rarely, frequently, and often. The Model Data JSON string initializes the list with the value never.

Important: Any Dropdown List must be initialized, otherwise the Grid Component will fail. The initialization can be done in the Model Data value or in the workflow.

The column specification for the Date column includes the Format specification of {0:MM/dd/yyyy}. The Date column is not initialized in the Model Data JSON string.

The Note column uses a String data type. The Model Data JSON string initializes the strings in each row as My note, My note2, and My note3. The Editable setting in the column specification is selected because we want the end user to modify the notes.

Workflow Initialized List

Note: If the list is based on dynamic data and the Model Data static initialization method cannot be used, then follow the step below to create a workflow initialized list.

When you are creating a Workflow Initialized List, the simplest object to use is a NameIdObject. With an array of these, the Text Member will be Name and the Value Member will be Id, and they will be of type string and integer respectively. If you don’t need the Id, it is optional to set it.

In the workflow, create a variable (myList in this case). DO NOT use an argument or this will not work.

The type will be NameIdObject[] (array of NameIdObject). You can initialize the object with assign statements, but since variables allow a Default value, use the following example.

In this example we want to create a list of 2 elements, where Yes is value 1 and No is value 2. Set Default to:

new NameIdObject(1){new NameIdObject With { .Name="Yes", .Id=1}, new NameIdObject With { .Name="No", .Id=2}}

Note some significant syntax here:

  • The 1 for the array size is VB syntax for an array of 2 elements, with index 0 and 1.
  • There is a dot before each property name in the With sections.

If you were doing this in assign statements, you could break the statements down as follows:

myList = new NameIdObject(1){} - creates a 2-element array that is empty.

myList(0) = new NameIdObject - initialize the first array element with a new object, “With” could have been used here instead of the following two assigns.

myList(0).Name = “Yes”

myList(0).Id = 1

etc.

As you can see, the Default initialization above, while looking more complex, is less wieldy than a few assign statements in the workflow.

To use this, you must expose this as an Out argument of type NameIdObject[]. After you create this argument, you do this with a final assign statement.

myArgList = myList

The result is that all drop-down list controls that have vm.models.myArgList as the Model For Value List binding (in the popup), will have a Yes/No list. Their Text Member must be Name, and if you use the Value Member, it must be Id.

  1. You need more than two properties
  2. The property names cannot be Name and Id
  3. The types of the property names cannot be string and int respectively.

However, the initialization for the SerializableDynamicObject is considerably more complex to understand to do the same thing as above (with only 2 elements). Here it is:

new SerializableDynamicObject(1){new SerializableDynamicObject With { .DataDictionary = new Dictionary (Of String, Object) From { { "Name", "Yes"}, { "Id", 1} } }, new SerializableDynamicObject With { .DataDictionary = new Dictionary (Of String, Object) From { { "Name", "No"}, { "Id", 2} } } }

You must do this with a variable, and then you must assign it to an argument which is bound to the control.