g_form.showFieldMsg() : Field message disappears as soon as its displayed in configurable workspace

Sanjay Nayak
Tera Contributor

Hello All,

I have a requirement for clearing out the value in 'Planned Effort(Hours)' field and show a field message under it if the value entered is less than 'Planned Effort for Current FY' field [Both are floating point number fields].

SanjayNayak_2-1714460795632.png

I have written an onChange client script on 'Planned Effort(Hours)' field in order to do this validation. This client scripts works properly in native UI showing the field message and the message is retained after the value is cleared out.

Client script [UI Type = All, Type = onChange, Field = Planned Effort(Hours)]:

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
    if (isLoading || newValue === '' || g_form.getValue('planned_effort_for_current_fy') === '') {
        return;
    }

    if (parseFloat(g_form.getValue('planned_effort_for_current_fy')) > parseFloat(newValue)) {
        g_form.clearValue('estimated_planned_effort_hours');
        g_form.showFieldMsg('estimated_planned_effort_hours', 'The value should be less than Planned Effort(Hours)', 'error');
    }
}
In a configurable workspace, when I'm entering a value in 'Planned Effort for Current FY' field and adding a smaller value in 'Planned Effort(Hours)' field, this script clears out the value in 'Planned Effort(Hours)' field and displays the field message for a fraction of second and then disappears. I need the field message to be retained as it does in native UI.
Parallel observation:
When I'm trying to display an error message instead of the field message, the same error message appears twice. I have checked and verified that the client script is not duplicated and there is only one script running on change of the field in consideration. In native UI the error message appears only once. 
 
On the same form, the validation on date type field using the same code as above works fine. The date fields are cleared out and field message is retained on the form as expected.
 
Please let me know if anyone has faced this issue only in configurable workspace and how it can be rectified.

 

 

 

4 REPLIES 4

Maddysunil
Kilo Sage

@Sanjay Nayak 

Can you try giving some delay before displaying the field message

 

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
    if (isLoading || newValue === '' || g_form.getValue('planned_effort_for_current_fy') === '') {
        return;
    }

    if (parseFloat(g_form.getValue('planned_effort_for_current_fy')) > parseFloat(newValue)) {
        g_form.clearValue('estimated_planned_effort_hours');
        setTimeout(function() {
            g_form.showFieldMsg('estimated_planned_effort_hours', 'The value should be less than Planned Effort(Hours)', 'error');
        }, 500); // Delay of 500 milliseconds
    }
}

 

  

Please Mark Correct if this solves your query and also mark 👍Helpful if you find my response worthy based on the impact.

 

Thanks

With the delay added, the error message appears twice:

SanjayNayak_0-1714475126957.png

For some unknown reason, the script is executing twice in workspace.

 

@Sanjay Nayak 

Lets try adding additional checks in your client script to ensure that it runs only once.

 

var onChangeExecuted = false; // Variable to track if the onChange function has already been executed

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
    // Check if onChange function has already been executed
    if (onChangeExecuted || isLoading || newValue === '' || g_form.getValue('planned_effort_for_current_fy') === '') {
        return;
    }

    // Set the flag to true to indicate that onChange has been executed
    onChangeExecuted = true;

    if (parseFloat(g_form.getValue('planned_effort_for_current_fy')) > parseFloat(newValue)) {
        g_form.clearValue('estimated_planned_effort_hours');
        g_form.setFieldMsg('estimated_planned_effort_hours', 'The value should be less than Planned Effort(Hours)', 'error', true); // Set the last parameter to 'true' to make the message sticky
    }
}

 

  

Please Mark Correct if this solves your query and also mark 👍Helpful if you find my response worthy based on the impact.

 

Thanks

rmoraski
Tera Contributor

Not sure if you've sorted this, but something like the below should work. We set up a simple flag (that should've been sufficient) as well as a counter (because of ServiceNow's magical reloads). We used the scratchpad (which survives across page loads) to store those 2 variables. We used the javascript console logging messages to determine how many times the page reloaded before it settled down (which gave us 3 and 4).

 

Couple notes: 

  • Omitting the if statement for the showFieldMsg() call will show multiple error boxes (2 in our case) which get erased and replaced with the final one.
  • You might want to remove the counter information appended to the error message from the final product.

 

 

 

 

  function onChange(control, oldValue, newValue, isLoading, isTemplate) {
      if (isLoading || newValue === '') {
          return;
      }

      var limit = 1000; // Parameter for the error message

      // Check for error condition
      if (newValue > limit) {
          console.log('Error condition');

          // Set the flag and counter
          g_scratchpad.error = true;
          g_scratchpad.counter = 1;

          // Clear the bad value
          g_form.setValue('field', 0);
      }

      // Display error message as appropriate
      if (g_scratchpad.error == true) {
          console.log('Error message: ' + g_scratchpad.counter);
          g_scratchpad.counter += 1;

          // Skip the messages that don't persist
          if (g_scratchpad.counter == 4) {
              g_form.showFieldMsg('field', "Error message, counter = " + g_scratchpad.counter, 'error');
          }

          // Reset the flag
          if (g_scratchpad.counter > 3) {
              g_scratchpad.error = false;
          }
      }
  }