Awesome functional formatting

What you'll be learning:

  • How to apply styles that support the business logic and enhance form functionality

The ultimate formatting for mobile forms is when the form would actually not work without it. The latest version of the dashboard form from earlier in your learning journey is a prime example: the delivery tasks in it are ordered by status, but there is no room to explicitly display the status information to the driver. As the whole point of the dashboard form is a quick status update for the driver, the fact that the driver needs several moments to figure out the information presented in the form is a major UX issue.

The presence and text of the closebuttons on the right is the only clue to the tasks' status

Figure 199. The presence and text of the closebuttons on the right is the only clue to the tasks' status


What you'd like to do here is take the functionality of the dashboard form a step further purely with formatting. The idea for the dashboard form is that drivers are instantly notified of any change to the delivery tasks that are assigned to them, without having to open any form.

If this is the first time you meet the Driver Task List dashboard form, you'll appreciate the solution artifacts (reference table declaration files, input data spreadsheets, technical forms, and workflow scripts) that it needs to function.

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.

If you color-coded the delivery tasks that show up on the dashboard by their most important and quickest-changing detail, status, this notification process would be even faster and more comfortable.

Actually, you don't need to make too many changes to the dashboard, because your excellent query statement in the dashboardPanel dynamic list control already sorts the delivery tasks by status.

It's easy for the query to access the status of a delivery task, though - after all, it's right there in the assignments reference table. What you need to figure out is how the sylnRow attribute will access the task status, and apply the various styles accordingly. Give it a moment's thought before you go ahead and download the sample code.

<Form name="dashboard"
  description="Driver Task List"
  form_group="driver"
  typed="true"
  autoform="true"
  hidden="true"
  ksubmit="nobutton"
  dateformat='(dtf yyyy"-"MM"-"dd" "HH":"mm":"ss)'
  numberformat='{decimalSeparator:"."}'>
  <Rgsyl>
    <Syl syln="header"
      clrBg="#EDECC0"
      pctFontSize="110"
      fBold="true"
      duPaddingTop="20px"
      halign="center"/>
    <Syl syln="AssignedRow"
      clrBg="#34A0E8"
      clrFont="#FFFFFF"
      duPaddingTop="10px"
      duPaddingBottom="10px"/>
    <Syl syln="CancelledRow"
      clrBg="#9C6628"
      duPaddingTop="10px"
      duPaddingBottom="10px"/>
    <Syl syln="LoadedRow"
      clrBg="#9C2C28"
      duPaddingTop="10px"
      duPaddingBottom="10px"/>
    <Syl syln="CompletedRow"
      clrBg="#989C28"
      duPaddingTop="10px"
      duPaddingBottom="10px"/>
    <Syl syln="ConfirmedRow"
      clrBg="#124669"
      duPaddingTop="10px"
      duPaddingBottom="10px"/>
  </Rgsyl>
  <Control type="panel" name="root">
    <Control type="label" name="header" text="Driver Task List"/>
    <Control name="dashboardPanel"
      type="panel"
      data_type="string, string, string, string"
      navigation="inline"
      layout="table"
      table_width="1 swt"
      generator="SELECT assignment_id, client, load_address, status
                  FROM Reference_assignments
                  WHERE usr =@user AND status IN ('Assigned', 'Confirmed', 'Loaded')
                  ORDER BY CASE WHEN status='Confirmed' THEN 1
                  WHEN status='Loaded' THEN 2
                  WHEN status='Cancelled' THEN 3
                  WHEN status='Assigned' THEN 4 END"
      sylnCrown="=header"
      sylnRow="SELECT @1||'Row'"
      sylnargRow="SELF.col3">
      <Control name="client"
        type="label"
        label="Client"
        width="remaining 2"
        reference="REF"
        ref_arg="PARENT.col1"/>
      <Control name="address"
        type="link"
        link_type="address"
        label="Load address"
        width="remaining 2"
        link_target_reference="REF"
        link_target_ref_arg="PARENT.col2" />
      <Control name="confirmPanel"
        type="panel"
        navigation="inline"
        width="remaining 1"
        generator="SELECT '' WHERE @1='Assigned' AND NOT EXISTS
                    (SELECT * FROM Reference_assignments
                    WHERE usr =@user AND status IN ('Confirmed', 'Loaded'))"
        ref_arg="../PARENT.col3">
        <Control name="confirm"
          type="closebutton"
          text="Confirm"
          action="submit_form"/>
        <Control name="assignment_id"
          type="label"
          visible="false"
          reference="REF"
          ref_arg="../../PARENT.col0"/>
      </Control>
      <Control name="loadPanel"
        type="panel"
        navigation="inline"
        width="remaining 1"
        generator="SELECT '' WHERE @1='Confirmed'"
        ref_arg="PARENT.col3">
        <Control name="load"
          type="closebutton"
          text="Load cargo"
          action="discard_form"
          next_form_name="load"/>
      </Control>
      <Control name="unloadPanel"
        type="panel"
        navigation="inline"
        width="remaining 1"
        generator="SELECT '' WHERE @1='Loaded'"
        ref_arg="PARENT.col3">
        <Control name="unload"
          type="closebutton"
          text="Deliver cargo"
          action="discard_form"
          next_form_name="unload"/>
      </Control>
      <Control type="panel"
        name="default"
        navigation="inline"
        width="remaining 1"
        layout="standard"
        sylnRow="=AssignedRow"
        generator="SELECT '' WHERE NOT
                  (@1='Assigned' AND NOT EXISTS
                  (SELECT *
                  FROM Reference_assignments
                  WHERE usr =@user
                  AND status IN ('Confirmed', 'Loaded'))
                  OR @1='Confirmed'
                  OR @1='Loaded')"
        ref_arg="PARENT.col3">
        <Control type="label"
          name="placeholder"
          text=""/>
      </Control>
    </Control>
  </Control>
</Form>

The solution on line 56 is to use the SELF operator to access the status column in the query result - simple really.

Apart from this, there's not much going on in the code above: naming the Syls after the status data that they refer to saves you a lot of typing, and the table_width attribute combined with the remaining keyword to distribute the columns in a user-friendly way makes for a cleaner overall look.

The only slightly interesting styling decision is to have the fallback panels styled as if they were the 'Assigned'-status tasks. This is because if there's no hitch in the workflow, the delivery tasks on the dashboard without a closebutton are 'Assigned'-status tasks. If the fallback panels ever come into play, this way they'll go unnoticed.

Save, publish, and wait for the dashboard form to sync itself on your Android device. Confirm, load, and deliver one or two of your displayed deliveries, and see the background color of the tasks change as their status progresses.

If no delivery tasks show up on your device, the reason might be that the assignments reference table does not contain the user account that you're logged in with. The hassle-free solution is to modify your username to petar.hoyt@gmail.com on the Users tab of the Backoffice site.

The Rocky Jupiter branded color scheme on show in status-based functional formatting
The Rocky Jupiter branded color scheme on show in status-based functional formatting

Figure 200. The Rocky Jupiter branded color scheme on show in status-based functional formatting


If you have followed along with the previous tutorials, you officially know and have tried everything. This is as much as we can teach you about mobile forms. You'll need to actually make your own workflow solution, and publish it to real users to learn more.