cancel
Showing results for 
Search instead for 
Did you mean: 
furstlars
Nintex Newbie

Getting JavaScript to Invoke In Every Repeating Row

Can anyone explain how to get JavaScript to invoke on every repeating row?

 

I've never understood how to get it to work and would like a solution once and for all.

 

Does one need to use the NWF.FormFiller.Events.RegisterRepeaterRowAdded function?

Refer to the data control name rather than the variable ID?

 

The JavaScript logic below is such that if Lease Start Date is not blank and Special Condition equals "Smoke alarms", the due date is automatically set to 28 days after the Lease Start Date.

 

My JavaScript below is only invoked on the first row, but not the rest. If anyone could help amend my script to make this work I would really appreciate it.

 

  • Lease Start Date is outside the repeating section
  • Special Condition and Due Date is inside the repeating section.

 

What should I do?

 

2019-11-29_13-19-13.jpg

 

 

var TriggerControls = [ // Build an array of the controls which, when changed, will evaluate the the conditions below
  NWF$('#' + SpecialCondition),
  NWF$('#' + LeaseStartDate)
  ]

NWF$(TriggerControls).each(function(i) {

NWF$(this).change(function() {

if (NWF$('#' + SpecialCondition).val() == 'Smoke alarms' && NWF$('#' + LeaseStartDate).val() != "") {

var LeaseStartDateVal = NWF$('#' + LeaseStartDate).datepicker('getDate');
var Add28Days = moment(new Date(LeaseStartDateVal)).add(28, 'days').toDate();

NWF$('#' + DueDate).datepicker('setDate', Add28Days);

}

else {

NWF$('#' + DueDate).val('');

}
});
});

 

 

Labels: (1)
0 Kudos
Reply
7 Replies
beckettj
Nintex Newbie

Re: Getting JavaScript to Invoke In Every Repeating Row

Within the RegisterRepeaterRowAdded method, you can get hold of the ID of the HTML element you are after with the following:

 

