In this section, you'll finish up the Vehicle Inspection form, adding the finishing touches to your creation.
Problem: The user of the form has to go inside the popup panels in the form to check the result of the inspection. This is inconvenient.
Solution: put an automatically updating running total of all the positive and negative inspection results outside the popup panels, so the driver can see it as soon as he or she opens the form.
Keep count of user input in your form, and display it
In the previous section of the tutorial, you already used a hidden label as a helper variable, and then counted and used its value later. Here, you'll be setting up five hidden labels in total:
-
the first two will keep score of the number of 'Yes' and 'No' answers in the popup panels (
YesCounter
andNoCounter
) -
a second two (
hiddenSegmentYesLabel
andhiddenSegmentNoLabel
) will count the values in the first two -
the last helper variable will have a value of 1 every time the user adds an optional car part - you'll count these 1's as 'No's
Finally, in two labels that are not hidden (inOrder
and
notInOrder
), you'll use the special SUM
query
operator to add up all the positive and negative answers.
Figure 91. Overview of how the hidden labels reference each other in the form to display the summary of the user input in the form
-
Add the
YesCounter
andNoCounter
hidden labels below theSegmentedControl
element that they refer to.They simply store whether the segmented control that they are generated with has a Yes or No value.
Because you'll use the
COUNT
query operator to keep track of how many there are, you need to set the data_type attribute ofYesCounter
andNoCounter
tobool
.... <Control type="panel" name="popupGenerator" layout="table" headless="true" navigation="inline" generator="SELECT distinct where_in_vehicle FROM Reference_parts"> ... <Control type="panel" name="Popup" navigation="popup"> <Control type="panel" name="wrapper" layout="standard" navigation="inline" generator="SELECT part_name FROM Reference_parts WHERE required='1' AND where_in_vehicle=@1" ref_arg="../../popupLabel"> ... </Control>
<Control type="label" name="YesCounter" visible="false" data_type="bool" reference="SELECT @1='Yes'" ref_arg="../SegmentedControl"/> <Control type="label" name="NoCounter" visible="false" data_type="bool" reference="SELECT @1='No'" ref_arg="../SegmentedControl"/>
</Control> ... </Control> ... -
Add the
hiddenOptionalPartLabel
hidden label inside theOptionalParts
panel.What this does: Each time the user taps the add button to generate an extra problem reporting control, this hidden label will also generate once, with the number '1' as its value.
At a later point, you will add these '1' values up, and add them to the number of negative answers.
-
Add the
hiddenSegmentYesLabel
andhiddenSegmentNoLabel
hidden labels below thesubmitter
panel.The
COUNT
query operator in their query statement returns how many Yes's and No's there are in the form.You can't use
YesCounter
andNoCounter
for this, because those controls are inside a dynamic list control, and are themselves generated.... <Control type="panel" name="submitter" navigation="inline" generator="SELECT '1' WHERE @1 ='No'" ref_arg="../SegmentedControl"> ... </Control>
<Control type="label" name="hiddenSegmentYesLabel" data_type="int" visible="false" reference="COUNT" ref_arg="../YesCounter"/> <Control type="label" name="hiddenSegmentNoLabel" data_type="int" visible="false" reference="COUNT" ref_arg="../NoCounter"/>
...The
COUNT
query operator takes boolean type values as input, and returns how many were true.Make sure that whenever you use the
COUNT
or theSUM
operators the containing element has a data_type="int" attribute.When you use
COUNT
orSUM
, and the path to the control that you bind them to includes one or more dynamic list controls, you need to use the.*/
wildcard regular expression for each of the dynamic list controls in the path, to reference each and every generated child element of the dynamic list. -
Add the
inOrder
andnotInOrder
labels below thepopupGenerator
element.Both of these uses the
SUM
query operator to add up the positive and the negative answers, respectively.... <Control type="panel" name="popupGenerator" layout="table" headless="true" navigation="inline" generator="SELECT distinct where_in_vehicle FROM Reference_parts"> ...
</Control> <Control type="label" name="inOrder" label="Number of working parts" data_type="int" reference="SUM" ref_arg="../popupGenerator/popupGenerator. */Popup/wrapper/wrapper.*/hiddenSegmentYesLabel"/> <Control type="label" name="notInOrder" label="Number of faulty parts" data_type="int" reference="SUM" ref_arg="../popupGenerator/popupGenerator. */Popup/wrapper/wrapper.*/hiddenSegmentNoLabel, ../popupGenerator/popupGenerator.*/Popup/OptionalParts/OptionalParts. */hiddenOptionalPartsLabel"/>
...Make sure that whenever you use the
COUNT
or theSUM
operators the containing element needs to have a data_type="int" attribute. -
Save and publish the new
vehicleInspection.form.xml
, and be pleased. The number of positive and negative answers from the user are summarized below the popup panels in the form in real time.
Add a datepicker and a barcode scanner control, and let the user sign the form
The datepicker, the barcode scanner, and the signature controls are subtypes of
another type of control that you already used: the datepicker and the scanner are
disguised textbox
es, and the signature control is actually a
photo
control.
Let's start out with the barcode scanner: insert the following lines into the form
above the inOrder
and notInOrder
labels:
The
ptype="barcode"
is what makes a garden-variety text box turn
into a barcode scanner control.
When the user taps the barcode icon, the device camera will fire up, and scan the barcodes that it detects. The textual representation of the barcode will appear in the text box to the left of the icon.
The readonly="true"
attribute is also important: you can prevent the
driver from editing the text value that the barcode scanner read off.
Read some more about the barcode scanner control here.
Go and add the following code below the inOrder
and
notInOrder
labels:
... <Control type="textbox" name="datepicker" label="Select the current date" readonly="true" ptype="date" dateformat='(dtf yyyy"-"MM"-"dd)' now_button_label="Today" show_clear_button="true"> <Validators> <Validator type="DateValidator" from="2014-01-01" to="2014-12-31"/> </Validators> </Control> <Control type="photo" meta_type="signature" name="Signature"> <Validators> <Validator type="RequiredValidator"/> </Validators> </Control> ...
You
modify the entry-mode of a text box control with the ptype="date"
and the readonly="true"
attributes to accept dates but not
text.
The DateValidator
is a specialized validator control only avilable
for date- and timepickers. It checks whether the date that the user entered conforms
to the dateformat
attribute that you declared for the datepicker,
and is therefore particularly important if you allow the user to enter a date
manually. With the optional from
and to
attributes, you can narrow the input that you allow down to a specific period.
A signature control is a photo
control with
the meta_type="signature"
attribute. When the user taps it, it
expands to fill the screen of the device, and accepts taps and strokes. The
resulting image is the value of the control.