Modules Dynamic items - happy-geeks/wiser GitHub Wiki

Introduction

The module Dynamic items is the main module type for Wiser. As the name indicated, it's a module that can load data dynamically, based on its configuration. You can add as many modules of this type as you like, each with different configuration and data. This module has two different modes:

  1. Treeview: This module shows a tree structure with data, which can have structures with multiple layers. It is ideal for smaller amounts of data, or categorized data.
  2. Gridview: This module shows a grid with data, which can be filtered and sorted. It is ideal for large amounts of data where the structure matters less.

Whichever mode you use, the items that are opened in these modules are fully dynamic. Wiser can have an unlimited amount of entity types and each entity type can have an unlimited amount of tabs, groups and fields. These entities can be different for each tenant in Wiser (e.g. a product in tenant A can have completely different fields than a product in tenant B). All of this can be configured via the Admin module, or directly in the database via tables such as wiser_entity, wiser_entityproperty and wiser_link. Entities can have all kinds of different fields, such as text fields, date fields, file fields, etc. These fields can be configured in the wiser_entityproperty table. The values of these fields are stored in the wiser_itemdetail table. Each item in Wiser is stored in the wiser_item table, which contains the ID and entity type of that item. For more information, see the Entity properties document.

Configuration of a module

In the options field of the wiser_module table you can enter a JSON object with all the specific setting for either a Gridview or a Treeview module. These properties are basic, per module type below there is an additional list of properties for each specific module.

Property Mandatory Default value Explanation
gridViewMode yes false When set to false you get treeview mode with the tree structure on the left and the details of an item on the right.

When set to true you get gridview mode with a table containing the items. This table works with virtual scrolling, which means that only the items you scroll to are loaded. From the table, however, items can be opened in a popup.

If you set this value to true, you must also populate the custom_query and count_query columns. You will find more information about this in the following sections.
onlyOneInstanceAllowed no false By default, multiple instances of a module may be opened. If this option is set to true, only one instance of that module can be opened.

Users can always open a new tab in their browser and open the same module in it.

Grid view mode

Introduction

A gridview module consists primarily of a table containing data. Besides that, it's possible to show a detail pane on the left, right, top or bottom side of the screen. This detail pane can be used to show details of the selected item in the grid, or to show the details of a pre-defined item. This is done by setting the informationBlock property in the gridViewSettings object. Here is a schematic that shows some of these options:

gridview_options

The table of data in the gridview module should be populated with data from an SQL query. This query accepts certain variables, which are replaced by Wiser when the query is executed. The most important variables are {limit} and {sort}. These variables are replaced by Wiser with the appropriate SQL statements for filtering, pagination and sorting. You can read more about this in the sections below.

It's also possible to add custom buttons to the grid, either in the toolbar in the header of the grid, or in a column of each row. These can be general actions such as creating a new item, or other actions such as executing custom SQL queries. Those actions can use data from the selected row(s) in the grid. You can read more about these actions in the action buttons information.

Additional options of a gridview module

Certain properties of the options column of the table wiser_module are specific to the gridview module. These properties are only used when the gridViewMode property is set to true. The following table shows all properties that can be used in the options column of the wiser_module table:

Property Mandatory Default value Explanation
showNameFieldInWindows no false Set this value to true to ensure that item names can be modified when those items are opened in a screen/popup.

Note that even with this option on, the field to change the name may still not be visible. This is because the name field will still be hidden when the show_in_tree_view option is off for the entity type in question, or when the hideTitleColumn option is on in the grid in question.
gridViewSettings no Contains an object of type gridViewSettings see the table below for more information.
fieldMappings no Contains an array with fieldMapping objects, see the table below for more information.
informationBlock no Contains an object of type informationBlock, see the table below for more information.
The gridViewSettingsobject

This object determines how the grid should behave and what functionality it has. The object has the following properties:

Property Mandatory Default value Explanation
pageSize no 100 Enter here how many items should be displayed per page. Be careful not to enter a value here that is too small or the virtual scrolling will not work properly. You should enter a value high enough so that no empty space would remain on your screen. For example, 10 items per page is far too little, because usually much more than 10 items will fit on your screen.
hideCommandColumn no false By default, a column is shown on the far right with a button to open items in a popup. If this column is not desired, it can be disabled with this option.