NWF.FormFiller.Events.RegisterRepeaterRowAdded(function (){

  var field_control_id = NWF$(arguments[0][0]).find(".control_class_name").attr("id");

  // then populate the date control...

}

 

Once you have that ID, you can set it's value. I'm anticipating you're going to have problems because it's a date field - it might be straightforward though (e.g. NWF("#" + field_control_id).val(...) )

 

From memory, fiddling with JavaScript on Repeating sections is a pain in the backside, because of the way Nintex Classic Forms work - they have a hidden row at runtime that is copied to make new rows - so you have to hook any jQuery event driven code onto the "last row" after the add event (if that's what you're doing)...

0 Kudos
Reply
furstlars
Nintex Newbie

Re: Getting JavaScript to Invoke In Every Repeating Row

I think I'm halfway there. The first part of the code definitely works, but not the second part. The DueDate field isn't populating as it should...

 

Help!

 

NWF.FormFiller.Events.RegisterRepeaterRowAdded(function () {

var TriggerControls = [ // Build an array of the controls which, when changed, will evaluate the the conditions below
  currRowSpecialCondition = NWF$(arguments[0][0]).find('.SpecialConditionCSS'),
  NWF$('#' + LeaseStartDate)
  ]

NWF$(TriggerControls).each(function(i) {

NWF$(this).change(function() {

Add28Days(currRowSpecialCondition.find('.SpecialConditionCSS'));

});
});
});
function Add28Days() {

window.setTimeout(1000);

var currRowDueDate = NWF$(arguments[0][0]);

if (currRowDueDate.closest(".nf-filler-control").hasClass('SpecialConditionRS')) {
NWF$(currRowDueDate).find('.DueDateCSS').find('input').val('10/11/12');
}
};
0 Kudos
Reply
furstlars
Nintex Newbie

Re: Getting JavaScript to Invoke In Every Repeating Row

How can I get this function to populate the field in the current row and not the same field in every row?

 

Anyone?

 

function Add28Days() {

var rs = null;
NWF$(document).ready(function() {
rs = NWF$('.SpecialConditionRS');
window.setTimeout(1000);
});

NWF$(rs).find('.DueDateCSS').find('input').val('10/11/12');
}

 

0 Kudos
Reply
Automation Master
Automation Master

Re: Getting JavaScript to Invoke In Every Repeating Row

This post is going to contain a basic answer to your question (with examples / instructions), but I really need some of my own questions answered before something more 'complete' can be crafted.

 

For this brief answer, and anything else I end up talking about, I'll be using a test Example Form that I made which roughly approximates the Form you used in your screenshot / original Question: 

image.png

 

I have placed numbers next to every Form Control showing us that we have 8 Controls total.

 

Each Control (excluding the Save and Submit button & Repeating Section) have been given a Control Name. They are as follows.

 

(2): leaseDate_Label

(3): leaseDate

(5): specialConditions_Label

(6): specialConditions

(7): dueDate_Label

(8): dueDate

-----------------------------

 

Placing the following JavaScript code into the Custom JavaScript portion of your Form Settings should get the controls shown to behave in a way you'd like: 

NWF$("[data-controlname='specialConditions']").on("change", function(e){
  /*  First thing first, let's get the value of the Lease Starting Date Control.
      I named my control "leaseDate", meaning that I can get to the general control
      using the following method */
  var leaseDateControlParent = NWF$("[data-controlname='leaseDate']");

  /*  Because I'm using some built in Nintex Functions I'll need to get some information
      that is really only important to them (the functions in question). Specifically
      I need the 'formcontrolid' attribute's value */
  var leaseDateFormControlID = leaseDateControlParent.attr("formcontrolid");

  /*  We'll get the value of the Lease Date Control using the following */
  var leaseDateControlValue = NWF.FormFiller.Functions.GetValue(leaseDateFormControlID, NWF.FormFiller.Functions.GetParentContext(leaseDateControlParent.find("[formcontrolid][id]")));

  /* If there is no Lease Date then we don't need to continue */
  if (leaseDateControlValue === "") {
    return;
  }

  /*  The event object (e) has a property called 'target' which references
      the control that kicked off the event */
  var conditionControl = NWF$(e.target);

  /*  Because that 'target' control is buried inside of a few different wrapper
      layers, we can get the outermost Control Container using the following
      reference */
  var conditionControlParent = conditionControl.closest(".nf-filler-control");

  /*  We can also get the value of the control that kicked off the event */
  var conditionValue = conditionControl.val();


  /*  Let's test the value against our condition */
  if (conditionValue.toLowerCase() !== "smoke alarms") {

    /*  If the value isn't "smoke alarm", then we stop handling the event */
    return;
  }

  /*  Otherwise... We need to get the Due Date control.
      The easiest way to do that is to just search for the control from the
      perspective of the control we are CURRENTLY handling!
      From the outermost wrapper (conditionControlParent), we'll see if there
      is a nearby control with an attribute name of 'data-controlname' that has
      a value of "dueDate" */
  var dueDateControlParent = conditionControlParent.siblings("[data-controlname='dueDate']");

  /*  If we found that control, then the length of dueDateControlParent should be over 0.
      If it's Lesser Than 1, then we know there is an issue and can stop handling the event */
  if (dueDateControlParent.length < 1) {
    return; 
  }

  /*  If we have made it this far then everything is in place.
      We have a Lease Date
      We know that the Special Conditions is set to "Smoke alarm"
      We know that we have a Due Date control
      All we need to do is to change the value of the Due Date Control so that it's
      28 days later than the Lease Starting Date Control. */

  var updatedDate = NWF.RuntimeFunctions.dateAddDays(leaseDateControlValue, 28);
  var updatedDateString =  NWF.RuntimeFunctions.formatDate(updatedDate, "MM/dd/yyyy"); 
  dueDateControlParent.find("[formcontrolid][id]").val(updatedDateString).trigger("change");
});

Or if you don't want to see the comments, here is the same code but with the comments removed: 

NWF$("[data-controlname='specialConditions']").on("change", function(e){
  
  var leaseDateControlParent = NWF$("[data-controlname='leaseDate']");
  var leaseDateFormControlID = leaseDateControlParent.attr("formcontrolid");
  var leaseDateControlValue = NWF.FormFiller.Functions.GetValue(leaseDateFormControlID, NWF.FormFiller.Functions.GetParentContext(leaseDateControlParent.find("[formcontrolid][id]")));

  if (leaseDateControlValue === "") {
    return;
  }

  var conditionControl = NWF$(e.target);
  var conditionControlParent = conditionControl.closest(".nf-filler-control");
  var conditionValue = conditionControl.val();

  if (conditionValue.toLowerCase() !== "smoke alarms") {
    return;
  }

  var dueDateControlParent = conditionControlParent.siblings("[data-controlname='dueDate']");

  if (dueDateControlParent.length < 1) {
    return; 
  }

  var updatedDate = NWF.RuntimeFunctions.dateAddDays(leaseDateControlValue, 28);
  var updatedDateString =  NWF.RuntimeFunctions.formatDate(updatedDate, "MM/dd/yyyy"); 
  dueDateControlParent.find("[formcontrolid][id]").val(updatedDateString).trigger("change");
});

 

 

Now, again, I'm not considering this a complete answer because there are a few things that require answers from you. Specifically: 

 

  1. What should happen to the Due Date if the Lease Date is updated AFTER it has been set? 
  2. Are you allowed to change the Due Date AFTER it has been set? 
  3. If the Lease Date is set, and at some point the Special Condition was "Smoke Alarms" but was then changed to a different condition, what should happen to the Due Date? 

Answering these should give you a more solid / bulletproof form, and will allow for a different way of solving this problem (using both Validation and Formatting Rules) that is perhaps more foolproof (<- always good). 

 

Later on I'll try to come back in here and answer  your questions regarding how to better target / think about the Controls inside of Repeating Sections because it really isn't an obvious thing if you haven't already done a LOT of digging. 

 

For now though, I hope this gets you on the right track. 

 

 

 

 

 

0 Kudos
Reply
furstlars
Nintex Newbie

Re: Getting JavaScript to Invoke In Every Repeating Row

@MegaJerk thank you for your very comprehensive reply. Really appreciate it. I have done A LOT of digging including some of your own posts, but still can't really figure it out.

 

I have tested your code and it works brilliantly. Would you please expand it to take into account these answers to your questions? Thank you!

 

What should happen to the Due Date if the Lease Date is updated AFTER it has been set?

 

Leave it alone. I will let the business know that it is only set at the first instance and the due date will need to be manually updated if the lease date is subsequently changed. Don't want to over-complicate things here,

 

Are you allowed to change the Due Date AFTER it has been set?

Yes

If the Lease Date is set, and at some point the Special Condition was "Smoke Alarms" but was then changed to a different condition, what should happen to the Due Date?

 

Leave the due date there and let the user change it manually.

One additional question: how does one also invoke this outside "NWF.FormFiller.Events.RegisterRepeaterRowAdded(function () {" ?

Clearly this needs to also operate within the first row which falls outside the NWF RowAdded event. Can we avoid a scenario where there are two similar pieces of code within:

 

1. NWF.FormFiller.Events.RegisterAfterReady(function () {

2. NWF.FormFiller.Events.RegisterRepeaterRowAdded(function () {

0 Kudos
Reply
Automation Master
Automation Master

Re: Getting JavaScript to Invoke In Every Repeating Row

Good to hear that the example worked!

 

I'm not entirely sure how to answer your question, however. 

 


One additional question: how does one also invoke this outside "NWF.FormFiller.Events.RegisterRepeaterRowAdded(function () {" ?

Clearly this needs to also operate within the first row which falls outside the NWF RowAdded event. Can we avoid a scenario where there are two similar pieces of code within:

 

1. NWF.FormFiller.Events.RegisterAfterReady(function () {

2. NWF.FormFiller.Events.RegisterRepeaterRowAdded(function () {


How does one invoke 'what' exactly? My code? It should be executing on every row so long as you either named the controls to names I gave, or changed my code to reference the names of your own controls. 

 

In the below image, you'll see all of the the rows I have created are set to the same date using only the code I have posted as an example above. If this is not happening in your own test, then there might be something else amiss. 

image.png

 

I am not using either the RegisterAfterReady or RegisterRepeaterRowAdded Nintex Events in my code because I'm handling the browser's 'on change' event in such a way that it'll do work on any of the specified controls, which in this case is any control with a Control Name of "specialConditions"

NWF$("[data-controlname='specialConditions']").on("change", function(e){
    //....
});

 

 

It's important to make a distinction here between what I'll call 'Browser' events (though really technically 'DOM' events: https://developer.mozilla.org/en-US/docs/Web/Events), and the exposed Nintex Events (anything that starts with "NWF.FormFiller.Events..."). While Nintex Events are indeed an important part of the overall puzzle that is Forms, it's best to think of them as a way for the Form to express its state to us (the developer). In otherwords, unlike DOM Events, which are are far more generic and concerned (mostly) with the actions happening at any given moment within the confines of the Web Browser or Web Page, Nintex Events inform us to a VERY specific set of states that the Form may find itself in, and opens a window for us (the Developer) to do *some* work to that form preemptively or in preparation for something else. 

 

So it's best to not think of Nintex Events as a means to 'Attach' JavaScript to a Forms Control, but more-so as a means to *Invoke* JavaScript when the Form has reached a particular state. 

 

Again, this isn't as in depth as an answer as I'd like, but hopefully provides a little bit more context / insight into how these different systems can be used to accomplish your goals. 

 

Now that I have a few more answers in regard to how you'd like to do things, I'll be able to produce a Rule Based solution that can open the doors to Validating your control and clearing its value in the event that something changes in a way that requires it. 

 

Cheers! 

0 Kudos
Reply
furstlars
Nintex Newbie

Re: Getting JavaScript to Invoke In Every Repeating Row

@MegaJerk got it, the code now works nicely on all rows without the RegisterRepeaterRowAdded function!

0 Kudos
Reply