I never saw a notification for being tagged in this thread, but I happened upon it nevertheless.
The reason I think that your code isn't working is twofold.
Reason Number 1
Is because using the Form Control's JavaScript named ID variable that you set in a Control's Settings, simply doesn't work well with any Control that is within a Repeating Section. This is in part because an ID in the spec of HTML is considered a unique value. So, while the *first* instance of a control in a Repeating Section will have that ID, every control created when a new row has been added will have its own unique ID because an ID can only ever reference a single element.
Because of this, a form can be considered to have different levels of "Context". Repeating Section Rows are considered their own 'context' from the rest of the form outside of the Repeating Section Control proper. While all of this is typically kept away from you as a form creator, it's important to understand as you do more complex things with Forms.
My suggestion for working with Form Controls (in general, not just for Repeating Sections) is to use the Control's Name instead. Ideally you should be naming your controls with unique and useful names, and you can use those names to target the controls of any particular Context, which is far more useful and typically more correct.
Reason Number 2
While you apply your "On Change" event handler to the target control in a new / existing form that has only one row, it never is applied to any of the controls in the rows that are created after it! In fact it would never be applied to any of the target controls outside of the control in the first row because it is using the ID of only that control.
Instead you must not only target the control in any existing row at the start of the form load, but you must then also use a built in Form Event ("RegisterRepeaterRowAdded") to target the control in any subsequent rows that are generated during use (please see my community post about Nintex Form Events here https://community.nintex.com/t5/Community-blogs/The-Big-Event-A-Closer-Look-At-Nintex-Form-Events/ba-p/79521 to learn more)
Possible Solution
I have worked up the following code without actually opening a form, mainly because you have a lot going on in yours and working up a full on mockup with dummy data would be difficult without a lot more time and information. That said I have tried to be as thorough as I can be with the explanation in how it works using the comments. You should be able to paste this code into the Custom Javascript section of your Form (in settings) and with a few tweaks to things like Control Names, should be able to get it working.
Also, there are several "helper" functions that are included with this that are just parts of a greater body of work that I use for my own forms. While they are not commented as thoroughly, their nature is pretty straight forward. That said, it does add to the general "busy" look of the code, but makes the important code that handles things proper a lot cleaner looking.
That said if you have more questions or issues, let me know and I can work them out given enough info.
The code is as follows:
/* -------------------------------- */
/* -------------------------------- */
/* ==== HELPER FUNCTIONS START ==== */
/* -------------------------------- */
/* -------------------------------- */
/*
This function takes a ControlName (string) and sourceContext,
and returns the value(s) of any controls of matching name.
The returned value's TYPE will change based on how the Control
is setup, but can be forced to be a string if you set the third
argument to true.
*/
var getControlValueByName = function (controlName, sourceContext, getValueAsString) {
if (getValueAsString) {
getValueAsString = "string2";
}
sourceContext = (sourceContext || NWF$(document));
var targetFormControlID = sourceContext.find("[data-controlname='" + controlName + "']").attr("formcontrolid");
NWF.FormFiller.Functions.GetValueContextCache(sourceContext)[targetFormControlID] = undefined;
var rawValue = NWF.FormFiller.Functions.GetValue(targetFormControlID, sourceContext, getValueAsString);
return rawValue;
};
/*
This function takes a controlName (string) and sourceContext,
and returns a jQuery object of any controls matching that name.
The number of controls is limited to whether or not a proper
sourceContext has been passed into the function.
*/
var getControlByName = function (controlName, sourceContext) {
sourceContext = (sourceContext || NWF$(document));
return sourceContext.find("[data-controlname='" + controlName + "']");
};
/*
This function takes a SLT control (jQuery Object), and a
new Value to set the SLT control to.
It will automatically force an update to the control to trigger
any associated Rules to said control, but that behavior can be
toggled by setting the third argument to false.
*/
var setSLT = function (txtControl, newValue, updateControl) {
var innerControl = txtControl.find("input.nf-associated-control, textarea.nf-associated-control");
var currentValue = innerControl.val();
updateControl = updateControl !== false;
if (typeof newValue !== "string" || !newValue) {
return txtControl;
}
if (innerControl.data("OldValue") !== currentValue) {
innerControl.data("OldValue", currentValue);
}
if (updateControl) {
innerControl.val(newValue).trigger("change");
} else {
innerControl.val(newValue);
}
return txtControl;
};
/* -------------------------------- */
/* -------------------------------- */
/* ===== HELPER FUNCTIONS END ===== */
/* -------------------------------- */
/* -------------------------------- */
/*
This is the function that actually does the work of setting up the On Change event
It requires a Repeating Section Row to function.
*/
var setNSNLookupEvent = function(repeaterRow){
/* just making sure the repeaterRow is a jQuery object */
repeaterRow = NWF$(repeaterRow);
/* if we have just 1 row, then continue */
if (repeaterRow.length === 1) {
/* get the control named "llu_ProductionReportTARF1NSN" and handle it's on change event */
getControlByName("llu_ProductionReportTARF1NSN", repeaterRow).on("change", function(){
setTimeout(function() {
/* get the value of the following controls */
var calNomenclatureVal = getControlValueByName("TARF1Nomenclature_CAL", repeaterRow, true);
var calDescVal = getControlValueByName("TARF1USGDesc_CAL", repeaterRow);
var calStonVal = getControlValueByName("TARF1STON_CAL", repeaterRow);
var calPriceVal = getControlValueByName("TARF1Price_CAL", repeaterRow);
var calRoundsVal = getControlValueByName("TARF1Rounds_INT", repeaterRow);
/* if the following control has a value then... */
if (calNomenclatureVal){
/* set the SLT values accordingly */
setSLT(getControlByName("TARF1Nomenclature_TXT", repeaterRow), calNomenclatureVal);
setSLT(getControlByName("TARF1USGDesc_TXT", repeaterRow), calDescVal);
setSLT(getControlByName("TARF1STON_TXT", repeaterRow), calStonVal * calRoundsVal);
setSLT(getControlByName("TARF1DollarValue_CUR", repeaterRow), calPriceVal * calRoundsVal);
}
},2000);
});
}
};
/*
This Form Event will run once all of the controls are ready to rock,
but before the user has control
*/
NWF.FormFiller.Events.RegisterAfterReady(function () {
/* PROVIDE YOUR RS CONTROL'S NAME IN THE CODE BELOW */
var targetRSControl = getControlByName("your_RS_ControlName_HERE");
/*
Because this code needs to work when you load a form
that has already had Rows added to its RS, we grab all
of the visible rows of the RS
*/
/*
NOTE: notice how I have to break up the "not" portion of that selector statement?
that's because Nintex Forms has a runtime function called "not", and it will
attempt to replace the word "not" followed by an open parens with that built in
runtime function. That's not what we want, so I have to keep the open paren
away from the keyword. This is a quirk of working with js directly in the form!
*/
var visibleRows = targetRSControl.find(".nf-repeater-row:not" + "(.nf-repeater-row-hidden)");
/* for every visible (existing) row... */
visibleRows.each(function(index, row){
/* apply the event handler */
setNSNLookupEvent(NWF$(row));
});
});
/*
Last but not least, this is reason number 2 why your code wasn't working.
Every time you add a new row, it gets created without the above event
handler ever knowing it exists because that code has already run!
So, every time there is a new row added, we need to add that event
handler to the target control in the new row.
Every time a new row is added to a form, the code responsible for
created that new row invokes anything you've added to the
RegisterRepeaterRowAdded form event.
So by adding the below function to that registry, it will be invoked
every time you create a new row!
*/
NWF.FormFiller.Events.RegisterRepeaterRowAdded(function (thisRow) {
setNSNLookupEvent(thisRow);
});