Preserving old options in dropdowns, checkgroups and radiogroups

From pmusers
Jump to: navigation, search

When the list of options in a dropdown, checkgroup or radiogroup field depends on a database query or an array which can change over time, this can create problems when redisplaying that field at a later time, because the originally selected option may no longer exist. This example shows how to add JavaScript to a DynaForm to preserve the originally selected option in a field after the option has been deleted from the list of available options.


Process: Preserving_old_options_in_fields-2.pmx (right click and select Save Link As)
Author: Amos Batto (amos@processmaker.com)
Version: 2.0 (2019-01-11)
Tested in: ProcessMaker 3.3.0 Community in Debian 9.5 with Firefox 52


In the following example, a DynaForm has a "Payment Method" dropdown whose list of options is provided by the @=paymentOptions case variable. The list of options in this variable can change, so an option selected in the past may no longer exist in the future. If the option no longer exists, then the option will not appear in the dropdown when it is displayed in a DynaForm.

In addition, the Dynaform has a "Product Category" dropdown in the "Order List" grid, whose options are provided by the @=categoryList variable. One of the options in the "Payment Method" dropdown and another option in the "Product Category" dropdown will be removed by a trigger.

FormWithDropdownsInDesigner.png

To prevent the problem of deleted options not appearing in the dropdowns, the following JavaScript code is added to the DynaForm:

function addOptionIfMissing(fieldId) {
  var drpValue = $("#"+fieldId).getValue();

  if (drpValue == '') {
    return;
  }
  
  var drpLabel = $("#"+fieldId).getText();
  var aOpts = getFieldById(fieldId).model.attributes.options;
  var found = false;

  //search for the dropdown's current value in its list of available options:
  for (idx in aOpts) {
    if (aOpts[idx].value == drpValue) {
      found = idx;
      break;
    }
  }

  //if the current value of the dropdown is not in the list of options,
  //then the value has been deleted from the database, so temporarily
  //add it to the list of options so the user can see it:
  if (found === false) {
    $("#"+fieldId).getInfo().options.push({value: drpValue, label: drpLabel});
    $("#form\\["+fieldId+"\\]").append( $(new Option(drpLabel, drpValue)) );
    getFieldById(fieldId).setValue(drpValue);
  }
}

addOptionIfMissing("paymentMethod"); //set to ID of dropdown field 

//set variables for the dropdown in a grid:
var gridId = 'orderList';           //set to ID of grid
var dropdownColumn = 2;             //set to the column number of the dropdown in grid. Counting starts from 1.
var dropdownId = 'productCategory'; //set to the ID of the dropdown in the grid. 
var gridJson = 'orderListJson';     //set to ID of hidden field holding contents of grid in JSON string 

var sGridValues = $("#"+gridJson).getValue();

if (sGridValues != '') {
  var oGridValues = JSON.parse(sGridValues);
  
  for (var i in oGridValues) {
    //if the value is not the same, then the option has been deleted and 
    //needs to be added as an option in the dropdown box:
    if (oGridValues[i][dropdownId] != $("#"+gridId).getValue(i, dropdownColumn)) {
      var oGridField = getFieldById(gridId).gridtable[i-1][dropdownColumn-1];
      var val   = oGridValues[i][dropdownId];
      var label = oGridValues[i][dropdownId+'_label'];
      
      oGridField.getInfo().options.push({value: val, label: label});
      oGridField.getControl().append( $(new Option(label, val)) );
      oGridField.setValue(val);
    }
  }
}

The addOptionIfMissing() function will restore an option that has been deleted from a dropdown, checkgroup or radio button.

The second part of the code restores deleted options in a grid field. Make sure to change the variables to match you Dynaform. In order to restore the options in a grid field, the grid's variable needs to be serialized as a JSON string and stored in a variable associated with a hidden field. The following trigger is fired before the Dynaform, which stores the grid's values in the @@orderListJson variable, which is associated with a hidden field in the Dynaform.

@@orderListJson = json_encode(@=orderList);

To test this code, import the Preserving_old_options_in_fields-2.pmx( process and run a case in it. In between the "Order List Form" and the "Review Order List" form, the following trigger will fire which deletes the "10% down" from the "Payment Method" dropdown and deletes the "Furniture" option from the "productCategory" dropdown in the grid. These originally-selected options will still be maintained when the Dynaform is displayed a second time.

DisplayingDeletedOptionsInDropdowns.png

Note that this code example will not work with suggest boxes, but it is not needed, since suggest boxes are designed to accept values which are not in their list of available options.