This has no effect on being able to double-click in a line of the grid, which still allows you to open an item.
columns no Enter an array of columns you want to show here. You can use this to show different titles to columns than the column names that come from the query. If you leave this property empty, all columns will be shown as they come from the query. More information can be found here: columns - API Reference - Kendo UI Grid
columnMenu no false If this value is set to true, an additional menu is displayed with each column. This allows the user to choose which columns to see. This is remembered in the localStorage of that user's browser.
selectable no false If the user should be able to select items in the grid (for certain actions in the toolbar, for example), you can specify that here. Possible values are:
'row': The user can select 1 line.
'multiple, row': The user can select 1 or more lines.
dataSelectorId no If the data is to be retrieved from a data selector, you can enter its ID here. The columns custom_query and count_query will then be ignored. Also, server filtering and server paging will then no longer work.
toolbar no This contains an object of type 'toolbar'. This object has the following properties;
hideCreateButton: Allows you to determine whether the button to add a new item should be hidden. By default, this button is always visible.
customActions: an array of actions that can be executed on every selected row in the grid. The setup is the same as the actions within the sub-entity-grid field type. See the documentation in chapter 3.1
informationBlock no This allows an additional block to be displayed on the page containing additional information. Currently it is only possible to show a Wiser item in it. See the information below under header 'information block setup'
skipNameForNewItems no false If set to true, the user no longer needs to enter a name when creating a new item.
showDeleteButton no Set this value to true to show a default delete button with each line. For this functionality to work, make sure that the module's query has a column encrypted_id or encryptedId with the encrypted ID of the item that is then to be deleted. Example: SELECT id AS encrypted_id_encrypt_withdate FROM wiser_item
deleteItemQueryId no false Here an ID can be entered from the table wiser_query, then an additional button with an icon of a trash can is added to each line in the grid. The query should then cause this item to be deleted. In this query all values from the grid's query can be used.
clientSidePaging no false Set to true to turn on client-side pagination. If this option is on, the count_query may be left blank, as it will no longer be executed. This works best if clientSideSorting and clientSideFiltering are also on.
clientSideSorting no false Set to true to turn on client-side sorting. The sorting is then done by javascript, sorting only on the data currently known in the javascript. This works best if clientSidePaging is also turned on.
clientSideFiltering no false Set to true to enable client-side filtering. Filtering is then done by javascript, allowing filtering only on the data currently known in the javascript. This works best if clientSidePaging is also turned on.
keepFiltersState no true By default, any filters set by the user are remembered and stored with their account. If the user then reloads the module one time later, the saved filters will be loaded. This functionality can be turned off by setting this option to false.
allowOpeningOfItemsInNewTab no true This adds one more button to the end of each line. This button allows items to be opened in a new tab in Wiser (as if you were opening a new module). This does not work when the disableOpeningOfItems option is set to true.

Besides these Wiser-specific options, it's also possible to use most other settings from the Kendo UI for jQuery Grid. Only options that are not valid JSON properties cannot be used, such as options that require javascript functions.

The fieldMappings

This object is to let Wiser know how and where to get each column value from, to automatically update your query with the filters that the user specified. This is used for mapping columns of your grid to properties of wiser_itemdetail, it cannot be used for values from other tables. The object has the following properties:

Property Mandatory Default value Explanation
field yes The name of the field as it's known by the Kendo Grid. This is the same as what you'd enter in the field property of each object in the columns array of the gridViewSettings.
property no The value of field If the field is a value from one of the wiser_itemdetail tables, enter the key of that here.
ignore no false Set this to true for fields that don't get their data from wiser_itemdetail or if you want to ignore this field in the filters for other reasons. Wiser will not use this field for filtering then, even if the user specified a filter value for this column. If you also want to disallow users to filter on this field, then disable filtering in the column settings of that field.
itemTableAlias no i The table alias that is used in your query for the main wiser_item table.
addToWhereInsteadOfJoin no false Set this to true for fields that belong to the wiser_item table instead of wiser_itemdetail, so that Wiser will add filters for this field to the WHERE clause of the query, instead of adding a JOIN.
Information block

This property is an object that contains the settings for the information block. The object has the following properties:

