Refresh gridadd grid after editing data in Form_CustomValidate (v2024)

In (client) Form_CustomValidate() I edit certain fields of a grid based on the rest of the grid. Works perfectly but I want the user to confirm that the data is acceptable before finally committing the form.

I've got the edits working perfectly and a confirm dialog also working perfectly but I can't get the screen to refresh after edits, before the confirm dialog so the user can confirm or abort while seeing the final grid with my proposed changes.

Small note that I will add (might be an extra step) some fields are lookups.

How can I achieve what I want?

Since you use client side JavaScript, you should update the grid with new values by JavaScript script yourself, don't try to "refresh the screen" by reloading, that will defeat the purpose of client side validation.

Yes, I did update the grid with the new values as such:

$("#x" + rownum + "_Date").val($("2026-12-31"));

This worked perfectly (it did update the grid as verified in the server) but it didn't update the display as my confirm() line at the end of my Form_CustomValidate was executed but at that time, the display had the old value.

Is there another value I should update for display purposes?

You better post your complete code for discussion.

Here is a very stripped down version of Form_CustomValidate. The point of the code is that on a gridadd, if certain fields are left blank, I copy the value in the row above. This means the data entry clerk doesn't have to keep entering certain fields that don't change for many rows (e.g. 10 rows all with the same date).

All I'm looking for is to repaint the page before the confirm so the user can see the autofill.

function (fobj) { // DO NOT CHANGE THIS LINE! (except for adding "async" keyword)!

// Get row information
var rowcnt = fobj.elements["key_count"] ? fobj.elements["key_count"].value : 1;
var rowindex = $(fobj).attr("data-rowindex");

// ignore if not a grid or if not first row
if (rowcnt == 1 || rowindex != 1)
  return true;

// default to not dirty
let dirty = false;

//loop through all rows
for (rownum = 1; rownum <= rowcnt; rownum++)
{

  // if Date is "", carry forward
  if (!$("#x" + rownum + "_Date").val())
  {
    $("#x" + rownum + "_Date").val($("#x" + (rownum - 1) + "_Date").val());
    dirty = true;
  }

}

// if dirty, ask for confirmation
if (dirty)
  return confirm("Some data was autofilled.  Continue submitting?");
}


Any suggestions welcome!

Hmm. Made some headway.

I changed the confirm to an alert and changed the text slightly ("Please review and resubmit"). This completed most of my Form_CustomValidate and gave the browser a chance to repaint.

The lookup fields, however, didn't update. How do I force it to update lookup fields. I suppose this means an ajax call but I don't know how to trigger it. Also, I'm not sure when to trigger it (before the confirm?).

Thanks to Arbei and a little trial and error on my part, I almost there!

Try: let rownum = 1

Yes, I missed that when stripping my code for this post. The "let" is in my code, though.

Having said that, SUCCESS! I have figured out what was going wrong with the lookups (implemented in phpmaker 2024 by corejavascript/typeahead.js) that was stumping me. The problem is that to change the value (query) of a typeahead you are supposed to use .typeahead('val', value) on the input element (id="sv_x_). This does NOT change the displayed value!!!! To change the displayed value you must use .val(value) on the element (id="x_) which is totally frowned upon by all 10,000 posts I read about typeahead (in fairness, frowned upon by those using it instead of .typeahead('val', value) not in addition to!). NOTE: one of the two should be the link text (a single field of the lookup) and the other should be the display text (could be more than one field of the lookup with commas separating).

My code for the for loop and verification then results in:

for (rownum = 1; rownum <= rowcnt; rownum++)
{

  // if Date is "", carry forward (simple field)
  if (!$("#x" + rownum + "_Date").val())
  {
    $("#x" + rownum + "_Date").val($("#x" + (rownum - 1) + "_Date").val());
    dirty = true;
  }

  // if _Username is "", carry forward (lookup field)
  if (!$("#x" + rownum + "__Username").val()) 
  {
    const newvallong = $("#sv_x" + (rownum - 1) + "__Username").val();
    const newvalshort = newvallong.split(",")[0];
    let $inputElement = $("#sv_x" + rownum + "__Username");
    $inputElement.typeahead("val", newvallong);
    let $inputElement2 = $("#x" + rownum + "__Username");
    $inputElement2.val(newvalshort);
    dirty = true;
  }
}

// if dirty, ask for confirmation
if (dirty)
{
  alert("Some data was autofilled.  Please check all data and resubmit");
  return false;
}

// if it gets here, there was no data altered, so simply submit
return true;
}

Tested successfully! Hope it helps someone else.