Check datetimes inside grid

From pmusers
Jump to: navigation, search

This example shows how to check whether the datetime fields inside a grid are inside the proper bounds when the Dynaform is submitted.



DynaForm: Grids-Crane_times.json (right click and select Save link as)
Author: Amos Batto (amos@processmaker.com)
Version: 1.0 (2018-09-18)
Tested in: ProcessMaker 3.2.3 Community in Debian 9.5 with Firefox 52


The moment.js functions .isBefore(), .isSameOrBefore(), .isAfter(), .isSameOrAfter(), .isSame() and .isBetween() can be used to check whether the values in datetime fields are inside acceptable bounds. All these functions have an optional second parameter to specify the "year", "month", "day", "hour", "minute", "second" or "millisecond", so that they can compare within a specified unit of time.

In this example, a Dynaform is used to schedule the work times for a crane at a work site. The user enters the datetimes when the crane will be on the work site and then enters a series of datetimes in a grid when the crane will work on specific jobs at that site. Each of the datetimes entered in the grid must be between the datetimes when the crane arrives at the site and it taken off site.

Create the following Dynaform to fill out the work times for the crane at the construction site:

Grids-CraneTimesFormInDesigner.png

This form has the following fields:

  • Datetime with the ID "craneArrivalTime"
  • Datetime with the ID "craneOffSiteTime"
  • Grid with the ID "craneWorkTimes" with the following fields:
    • Textbox with the ID "jobDescription"
    • Datetime with the ID "craneStartTime"
    • Datetime with the ID "craneFinishTime"
  • Submit button

Add the following JavaScript code to the form:

var gridId        = 'craneWorkTimes'; //set to the ID of the grid
var startTimeId   = 'startLiftTime';  //set to the ID of the start time field in grid
var finishTimeId  = 'finishLiftTime'; //set to the ID of the finish time field in grid
var startTimeCol  = 2;                //set to the column number of the start time field in grid
var finishTimeCol = 3;                //set to the column number of the finish time field in grid

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

$("#"+formId).setOnSubmit( function() {
  var arrivalTime = moment( $("#craneArrivalTime").getValue() );
  var offSiteTime = moment( $("#craneOffSiteTime").getValue() );
  var oGrid = $("#"+gridId);
  var nRows = oGrid.getNumberRows();
  var msg = '';
 
  for (var i = 1; i <= nRows; i++) {
    var startTime  = oGrid.getValue(i, startTimeCol);
    var finishTime = oGrid.getValue(i, finishTimeCol);

    if (arrivalTime.isAfter(startTime)) {
      msg += "The Start Crane Time in row "+i+" must be after the Crane Arrival Time.\n";
      $("#form\\["+gridId+"\\]\\["+i+"\\]\\["+startTimeId+"_label\\]").css("border-color", "red");
    }
    else {
      //set back to default border color:
      $("#form\\["+gridId+"\\]\\["+i+"\\]\\["+startTimeId+"_label\\]").css("border-color", "");
    }
  
    if (offSiteTime.isBefore(finishTime)) {
      msg += "The Finish Crane Time in row "+i+" must be before the Crane Off Site Time.\n";
      $("#form\\["+gridId+"\\]\\["+i+"\\]\\["+finishTimeId+"_label\\]").css("border-color", "red");
    }
    else {
      //set back to default border color:
      $("#form\\["+gridId+"\\]\\["+i+"\\]\\["+finishTimeId+"_label\\]").css("border-color", "");
    }    
  }  

  if (msg) {
    alert(msg);
    return false;  //return false to stop submit action
  }
  return true;  //all values are good, allow submit action to continue
});

When the form is submitted, JavaScript will check whether the datetimes entered in each row are between the datetimes in the "Crane Arrival Time" and the "Crane Off Site Time" fields. If the datetimes are outside the bounds, then the datetime field will be outlined in red and an alert message will be displayed to the user, saying which fields should be changed. If any of the datetime fields in the grid are out of bounds, then the submit event handler function will return false, which stops the submit action, so the user has a chance to fix the datetimes in the grid and resubmit the form.

To change the border color of a datetime field in a grid, it needs to accessed with its ID "form[grid-id][row-number][field-id_label]", but [ and ] need to be escaped with a double backslash as \\[ and \\] in order to accessed by a jQuery selector. Then, its style property can be changed using the .css() function.

After filling out the form and clicking on the submit button, the JavaScript code will loop through each row and create a message which explains the problems in each row and then display it to the user.

Grids-badDatesInGridAlert.png

Then, the user can correct those bad datetimes in grid and resubmit the form:

Grids-acceptedDatesInGridwhenSubmitted.png