# Hands-on Practice

## Target Form

[Example](http://oz.ozeform.io/oz/edu/eformdev/customer-day2.html)

### Requirements

<table><thead><tr><th width="204.95668229781649">Item</th><th width="493.3571500240309">Description</th></tr></thead><tbody><tr><td>NRIC</td><td>Auto tab (auto-focus to the next)</td></tr><tr><td>Birthdate</td><td>Month: put items with scripts</td></tr><tr><td>Country</td><td><p>Select "Singapore" or "Singapore PR" -> hide <em><strong>country_other</strong></em></p><p>Select "Others" -> show <em><strong>country_other</strong></em></p></td></tr><tr><td>Smoker</td><td><p>Check "Yes" -> show the BMI band</p><p>Check "No" -> hide the BMI band</p><p>Set the OZFormParam <em><strong>smoker</strong></em>="Yes" -> show the BMI band</p><p>Set the OZFormParam <em><strong>smoker</strong></em>="No" -> hide the BMI band</p></td></tr><tr><td>BMI band</td><td>Calculate Index with Height and Weight</td></tr><tr><td>Plan</td><td>Show the Price 0 for Trial,100 for Standard, and 200 for Premium</td></tr><tr><td>From</td><td>When changing the From date, increase the To date by one year</td></tr><tr><td>To</td><td>Set the default date to one year after the current date</td></tr><tr><td>Radio button groups</td><td>When <em><strong>group1_y</strong></em> and <em><strong>group2_y</strong></em> radio buttons ticked, tick the <em><strong>agree_all</strong></em> checkbox automatically</td></tr><tr><td>"agree_all" checkbox</td><td>When ticked the <em><strong>agree_all</strong></em> checkbox, tick <em><strong>group1_y</strong></em> and <em><strong>group2_y</strong></em> radio buttons automatically</td></tr><tr><td>Full name &#x26; Signature</td><td>Open both SignPads in a single pad (give them the same group name)</td></tr><tr><td>Signature</td><td>When created the signature, show the signed date-time under Signature</td></tr><tr><td>Remove File button</td><td>Remove the file added by AttachmentButton</td></tr><tr><td>Blinking required fields</td><td>Set <strong>Required</strong> to true. Apply viewer options for blinking</td></tr><tr><td>Input validation</td><td>Add a button to check if there are any missing fields</td></tr></tbody></table>

## Implementation

### **1. Viewer options**

{% tabs %}
{% tab title="ReportTemplate" %}

```javascript
// OnStartUp event of the ReportTemplate
This.SetReportOption("viewer.viewmode", "fittoframe"); // fit form into frame
This.SetReportOption("viewer.pagedisplay", "continuous"); // allow scroll down
This.SetReportOption("viewer.showthumbnail", "true"); // show thumbnail pages on the left pane
This.SetReportOption("information.debug", "true"); // show viewer console information on the web
```

{% endtab %}
{% endtabs %}

### **2. Auto tab**

* Create a global function **autoTab** in the **Functions** event of the ReportTemplate.

{% tabs %}
{% tab title="ReportTemplate" %}

```javascript
// Functions event
function autoTab(obj, p){  // move focus to the next
    if(obj.GetText().length == 1){ // got an input char
            obj.GetInputComponent(p).SetFocus(); // move focus to p
    }
}
```

{% endtab %}
{% endtabs %}

* Call the function in the **OnValueChanged** of each single-digit textbox (***n1*** to ***n8***).

{% tabs %}
{% tab title="n1" %}

```javascript
// OnValueChanged of the textbox "n1"
autoTab(This, "n2"); // move to "n2"
```

{% endtab %}
{% endtabs %}

### 3. Put items to *<mark style="color:red;">birth\_mm</mark>*

* Remove items from the **Items** property.

{% tabs %}
{% tab title="birth\_mm" %}

```javascript
// OnStartBind of the ComboBox
var items = "";
for (var i=1; i<13; i++) {
    items += i+"\n";
}
This.SetItems(items);
This.SetSelectedIndex(5);
```

{% endtab %}
{% endtabs %}

### **4. Show/Hide&#x20;***<mark style="color:red;">**country\_other**</mark>* **for input**

* Set **Visible** of ***country\_other*** to "false".

{% tabs %}
{% tab title="country" %}

```javascript
// OnValueChanged of the ComboBox
var obj = This.GetInputComponent("country_other"); // the textbox name
if (This.GetInputValue("country") == "Others") { // if selected "Others"
    obj.SetVisible(true);
    obj.SetFocus();
} else {
    obj.SetVisible(false);
}
```

{% endtab %}
{% endtabs %}

### 5. Add a form parameter

* Add a parameter *<mark style="color:blue;">**smoker**</mark>* to the OZFormParam.
* Set its value to "Yes".

### 6. Tick *<mark style="color:red;">smoker\_y</mark>* & *<mark style="color:red;">smoker\_n</mark>* by *<mark style="color:blue;">**smoker**</mark>**&#x20;\*\*\*\*parameter value***

{% tabs %}
{% tab title="smoker\_y" %}

```javascript
// OnEndBind
var smoker = This.GetDataSetValue("OZFormParam.smoker");
if(smoker == "Yes") {
    This.SetChecked(true);
}
```

{% endtab %}

{% tab title="smoker\_n" %}

```
// OnEndBind
var smoker = This.GetDataSetValue("OZFormParam.smoker");
if(smoker == "No") {
    This.SetChecked(true);
}
```

{% endtab %}
{% endtabs %}

* Set the *<mark style="color:blue;">**smoker**</mark>* to "No".

### 7. Show/Hide *<mark style="color:red;">band\_bmi</mark>* by the *<mark style="color:blue;">**smoker**</mark>* parameter value

{% tabs %}
{% tab title="band\_bmi" %}

```javascript
// OnBind of the BMI band
if(This.GetDataSetValue("OZFormParam.smoker") == "Yes" ){
    This.SetEnable(true);
}else{
    This.SetEnable(false);
}
```

{% endtab %}
{% endtabs %}

* Set the **smoker** to "Yes" and try to preview.

### 8. Set *<mark style="color:blue;">**smoker**</mark>* value from "Yes/No" of Smoker

{% tabs %}
{% tab title="ReportTemplate" %}

```javascript
// Functions event
function reFresh(param, value) {
    var p = "connection.pcount=1;connection.args1=" + param + "=" + value;
    ReportTemplate.ReBind("Report", p, ";");
}
```

{% endtab %}
{% endtabs %}

* Tick Yes -> Set <mark style="color:blue;">smoker</mark> to <mark style="color:green;">Yes</mark>
* Tick No -> Set <mark style="color:blue;">smoker</mark> to <mark style="color:red;">No</mark>

{% tabs %}
{% tab title="smoker\_y" %}

```javascript
// OnValueChanged of "Yes"
if(This.IsChecked() == true){
  // set the value of "smoker" parameter to "Yes" and refresh
    reFresh("smoker", "Yes");  
}
```

{% endtab %}

{% tab title="smoker\_n" %}

```javascript
// OnValueChanged of "No"
if(This.IsChecked() == true){
    // set the value of "smoker" parameter to "No" and refresh
    reFresh("smoker", "No"); 
}
```

{% endtab %}
{% endtabs %}

![](/files/-MjDMQeqfn9blgEdLgvL)

### 9. Calculate BMI (Body Mass Index)

{% tabs %}
{% tab title="height / weight" %}

```javascript
// OnvalueChanged of textbox height and weight 
var h = GetInputValue("height");
var w = GetInputValue("weight");
var v = 10000*w/(h*h);
v = v.toFixed(2);
if (v == "Infinity" || v == "NaN") v = "";
SetInputValue("index",v);
if(v < 18.5 || v > 25){
    GetInputComponent("index").SetTextColor("red");
}else{
    GetInputComponent("index").SetTextColor("blue");
}
```

{% endtab %}
{% endtabs %}

### 10. Update Price when Plan changed

{% tabs %}
{% tab title="plan" %}

```javascript
// OnvalueChanged of the combobox
var price = 0;
var plan = This.GetInputValue("plan");
if ( plan == "Standard" ) { price = 100; }
else if ( plan == "Premium" ) { price = 200; }

This.SetInputValue("price", price); // put value to the textbox "price"
```

{% endtab %}
{% endtabs %}

### 11. Set *<mark style="color:red;">plan\_to</mark>* to one year later than *<mark style="color:red;">plan\_from</mark>*

{% tabs %}
{% tab title="plan\_from" %}

```javascript
// OnvalueChanged
var d= new Date(This.GetText());
d.setFullYear(d.getFullYear() + 1);
var s = _FormatDate(d.valueOf(), "yyyy-MM-dd");
This.SetInputValue("plan_to", s);
```

{% endtab %}

{% tab title="plan\_to" %}

```javascript
// OnEndBind (default)
var d = new Date(This.GetInputValue("plan_from"));
d.setFullYear(d.getFullYear() + 1);
var s = _FormatDate(d.valueOf(), "yyyy-MM-dd");
This.SetInputValue("plan_to", s);
```

{% endtab %}
{% endtabs %}

* Point "\_FormatDate" in the Script Editor and hit \<F1> key.

### 12. Tick *<mark style="color:red;">**agree\_all**</mark>* when both *<mark style="color:red;">**group1\_y**</mark>* **&&#x20;***<mark style="color:red;">**group2\_y**</mark>* ticked

* Set properties of ***agree\_all***:
  * **CheckedValue** = "y"
  * **UnCheckedvalue** = "n"

{% tabs %}
{% tab title="group1" %}

```javascript
// OnValueChanged of the buttongroup "group1"
if(This.GetInputValue("group1") != "Agree"){
    This.SetInputValue("agree_all", "n");
} 
if( GetInputValue("group1") == "Agree" && 
    GetInputValue("group2") == "Agree" ) {
    This.SetInputValue("agree_all", "y");
}
```

{% endtab %}

{% tab title="group2" %}

```javascript
// OnvalueChanged of the buttongroup "group2"
if(This.GetInputValue("group2") != "Agree"){
    This.SetInputValue("agree_all", "n");
} 
if( GetInputValue("group1") == "Agree" && 
    GetInputValue("group2") == "Agree" ) {
    This.SetInputValue("agree_all", "y");
}
```

{% endtab %}
{% endtabs %}

### 13. Tick *<mark style="color:red;">group1\_y</mark>* & *<mark style="color:red;">group2\_y</mark>* by ticking *<mark style="color:red;">agree\_all</mark>*

{% tabs %}
{% tab title="agree\_all" %}

```javascript
// OnValueChanged of the CheckBox
if(This.IsChecked() == true){
    SetInputValue("group1", "Agree");
    SetInputValue("group2", "Agree");
} else {
    SetInputValue("group1", "Disagree");
    SetInputValue("group2", "Disagree");
}
```

{% endtab %}
{% endtabs %}

### 14. Date signed

* Set the **FormID** of ***date\_time*** label to ***date\_time***.

{% tabs %}
{% tab title="signature" %}

```javascript
// OnValueChanged
This.SetInputValue("date_time", This.GetDataSetValue("OZSystem.Date/Time"));
```

{% endtab %}
{% endtabs %}

### 15. SignPadGroup

* SignPad has no **Group Name** in the Properties window.

{% tabs %}
{% tab title="full\_name" %}

```javascript
// OnBind
This.SetGroupName("sign_group");
```

{% endtab %}

{% tab title="signature" %}

```javascript
// OnBind
This.SetGroupName("sign_group");
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="ReportTemplate" %}

```javascript
// OnStartUp event of the ReportTemplate
This.SetReportOption("eform.signpad_type", "dialog"); // "direct" by default
```

{% endtab %}
{% endtabs %}

### 16. Button to remove the attached file

{% tabs %}
{% tab title="ReportTemplate" %}

```javascript
// OnStartUp of the ReportTemplate
This.SetReportOption("viewer.showthumbnail", "true");
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="remove1" %}