Property Mandatory Default value Explanation
position no bottom The position in which the block should be displayed. Possible options are:
top
bottom
left
right
height Only in the case of position top/bottom The height of the information block. This should always be a string, so for example '500px'.
width Only for position left/right The width of the information block. This should always be a string, so for example '50%'. This should always be a percentage.
openGridItemsInBlock no false Set to true to ensure that items opened via the main grid always open in the information block (instead of a new window).
showSaveAndCreateNewItemButton no false If set to true, an additional button is shown in the information block. This button allows users to save an item and then after saving, a new item is created and opened, which they can then enter immediately.
hideDefaultSaveButton no false Set this to true to hide the default save button in the information block, to show read-only items for example.
initialItem yes This is a JSON object with properties, see the following rows for more information.
initialItem.itemId no If a specific item should be opened in the information block by default, enter its ID here.

If nothing is entered here, a new, empty, item is always created when the module is opened and loaded into the information block.
initialItem.newItemParentId Only when initialItem.itemId is not populated Used only when initialItem.itemId is not populated. This is the item under which the new item should be added. Enter 0 to add the new item to the root.
initialItem.entityType yes The entity type of the item to be opened, or of the new item to be created.
initialItem.readOnly no false Set to true to ensure that items in the information block cannot be saved.
initialItem.hideHeader no false Set to true to ensure that the list of tabs is not shown.
initialItem.hideFooter no false Set to true to ensure that the footer is not shown, which contains the metadata and save button.

Properties

The custom query

This is required for gridview modules, they will not show any data when this column is empty. This query must have at least the columns id, encrypted_id and entity_type (if you want to be able to access/edit items), which will then contain the ID and encrypted ID of each item. You can have the ID automatically encrypted by adding encrypt_withdate at the end of the column alias. You will then get encrypted_id_encrypt_withdate, for example.

Items in a grid can be opened by double-clicking, or by using the button in the rightmost column. To do this, however, there must be a column called encrypted_id in the query results. If it is not there, the functionality to open items will not work and the button for it will not be visible. This functionality can also be disabled by setting the disableOpeningOfItems option to true.

If you want the name of an item (or some other value) to be shown in the title of the popup when that item is opened, you must make sure that the query has a column called title containing the value to be shown. All other columns are entirely up to you.

Furthermore, you have to put the variables {limit} and {sort} in the right places in the query, otherwise sorting and virtual scrolling / pagination will not work. These variables are then replaced by Wiser (e.g. LIMIT 0, 100 and ORDER BY i.id ASC).

The count query

For serverside virtual scrolling/paging to work, it is necessary to know in advance the total number of items to be displayed. For this, you can enter a separate query in this column. That query should then do a 'COUNT' in the 'SELECT' and return that as the only value. This query needs to take any filters into account, so that it will always return the correct number of items. The query should also not contain any LIMIT or ORDER BY statements, as these are not needed in a count query. This query can be left empty, in which case Wiser will automatically create a count query for you. This is done by simply adding a COUNT(*) to the custom_query, and removing all other columns. This is done by Wiser, so you don't have to worry about it. However, this is not always optimal, and therefore it is better to create your own count query in most cases.

Example query, without filtering:

SELECT COUNT(*)
FROM wiser_item
WHERE entity_type = 'customer'

Setup serverside filtering

To enable users to filter the results of a grid view module, you'll have to add something to your queries for that module. This can be done in two different ways:

  1. Use dynamic filtering functionality from Wiser, this will generate JOINS and WHERE statements dynamically/automatically for your query.
  2. The second option is to add GCL if statements to your query, to handle the filtering yourself.

Dynamic filter functionality

Dynamic filtering works great for filtering on wiser_item and wiser_itemdetail fields, and it supports having multiple filters on a single field (e.g. so that users can filter on a date range).

To make this work, you first should add a fieldMappings array to the options column of the wiser_module table. This object is to let Wiser know how and where to get each column value from. This is needed for mapping columns of your grid to properties of wiser_item and/or wiser_itemdetail, so that Wiser knows how to build the SQL query. For details about the objects in that array, see the additional options of a gridview module section.

Secondly, you need to add some variables to the query, to let Wiser know where to put the filtering. The variables you need to add are:

  • {filters}: This is where Wiser will add the JOINs for the filters on wiser_itemdetail tables.
  • {where}: This is where Wiser will add the WHERE statement for the filters on wiser_item tables.
  • {hasWhere}: This is a variable that will be replaced with 1 if there are any filters on wiser_item, or with nothing if there are no filters on wiser_item.

Example query, with filtering, sorting and paging:

