What you'll be learning:
This is what your device screen will look like when you're done
What you're being asked to do
Still hacking away at the Rocky Jupiter delivery task assignment project. You've built up a very nice foundation in the previous section: the workflow is ticking away nicely. The technique you'll pick up in this part is the difference between an 'OK' workflow solution, and a badass one.
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.
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 click Save.
-
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.
They still have 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="Date" NotNull="true"></Column> <Column Name="unload_date" Type="Date" 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. Fancy this: 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 shouldn't even have to open the form.
An obvious workaround could be to not close the form, ever, right? Not quite. As you will shortly see when handling conflicting reference data edits, for reasons of local data consistency, forms do not display updated values while open. Any driver who keeps their 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:
Read up on dashboard forms and what they can do for you.
All it takes is adding the dashboard="true"
attribute to the
form
root element. Honest.
In fact, since you've probably guessed what's coming, here's
confirm.fls.xml
as a dashboard
form:
So far so cool. A dashboard is supposed to be a sort of info-screen, though, and this
dashboard is only displayed after a delivery task is finished. Both the
load
and unload
forms immediately open a new form when
submitted, so the dashboard doesn't actually pop up to show how the number and status of
assigned delivery statuses change.
However, if you simply go ahead and delete the submitbutton
controls in
load
and unload
, there won't be any way for your hapless
driver to move the workflow forward. What would Obi-Wan do?
Integrate the workflow into the dashboard.
Getting rid of the nextForm
attributes in the two non-dashboard form
submitbutton
s is definitely the way to go. That way, the forms will be
submitted to the server and fire the workflow scripts, but no new form is automatically
opened, therefore, the client pops the dashboard form back on. The
submitbutton
s that open the load
and
unload
forms need to be on the dashboard itself.
However, you need a way to make sure that the text of the submitbutton
is set according to the status
field of the task they refer to: if it's
Assigned, the button should read Confirm,
if it's Confirmed the button should read
Load, and Loaded should go with
Deliver. That looks like three if
elements right
there.
You also need to make sure that there will still be no way for sneaky
drivers to Confirm any delivery until any other task is either
Loaded or Confirmed. A wrapper
if
should take care of that. Let's see how this could be pulled
off.
<form ...> <table id='assigned' record='a' recordset='{SELECT a.usr, a.assignment_id, a.client, a.load_address, a.load_date, a.status FROM assignments aWHERE a.usr==sysp.user
}'> ... <row> ... <cell> <if cond='{a.status IN ("Assigned", "Confirmed", "Loaded")}'> <if cond='{SELECT a.status=="Assigned" AND NOT EXISTS (SELECT "" FROM assignments o WHERE o.usr==sysp.user AND o.status IN ("Confirmed", "Loaded"))}'> <submitbutton id='confirm' text='Confirm'/> </if> <if cond='{a.status=="Confirmed"}'> <submitbutton id='load' nextForm='{forms.load}' text='Load cargo'/> </if> <if cond='{a.status=="Loaded"}'> <submitbutton id='unload' nextForm='{forms.deliver}' text='Deliver cargo'/> </if> </if>
</cell> </row> table> </form>
Note
that the query in the table
control's recordset
now
doesn't filter for Assigned status deliveries, but lets everything
through. The if
that shows or hides the submitbutton
s
does the filtering. So, if the status is one of the three interesting ones (line 15), we
show the driver a submitbutton
with the status-related
text
, but nobody gets a Confirmed button until
any task is still in progress.
Fun isn't over yet. You know what would be really awesomesauce? If the tasks in the
dashboard were ordered by their statuses, so that whatever task is active at the moment
would be at the top of the table. The driver wouldn't even have to scan the table to see
if there's a new delivery task assigned to them. It doesn't take much, just an ORDER BY clause in the table recordset
query
expression:
<form ...> ... <table id='assigned' record='a' recordset='{SELECT a.usr, a.assignment_id, a.client, a.load_address, a.load_date, a.status FROM assignments a WHERE a.usr==sysp.userAND a.status NOT IN ("Completed") ORDER BY CASE WHEN status="Confirmed" THEN 1 WHEN status="Loaded" THEN 2 WHEN status="Assigned" THEN 3 WHEN status="Cancelled" THEN 4 END}'>
... </table> </form>
Completed tasks won't show up any more, and the ordering makes sure that the currently active task is at the top.
Save, publish, and check on the device.
The Force is strong with you! In the next section, its all your workflow scripting
powers combined!