Workaround bug with dependent fields in grids

From pmusers
Jump to: navigation, search

If the dependent field is located before the independent field in a grid and the dependent field is a dropdown box, then the selected option in the dropdown will be changed if the Dynaform is displayed a second time.

The way to solve this problem is to save the selected values in the grid as a JSON string in a hidden field when the Dynaform is submitted. Then, when the Dynaform is redisplayed, the saved values in the JSON string can be restored to the grid.



Process with bug: Dependent_before_independent_field_in_grid-1.pmx (right click and select Save Link As)
Process with workaround: Dependent_before_independent_field_in_grid_with_workaround-1.pmx (right click and select Save Link As)
Author: Amos Batto <amos[at]processmaker[dot]com>
Version: 1.0 (2018-04-09)
Tested in: PM 3.3.6 Community in Debian 9.5 with PHP 5.6.37



To see the bug, create a Dynaform with two grids. In the first grid, a dependent field is located before its independent field, while in the second grid, the dependent field is located after the independent field.

DependentBeforeIndependentInGridInDesigner.png

Then, run a case and select the same values in both grids (make sure that the selected option in the dependent field is not the first option in the list):

FillFormDependentBeforeIndependentInGrid.png

Then, submit the form. Notice that the data in the grid is saved correctly in both grids in the debugger.

Then, go the Steps menu to return to the same Dynaform. When the Dynaform is redisplayed, the selected option in the dependent dropdown has been changed from "Freddy Mercado" to "Giovani Lopez", meaning that the correct value is not displayed in the first grid. In contrast, the correct value is displayed in the second grid, because the dependent field is after its independent field.

BugWhenReturnToSameFormDependentBeforeIndependentInGrid.png

To fix this problem, add a hidden field to the Dynaform, whose ID and variable is "gridValsJson", which will hold an array of the grid's values which is saved as a JSON string when the Dynaform was submitted.

When the Dynaform loads, it will check whether there is a saved value in this hidden value. If so, it will use JSON.parse() to convert it from a JSON string to an array. Then, it will pass through the array of grid values and restore the dependent field in each grid row to its previous value when the Dynaform was last submitted.

To implement this workaround, add the following JavaScript to the Dynaform:

var gridId = "usersList";        //set to grid's ID
var dependentFieldColNo = 0;     //set to column number of the dependent field in the grid. Count from 0.
var gridJsonId = "gridValsJson"; //set to the ID of the hidden field holding grid's values as JSON string 

var formId = $("form").prop("id");

//save the array of values in the grid when the form is saved:
$("#"+formId).setOnSubmit( function() {
  var gridValsJson = JSON.stringify( $("#"+gridId).getValue() );
  $("#"+gridJsonId).setValue(gridValsJson);
} );
                          
//when the Dynaform loads, check if there was a saved version of the grid in the hidden field.
//If so, then reset the values in the dependent field to the saved values to avoid the bug
//with dependent fields in grids.

var sGridValues = $("#"+gridJsonId).getValue();
if (sGridValues != "") {
  var aGridValues = JSON.parse(sGridValues);
  
  for (var i in aGridValues) {
    var dependentVal = aGridValues[i][dependentFieldColNo];
    
    //add 1 because setValue() starts counting rows and columns from 1, not 0.
    $("#"+gridId).setValue( dependentVal, i+1, dependentFieldColNo+1 );  
  }
}

Now both the first and second grids should display the same values when the user redisplays the Dynaform:

DependentBeforeIndependentWithWorkaround.png