```javascript
// OnClick of the button
var obj = This.GetInputComponent("attach1"); // AttachementButton name
if (obj.IsAttached() == true) {
    obj.SetValue("");
}
```

{% endtab %}
{% endtabs %}

### 17. Input validation

* Add a button ***submit*** and put scripts.

{% tabs %}
{% tab title="submit" %}

```javascript
// OnCheckValidity
if(This.GetInputValue("name") == ""){
    _MessageBox("Enter your name", "Submit", function(){
        GetInputComponent("name").EnsureVisible();
        GetInputComponent("name").SetFocus();
    });
    return false;
}
if (This.GetInputValue("gender") == "") {
    _MessageBox("Check your gender", "Submit", function(){
        GetInputComponent("gender").EnsureVisible();
        GetInputComponent("gender").SetFocus();
    });
    return false;
}
if (This.GetInputValue("agree_all") == "n") {
    _MessageBox("Agree to personal information ploicy.", "Submit", function(){
        GetInputComponent("agree_all").EnsureVisible();
        GetInputComponent("agree_all").SetFocus();
    });
    return false;
}
if (This.GetInputValue("signature") == "") {
    _MessageBox("Enter your signature", "Submit", function(){
        GetInputComponent("signature").EnsureVisible();
        GetInputComponent("signature").SetFocus();
    });
    return false;
}
_MessageBox("Validation Success", "Submit");
return true;
```

{% endtab %}
{% endtabs %}

### 18. Styling of required fields

* Set **Required** of all required fields to "true":
* ***name***, ***gender***(RadioButtonGroup), ***agree\_all, full\_name, signature***

{% code title="ReportTemplate" %}

```javascript
// OnStartUp
This.SetReportOption("eform.highlight_duration","2000"); // blinking for 2 sec
// color and thickness of boxes
This.SetReportOption("viewer.stylejson", 
"{\"Name\":\"InputValue\",\"Conditional\":[{\"Condition\":\"Required\",\"HighlightStrokeColor\":\"red\",\"HighlightStrokeThickness\":\"1.5\"}]}");
```

{% endcode %}

👉 Save your form as ***`company_id/user_id/customer.ozr`***.

## Challenge

Try to challenge yourself with an advanced example.

* Switch between two bands at the same position.

[Example](http://oz.ozeform.io/oz/edu/samples/customer-advanced.html)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://edu.ozeform.io/e-form-developer/day-2/practice.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