SELECT x,y,z 
FROM wiser_item AS i 
{filters}
WHERE i.entity_type = 'x' 
[if({hasWhere}=1)]AND ({where})[endif]
{sort}
{limit}

To actually allow users to select multiple filter conditions on a single column, you have to enable that for those columns in the columns array of the gridViewSettings. This is done by setting the filterable.extra property to true. This will allow users to select multiple filter conditions on a single column, and they can choose whether they want an "and" or an "or" filter. To do this, set the filterable.extra option to true in the column settings. It's also possible to change the allowed operators for each column, though Kendo decides them automatically based on the value type of each column. You can find more information about that in the Kendo documentation.

Here is an example of a column with the filterable.extra property set to true:

{
    "field": "birthdate_customer",
    "title": "Birthdate",
    "filterable": {
        "extra": true,
        "operators": {
            "string": {
                "eq": "Is gelijk aan",
                "lte": "Kleiner dan of gelijk aan",
                "gte": "Groter dan of gelijk aan"
            }
        }
    }
}

Handle filtering yourself in your query

If you want to have more control of the JOIN and WHERE clauses of your query, you can do the manual way. But keep in mind that this way does not support multiple filters on a single field (e.g. no date ranges).

To use this method, you can use specific variable suffixes in combination with GCL if statements. You can use the following suffixes in your query:

  • _has_filter: This will be replaced with 1 if the user has set a filter for that column, or with nothing if no filter is set.
  • _filter: This will be replaced with the value of the filter, and the appropriate comparison operator (e.g. =, LIKE, etc.) will be added automatically.

Example of a custom JOIN clause with filtering:

[if({name_has_filter}!1)]LEFT[endif] JOIN wiser_itemdetail AS name ON name.item_id = i.id AND name.`key` = 'name' [if({name_hasfilter}=1)]AND name.value {name_filter}[endif]

For count queries, you usually don't need to add the JOIN clauses when there are no filters, so you can make the entire JOIN clause optional, like this:

[if({name_has_filter}=1)]JOIN wiser_itemdetail AS name ON name.item_id = i.id AND name.`key` = 'name' AND name.value {name_filter}[endif]

As you can see in the above examples, no conditions like = or LIKE are added to the query and no quotes are added around {name_filter}. That is because Wiser will do all that automatically, based on the filter operator that the user has selected.

Information block setup

When in Gridview mode, the module can be set up to show an information block. This block can be used to show details of a selected item in the grid, or to show a new/empty item. This is useful when you want to show details of an item in the grid, but you also want to allow users to create a new item without having to open a new window. For details about this object, see the additional options of a gridview module section.

Example settings of grid with information block:

{
  "gridViewMode": true,
  "gridViewSettings": {
    "informationBlock": {
      "position": "bottom",
      "height": "800px",
      "openGridItemsInBlock": true,
      "initialItem": {
        "itemId": 1,
        "entityType": "relatie",
        "readOnly": false
      }
    },
    "dataSelectorId": 7,
    "hideCommandColumn": false,
    "toolbar": {
      "hideExportButton": true
    },
    "columns": [
      {"field": "id", "title": "ID"},
      {"field": "firstname", "title": "First name"},
      {"field": "lastname", "title": "Last name"}
    ]
  }
}

Dynamic (treeview) module

The treeview module always shows a screen in 2 parts, on the left side a treeview and on the right side the opened item in the treeview. This module is ideally suited for data that is hierarchical and does not contain thousands of items (e.g. for a multilayer category/product classification or for managing data that is divided into several subfolders). It is not suitable for managing thousands of customer items, for example, unless they are divided into, say, dozens of branches with several dozen to hundreds of customers per branch. In short; consider carefully when a treeview module is desired and useful. One does not exclude the other. Data managed using a treeview or a grid module can also be managed using the other type. It is a matter of setup. Sometimes you want to offer both for the same type of data but for specific purposes you choose one or the other module.

Additional options of a treeview module

Property Mandatory Default value Explanation
initialItemId no Enter an ID of an item here to load that item directly when opening the module. This can also be an item not normally found in this module.

This item will then be loaded immediately without an item selected in the tree. The item is also reloaded again if the selection in the tree is removed.
entityType no This is required when initialItemId is filled in, this must then be the entity type of that item. This is required so that Wiser knows which table to look in to load the item.
⚠️ **GitHub.com Fallback** ⚠️