If you're new to Mobilengine tutorials, welcome! Be sure to grab all the artifacts from Mobile form development parts 1 & 2, and the Workflow scripting tuts before you go on.
-
How to set up rows in a reference table that only ever synchronize to selected users
-
How to make a change in a reference table trigger data synchronization on the devices that use the reference table
-
How to notify the user with a jingle that the reference data in the form has been updated.
-
How to set up a form that stays open, and updates automatically (aka dashboard form)
This is what your device screen will look like when you're done
What you'd like to do with the form
Remember the Rocky Jupiter Transport Company and the truck inspection form you set up for them? Well, this fictional company liked your work, and just re-hired you for a job. They still use Mobilengine for their workflow solutions, so there shouldn't be too much trouble.
What the trucking company wants is to let every one of its truck drivers know about the deliveries and shipping tasks as soon as the tasks arrive in the company database. A system administrator assigns the incoming freight orders to various drivers, and Rocky Jupiter wants the drivers to go and pick up the cargo for their assigned tasks as soon as possible.
They would like to have the list of tasks and their details update as soon as possible on the drivers' mobile devices, and they want to alert the drivers that the list has updated, so that they check their device.
It would also be ideal if the driver didn't have to open a form to check the task list, but would have it display on his or her screen all the time.
With the Mobilengine developer environment, all this is actually quite a straightforward job.
Set up the dynamic list control in the form
-
Set up the reference table that will hold the data to update the form that you're building: let's call it
assignments
. Create the reference table declaration below, save it to theRockyJupiter
solution artifacts folder, and publish it to the Mobilengine Developer Cloud.<Reftab Name="assignments" xmlns="http://schemas.mobilengine.com/reftab/v1"> <Columns> <Column Name="usr" Type="Text"></Column> <Column Name="assignment_id" Type="Text" NotNull="true"></Column> <Column Name="client" Type="Text" NotNull="true"></Column> <Column Name="load_type" Type="Text" NotNull="true"></Column> <Column Name="load_address" Type="Text" NotNull="true"></Column> <Column Name="load_date" Type="Text" NotNull="true"></Column> <Column Name="unload_date" Type="Text" NotNull="true"></Column> <Column Name="unload_address" Type="Text" NotNull="true"></Column> <Column Name="comments" Type="Text"></Column> <Column Name="photo_load" Type="Text"></Column> <Column Name="photo_unload" Type="Text"></Column> <Column Name="status" Type="Text" NotNull="true"></Column> </Columns> </Reftab>
-
You've got an empty
assignments
reference table sitting in the cloud. It's not much use without reference data. Grab this input data spreadsheet to populate it. -
Now to the form that will reference this data. Name the form
taskList
, add a header label control with the UI name Driver Task List.You'd like a dynamic list control that displays all the tasks that are assigned to the user in the
assignments
reference table. For reasons of screen real estate economy, make the form only display the client data and the loading address for the tasks in the dynamic list control:The tutorials assume that you are logged in as petar.hoyt@gmail.com. The current user-based filtering won't work on the sample reference tables otherwise.
<Form name="taskList" description="Driver Task List" typed="true" dateformat='(dtf yyyy"-"MM"-"dd" "HH":"mm":"ss)' numberformat='{decimalSeparator:"."}'> <Control type="panel" name="root"> <Control type="label" name="header" text="Driver Task List"/> <Control type="panel" data_type="string, string" name="dashboardPanel" navigation="inline" layout="table" generator="SELECT client, load_address FROM Reference_assignments WHERE usr=@user AND status='Assigned'"> <Control type="label" name="status" label="Client" reference="REF" ref_arg="PARENT.col0"/> <Control type="label" name="address" label="Load address" reference="REF" ref_arg="PARENT.col1"/> </Control> </Control> </Form>
Save the form, and publish it along with the input data spreadsheet for the
assignments
reference table. Synchronize your device with the server, and open the form. -
This code uses the
WHERE usr=@user
filter in the query to display only the delivery tasks that are assigned to the driver who opened the form. This means that all the data is sent to every user's device, and the reference table only gets filtered inside the form. That's not necessarily a problem, but if the reference table that your query uses is large, or you expect it to grow steadily, there is a better way.The amount of data that needs to be downloaded to each user's phone can easily get out of hand as more drivers are added to the reference table, and if your form only ever needs to display the current user's data, more and more unnecessary data will accumulate on your user's mobile devices, slowing down processes and hogging memory.
The solution is to move filtering for the current user from the form into the cloud, and set up the reference table itself to not send all its rows to all the mobile devices with the
taskList
form, so each user downloads only the rows that are assigned to the him or her. All the actual coding that you need to do is inserting theAgentName="true"
attribute into the reference table declaration, on the column that lists the names of the drivers.<Reftab Name="assignments" xmlns="http://schemas.mobilengine.com/reftab/v1"> <Columns> <Column Name="usr" Type="Text"
AgentName="true"
></Column> <Column Name="assignment_id" Type="Text" NotNull="true"></Column> <Column Name="client" Type="Text" NotNull="true"></Column> <Column Name="load_type" Type="Text" NotNull="true"></Column> <Column Name="load_address" Type="Text" NotNull="true"></Column> <Column Name="load_date" Type="Text" NotNull="true"></Column> <Column Name="unload_date" Type="Text" NotNull="true"></Column> <Column Name="unload_address" Type="Text" NotNull="true"></Column> <Column Name="comments" Type="Text"></Column> <Column Name="photo_load" Type="Text"></Column> <Column Name="photo_unload" Type="Text"></Column> <Column Name="status" Type="Text" NotNull="true"></Column> </Columns> </Reftab>Save the new declaration, and re-publish the solution folder. You won't see any difference if you open the form, but you have reduced the amount of the data that needs to be synchronized to your mobile device.
-
Why don't you make this simple form a little more user-friendly? You could let the driver look up the load address with a single tap.
Do you remember the link control? Change the
address
label in the form into a map link:<Form name="taskList" description="Driver Task List" typed="true" dateformat='(dtf yyyy"-"MM"-"dd" "HH":"mm":"ss)' numberformat='{decimalSeparator:"."}'> <Control type="panel" name="root"> <Control type="label" name="header" text="Driver Task List"/> <Control type="panel" data_type="string, string" name="dashboardPanel" navigation="inline" layout="table" generator="SELECT client, load_address FROM Reference_assignments WHERE usr=@user AND status='Assigned'"> <Control type="label" name="status" label="Client" reference="REF" ref_arg="PARENT.col0"/>
<Control type="link" name="address" link_type="address" label="Load address" link_target_reference="REF" link_target_ref_arg="PARENT.col1" />
</Control> </Control> </Form>Save the form, re-publish, sync, and open:
If you tap one of the addresses, the built-in mapping application of your device opens and displays it.
-
Another job well done, right? You data-bound the
assignments
reference table into thedashboardPanel
, so it will always display the up-to-date list of tasks that are assigned to the user.Well, not always. Only every time the user synchronizes the device with the cloud, or a scheduled synchronization that was set up on the Backoffice site runs. And another inconvenience: the updated data will only appear after syncing if the user closes and re-opens the form.
What if the user forgets to regularly synchronize? Must the user really have to close and re-open to see the new data? Isn't there a better way to make the very latest reference data updates appear on users' devices?
Trigger data synchronization whenever the reference data updates
There are actually two ways to make data-bound forms always display the latest reference data:
-
setting up automatic data synchronization at relatively short intervals on the Backoffice site
This method is not recommended, because it puts too much load on the server, and generates unnecessary data traffic.
-
To set up automatic data synchronization for all of your mobile users at once, log in to the Backoffice site, and go to the Settings → Mobile synchronization screen.
-
Select the second check box from the top: Input data and form template synchronization interval (sec), and enter your preferred sync interval. For example, if you want to have 1 sync every 30 minutes, enter 1800. Click Save in the upper left of the screen.
-
When the mobile users next sync with the cloud, the updated settings will take effect on their devices, and reference data will be automatically synchronized to their phones or tablets at the specified intervals.
-
-
setting up synchronization each time the reference data is updated, in reference table declarations or on the Backoffice site
This is the method the experts recommend: this way, you'll only generate data traffic when necessary.
-
To trigger synchronization on users' devices whenever the input data in a given reference table changes, include the
Push="true"
attribute in theReftab
element of the reference table declaration before you publish it. -
You need to allow the
Push="true"
attribute in the reference table declarations before they can take effect: log in to the Backoffice site, and go to the Settings → Mobile synchronization screen. Select the Enable push notification check box, and clickSave.
-
Notify the user whenever the form is updated
These Rocky Jupiter people can never get enough. They tell you, fine, the drivers' task list is always up to date, but the driver may not be aware of recent changes.
He or she still has to regularly check the device for an update. What if you could somehow tell users that their form has new data?
Enter the Mobilengine jingle. You can make your users' devices
play it every time the reference data in their forms has been updated. It only takes one
more attribute in the declaration of the relevant reference table:
Notify="true"
. Observe.
<Reftab Name="assignments" xmlns="http://schemas.mobilengine.com/reftab/v1"
Push="true" Notify="true">
<Columns> <Column Name="usr" Type="Text" AgentName="true"></Column> <Column Name="assignment_id" Type="Text" NotNull="true"></Column> <Column Name="client" Type="Text" NotNull="true"></Column> <Column Name="load_type" Type="Text" NotNull="true"></Column> <Column Name="load_address" Type="Text" NotNull="true"></Column> <Column Name="load_date" Type="Text" NotNull="true"></Column> <Column Name="unload_date" Type="Text" NotNull="true"></Column> <Column Name="unload_address" Type="Text" NotNull="true"></Column> <Column Name="comments" Type="Text"></Column> <Column Name="photo_load" Type="Text"></Column> <Column Name="photo_unload" Type="Text"></Column> <Column Name="status" Type="Text" NotNull="true"></Column> </Columns> </Reftab>-
Save the declaration and re-publish your solution. From now on, whenever you or another Rocky Jupiter user submits changes to the
assignments
reference table, your device and their devices will download the changes, and everyone will hear the melody.
Set up a dashboard form
The Rocky Jupiter people are a tough bunch to please. Now they want you to make the drivers' life even more comfortable, and make the form with the task list always open on their devices. When they hear the jingle, they won't even have to open the form
An obvious workaround could be to not close the form, ever, right? Not quite. As you might have noted when handling conflicting reference data edits, for reasons of local data consistency, forms do not display updated values while open. Any driver who keeps his or her task list open to guarantee being up-to-the-minute will in fact miss all the updates.
The solution you need is called dashboard form in the Mobilengine mobile form terminology. You can put all the familiar controls in a dashboard form, but it has some special features that make it ideal for the transport company's purposes:
-
Three
Form
element attributes make a dashboard form what it is:-
autoform="true"
: this basically says 'You are a dashboard form.' You can't have a dashboard form without it. -
hidden="true"
: if you set this attribute, the form will not appear in the left-hand Forms screen panelThis attribute might be familiar from when you created the error message form for your workflow script.
-
ksubmit="nobutton"
: this attribute specifies what submission buttons are available on the form.nobutton
means none, but there are three other available values.
Save, publish, and try out your new creation: you'll find the new form is stuck to the right-hand side of your screen. You can't close it, and it stays open even if you open another form - you won't see it, but it's there. When you sync the device, you'll see the dashboard form close briefly after the sync, and pop up again with the updated data.
-
-
Trouble is, the specifications for the Rocky Jupiter driver dashboard have changed slightly since you started this project:
The managers now want to show the drivers not only their newest tasks, but all their in-progress tasks as well.
Plus, they want to show the tasks ordered by status: the newest and most important on top, the least important almost completed tasks at the bottom.
You need to play around with the
SELECT
statement of thedashboardPanel
dynamic list control a bit to pull this off. Use the same kind ofCASE WHEN
conditional expression that you put into the contacts list form when you wanted to sort the search results.<Form
name="dashboard"
description="Driver Task List" typed="true" autoform="true" hidden="true" ksubmit="nobutton" dateformat='(dtf yyyy"-"MM"-"dd" "HH":"mm":"ss)' numberformat='{decimalSeparator:"."}'> <Control type="panel" name="root"> <Control type="label" name="header" text="Driver Task List"/> <Control type="panel" data_type="string, string, string" name="dashboardPanel" navigation="inline" layout="table" generator="SELECT client, load_address,status
FROM Reference_assignments WHERE usr=@userORDER BY CASE WHEN status='Assigned' THEN 1 WHEN status='Confirmed' THEN 2 WHEN status='Cancelled' THEN 3 WHEN status='Loaded' THEN 4 WHEN status='Completed' THEN 5 END">
... </Control> </Control> </Form>Save, publish, and open on your mobile device.
-
As you can see, this last change to the form introduced a new problem: your
SELECT
query orders the tasks in the reference table by status, but no-one can tell when they look at the form. -
Let's display the value of
status
column in the dashboard form so that the driver is not confused.Include the
status
column in thedashboardPanel
query statement, and extend the template of thedashboardPanel
dynamic list control with a label that you data-bind to the value that the query returns for this column.... <Control type="panel" data_type="string, string, string" name="dashboardPanel" navigation="inline" layout="table" generator="SELECT client, load_address,
status
FROM Reference_assignments WHERE usr=@user ORDER BY CASE WHEN status='Assigned' THEN 1 WHEN status='Confirmed' THEN 2 WHEN status='Cancelled' THEN 3 WHEN status='Loaded' THEN 4 WHEN status='Completed' THEN 5 END"><Control type="label" name="status" label="Task status" reference="REF" ref_arg="PARENT.col2"/>
...Figure 129. The final version of the dashboard form, with the delivery tasks sorted and labeled by status
-
Lovely. The dashboard updates whenever the task list changes, and notifies the driver about it, who doesn't even have to open a form to check his or her delivery tasks.
Wouldn't it be even better, though, if the driver could not only see if he or she has been given a new task, but immediately do something about it using the mobile solution?
You guessed it: there's still more to dashboard forms. Check out the workflow setup tutorial for more.