Dynamically update another field when the current field is modified

Dynamically update another field when the current field is modified

book

Article ID: KB0076265

calendar_today

Updated On:

Products Versions
TIBCO EBX All versions from 5.8.0.

Description

The aim of this article is to be able to dynamically change the value of another field when the current field is modified, without having to save the record.
 

Issue/Introduction

Dynamically update another field when the current field is modified

Resolution

In order to achieve this we will implement a custom widget and apply it on the current field.

Please refer to the documentation:

In our widget implementation we will have to create a Javascript function that will update the other field.

 

When setting/getting a node value in javascript, you have to specify prefixed paths in the aPath parameter. You have to use getPrefixedPath:

https://docs.tibco.com/pub/ebx/5.9.5/doc/html/en/Java_API/com/orchestranetworks/ui/form/UIFormWriter.html#getPrefixedPath-com.orchestranetworks.schema.Path-

Also, you have to pay attention to the javascript type structure that is needed/returned depending on the widget.

For example, the javascript type for the UIComboBox widget is an Object with three fields: keylabel and previewURL.

You will find this information in the "Javascript type" section of each widget javadoc.

 

Once we have implemented our Javascript function, we have to specify that this function will be called each time the current field is modified. 

To achieve this we will call the setActionOnAfterValueChange method on the widget and specify the name of the javascript function:

More precisely, the JS function will be called after the field loses the focus (when clicking outside the field).

When calling the setActionOnAfterValueChange method, the current field value is automatically passed as the first argument of the javascript function.

If your javascript function uses another argument, you can specify its value using on(String aFunctionName, String anArgument) instead.


Example 1: reset field

I want to set the fk2 field as null when the fk1 field is modified (foreign key combo boxes).

write method implementation:

public void write(WidgetWriter writer, WidgetDisplayContext context) {
 
    Path fk2PrefixedPath = writer.getPrefixedPath(Path.parse("../fk2"));
     
    writer.addJS_cr("function resetFk2(){");
    writer.addJS_setNodeValue("null", fk2PrefixedPath);
    writer.addJS_cr("}");      
     
    UIComboBox box = writer.newComboBox(Path.SELF);
    box.setActionOnAfterValueChanged(JsFunctionCall.on("resetFk2"));
 
    writer.addWidget(box);
 
}


Example 2: concatenate two fields

I want a string field (str3) to be the concatenation of two string fields (str1 and str2). I want this field to be updated each time str1 or str2 is modified. All fields are text boxes (javascript string type).

To achieve this I will need two widgets, with (almost) the same implementation.

write method implementation of str1 widget:

public void write(WidgetWriter writer, WidgetDisplayContext context) {
 
        Path str3PrefixedPath = writer.getPrefixedPath(Path.parse("../str3"));
        Path str2PrefixedPath = writer.getPrefixedPath(Path.parse("../str2"));
         
        writer.addJS_cr("function updateStr3(value){");
 
        writer.addJS("var str2Value = ");
        writer.addJS_getNodeValue(str2PrefixedPath);
        writer.addJS_cr(";");
 
        writer.addJS_setNodeValue("value.concat(str2Value)",str3PrefixedPath);
 
        writer.addJS_cr("}");
         
        UITextBox box = writer.newTextBox(Path.SELF);
        box.setActionOnAfterValueChanged(JsFunctionCall.on("updateStr3"));
         
        writer.addWidget(box);
 
    }

Example 3: uppercase

I want a string field (text box) to be upper cased each time it is modified.

public void write(WidgetWriter writer, WidgetDisplayContext aContext) {
 
    Path prefixedCurrentPath = writer.getPrefixedPath(Path.SELF);
     
    writer.addJS_cr("function valueToUpperCase(value){");
    writer.addJS_cr("if(value === value.toUpperCase())"); //check if the value is already uppercased
    writer.addJS_cr("return;");
    writer.addJS_cr("value = value.toUpperCase();");
    writer.addJS_setNodeValue("value", prefixedCurrentPath).addJS_cr();
    writer.addJS_cr("}");
 
    UITextBox textBox = writer.newTextBox(Path.SELF);
    textBox.setActionOnAfterValueChanged(JsFunctionCall.on("valueToUpperCase"));
    writer.addWidget(textBox);
}