Actions
Actions define what happens after an event has occurred. They are bound to certain events (clicks; swipes; long clicks; after load; before load etc...)
Combined together, actions and events form an interaction with the app on a global level. Some actions can be used by only one widget while some others by all widgets.
In the Action Library all actions are described in detail.
Actions can be clearing data from widgets, saving data to database, switching to another screen, loading data to widget, etc…
All actions that are set to widgets are bound to an event. If an action is not bound to an event it can’t be used.
Example of an action bound to Button
widget:
<source lang="xml" enclose="div">
<Button
android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click to go to layout navigation0" ek:act_toLayoutClick="@+id/navigation0" />
</source>
All actions begin with prefix: “gn:act_”
.
Action formats
There are two formats that can be used to define actions:
- 1. As a widget attribute
- action signature is as defined in Widget Library.
- i.e.
gn:act_actionName=”actionValue”
- 2. As an action within another action
- action that is nested within another action as a value of its value
- An action that is defined as
gn:act_actionName=”actionValue”
for a widget has to be modified to be used within another action like:gn:act_parentAction=”[gn:act_actionName]|[actionValue]”
Action types
- 1. Event actions
- Event actions are always bound to an event. In the Widget Library there are defined events. An action is executed when an event is triggered. Event actions can also be used in conditional actions and action sets. Picture 1 displays example of event action.
- 2. No event actions
- No event actions can only be used within an action set or another conditional action that accepts actions. In the following example, nothing will happen since the actions are not bound to any event. Those actions do not have an event description in Widget Library.
<source lang="xml" enclose="div"> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:ek="http://schemas.enaikoon.com/enaikoon" android:layout_width="match_parent" android:layout_height="match_parent" ek:act_beforeLoad="[ek:act_cleanWidgets]|[]" >
</source>
- 3. Conditional actions
- Conditional actions are a special type of no event action and can be used within other actions or action sets. Depending on the outcome of a certain action it executes other actions. Conditional actions work like an 'if' statement. More about conditional actions in Action Library.
<source lang="xml" enclose="div"> <Button
android:id="@+id/btnOpenAsset" android:layout_width="wrap_content" android:layout_height="wrap_content" ek:act_setClick="[ek:act_cleanData]|[all],[ek:act_if]|[[ek:act_validateScreen]|[]**[ ek:act_querySortReverseTop]|[]--[ek:act_toLayoutClickDbVal]|[devicetypebyid]::[ek:act_toast]|[No item found or not all fields entered]]" android:textSize="14sp"/>
</source>
Actions usage best practices
In order to more efficiently use actions, the following best practices are suggested to all developers:
- Group business logic in a single location in XML file. Use helper views to store business logic code or separate it by functionality and use triggers to call it. This ensures the logic can be more easily understood in one single location and allows reusable components of your business logic to be called upon later via trigger somewhere else.
In the following example, FrameLayout
with “@+id/invalidateRecord”
is used to hold a “block” of business logic which is then called when necessary to invalidate record, by action “gn:act_trigger]|[@+invalidateRecord,gn:act_set]
<source lang="xml" enclose="div">
<FrameLayout
android:id="@+id/invalidateRecordReloadPointerDataCleanScreen" android:layout_width="wrap_content" android:layout_height="wrap_content" ek:act_set="[ek:act_trigger]|[@+id/invalidateRecord,ek:act_set],[ek:act_cleanWidgets]|[],[ek:act_fill_dropdown]|[@+id/ddCleaningReport_visibleDamages],[ek:act_setVariable]|[@variable/screen2NfcTag,@variable/visitNfcTag],[ek:act_trigger]|@+id/newOrExistingReading,ek:act_set]" />
<FrameLayout
android:id="@+id/invalidateRecord" android:layout_width="wrap_content" android:layout_height="wrap_content" ek:act_set="[ek:act_showSingleChoiceDialog]|[@string/msgBoxInvalidTag,@string/msgBoxDifferentWorkplaceConfirmation,a,a]::],[ek:act_reloadAutoFilledWidgets]|[@+id/timeOutDATA],[ek:act_calculate]|[@+id/workTime,(((@+id/timeOutDATA-@+id/timeInDATA)/1000)/3600)],[ek:act_rawUpdateValues]|[cleaningReports,@variable/reportId;cleaningReport_toiletNumber,cleaningReport_toiletCleaningCompleted,cleaningReport_toiletsShowers,cleaningReport_toiletPaperFilled,cleaningReport_handTowels,cleaningReport_soapFilled,cleaningReport_visibleDamage,cleaningReport_visibleDamageComment,cleaningReport_visibleDamageOtherComments,cleaningReport_employeeInitials,cleaningReport_timeOut,cleaningReport_workingTime,cleaningReport_status;@+id/txtToiletNumberDATA,@+id/txtToiletServiceToiletCleaningCompletedDATA,@+id/txtToiletServiceShowersCleanedDATA,@+id/txtToiletServiceToiletPaperFilledDATA,@+id/txtToiletServiceHandTowelsFilledDATA,@+id/txtToiletServiceSoapFilledDATA,@+id/ddCleaningReport_visibleDamages,@+id/txtToiletServiceDamageCommentsDATA,@id/txtToiletServiceOtherCommentsDATA,@+id/txtEmployeesInitialsDATA,@+id/timeOutDATA,@+id/workTime,2]"/>
</source>
Pointer Actions
A pointer value in ginstr launcher is a value that uniquely represents a row which holds some other row in database. Any value in that row of data except value which represents id of the row can be called a pointer value.
- i.e. We have columns
“a”
,”b”
,”c”
in table“one”
- We have a row in table
“two”
which contains column“xy”
which holds some row“id”
. - If we know in column data
“source table”
and“source column”
we will get value of the pointer value. In our case if“source table“=“one”
and“source_column”=”b”
, we will get value of column“b”
read based on pointer id in table“two”
.
- We have a row in table
If pointer id or value needs to be stored into a widget, the following attributes are necessary on target:
GnEditText
gn:data_type="pointer"
– if we just want to load pointed row idgn:getPointerValue=”true”
– if we want to load value from pointed, some additional attributes are necessary:gn:data_source_table="pointedValueTableName"
- name of table which holds pointed rowgn:data_source_field="pointedValueColumnName"
- column which we want to get data from in pointed row, it is necessary that column is ofdt.“text”
, text datatypegn:data_source_request="queryName"
– has to have name of query which prepares data for querying and key in that query has to be“_id”
- i.e. queries.xml “query” example:
- <source lang="xml" enclose="div">
<DbRequest id="roomsByPointer"
viewName="roomsByPointer" fields="room_name, room_administrativeUnit,room_timestampRecordCreation,room_comments" key="_id" />
</source>
GnDropDown
gn:data_source_field=”pointedValueColumnName”
(only necessary when dropdown is used to write or update data to database, not when data is set to dropdown byrawQueryToWidget(s)
gn:s_sourceType="database"
Actions that work with pointers are:
gn:act_rawQueryToWidget(s)
- When using query from database it is possible to store data from pointer columns to widgets
gn:act_loadPointer
- Load pointer is used after pointer
“id”
(not pointer value) is loaded by“rawQueryToWidget(s)”
to a widgetGnEditText
and then properties of theGnEditText
are used to load pointer“value”
into the widget and replace“id”
.
- Load pointer is used after pointer