cancel
Showing results for 
Search instead for 
Did you mean: 

Using Javascript to update a repeating section

paul_crawford
Nintex Newbie
15 23 9,872

Following on from this question Need to Copy a repeating section from a List-item to a repeating section to a different List-item?‌ raised by Pam Lewis‌ i thought i would blog my solution in case there were others with the same requirement.

Requirement:

ListA - Title column and repeating section.

ListB - Title column, lookup column and repeating section.

Create an item in ListA, update a repeating section with info as required. Save.

Create an item in ListB, from a lookup control, select the relevant item from ListA and the repeating section on ListB will be populated from the repeating section data from ListA.

Form from ListA:

The repeating section control is connected to a plain text multiline of text column.

The first text control in the repeating section has a name of dwgDimension.

The second text control in the repeating section has a name of ddOperation.

Form from ListB

The repeating section control is connected to a plain text multiline of text column with a name of rsdata and css class of rsdata.

The first text control in the repeating section has a name of dwgDimension.

The second text control int the repeating section has a name of ddOperation.

Under the Advanced section of the list lookup control set the Store Client ID in JavaScript variable to yes and add a variable name of varDropDown

Go to form settings and under Custom JavaScript add the following code:

NWF.FormFiller.Events.RegisterAfterReady(function () {
NWF$(document).ready(function () {
NWF$("#" + varDropdown).change(function () {
//clear repeating section
ClearRSData();
//get repeating section data
GetRSDataFromLookup();
});
});
});

function ClearRSData() {
//get the repeating section
var rsdata = NWF$('.rsdata');
//count number of fields to give number of rows
var labels = NWF$(rsdata).find('.dwgDimension');
//iterate through rows
NWF$.each(labels, function (index) {
//delete the last row
NWF$('.rsdata .nf-repeater-row:last').find('.nf-repeater-deleterow-image').click();
});
//for last row as index 0 row cannot be deleted
NWF$('.rsdata .nf-repeater-row:last').each(function () {
//get the row
var $row = NWF$(this);
//clear the field value
$row.find('.dwgDimension input').val('');
//clear the field value
$row.find('.ddOperation input').val('');
});
}

function GetRSDataFromLookup() {
//get the lookup value
var lookupId = NWF.RuntimeFunctions.parseLookup(NWF$('#' + varDropdown).val(), true);
//if lookup value is not null
if (lookupId != '') {
//clear jQuery error messages
NWF$('#errorMsg').empty();
//set the lookup list url to get repeating section xml data
var requestUri = _spPageContextInfo.webAbsoluteUrl + '/_api/Web/Lists/getByTitle(\'ListA\')/items?$filter=Title eq \'' + lookupId + '\'';
try {
NWF$.ajax({
url: requestUri,
type: 'GET',
headers: { 'ACCEPT': 'application/json;odata=verbose' },
success: GetRSDataFromLookupSuccess,
error: GetRSDataFromLookupError
});
}
catch (err) {
//set error message
NWF$('#errorMsg').html('getListData Error: ' + err);
}
}

}

function GetRSDataFromLookupSuccess(data) {
//check the result set is not empty
if (data.d.results.length > 0) {
//get the xml data from the result
var rsdata = data.d.results[0].rsdata;
//intiate xml parser
parser = new DOMParser();
// populate the parser with the xml data
xmlDoc = parser.parseFromString(rsdata, 'text/xml');
//get the item tag from the xml
var items = xmlDoc.getElementsByTagName('Item');
//foreach item in the xml
for (var i = 0; i < items.length; i++) {
//get the repeating section last row
NWF$('.rsdata .nf-repeater-row:last').each(function () {
var $row = NWF$(this);
//set the field value
$row.find('.dwgDimension input').val(xmlDoc.getElementsByTagName('dwgDimension')[i].childNodes[0].nodeValue);
//set the field value
$row.find('.ddOperation input').val(xmlDoc.getElementsByTagName('ddOperation')[i].childNodes[0].nodeValue);
});
//add new row
NWF$('.rsdata').find('a').click();
}
//delete extra unnecessary row
NWF$('.rsdata .nf-repeater-row:last').find('.nf-repeater-deleterow-image').click();
}
} function GetRSDataFromLookupError() {
alert('Failed to load Lookup Items');
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Fistly we register the function to the change event of the lookup field.

Then we clear any data from the repeating section (allows for changes in the lookup value)

Then we populate from the repeating section of the first List

Save and publish both forms.

Item 1 from ListA

Item 2 From ListA

New item from ListB

Change lookup value

Now you have a dynamically updating repeating section depending on the item selected in the lookup

Any questions, let me know.

Paul

nintex forms ;‌ repeating sections‌ javascript‌ custom javascript‌

23 Comments
kholleback
Nintex Newbie

Paul,

Thank you for your post!  I have a similar scenario that I'm hoping you could shed some light on.  List B associates more than one (multi-value) lookup item from List A.  On the List B form, when a list item is added to the selected Contacts (in my example) I'd like the repeating section to perform the lookup either on List A or the associated lookup column in List B.  

List A (Contacts) includes text columns with contact details

List B includes a multi-value lookup on Contacts, so one record in List B is associated with multiple contacts. 

 

Given your Javascript above, this scenario seems similar.  How to you parse the mutli-values that are moved to the box on the right?

Thanks in advance!

Katie

pam_lewis
Nintex Newbie

thank you Paul... works like a charm!! fantastically awesome...

frederickrivers
Nintex Newbie

Pam,

I was unsuccessful at getting the example to work. Would you be willing to share the files?

pam_lewis
Nintex Newbie

Hi.. Paul --  how could I use this process - dynamic repeating section - in multiple repeating sections on a ListB/Item form? I have a form with 2 repeating sections (right now max = 8 sections); using a drop down lookup selection from the ListA/Item, choosing a different item for each repeating section.  Can this be done within the JS ? 

pam_lewis
Nintex Newbie

Hi Fred,  following Paul's steps works, just be sure to change the file/link values in his code to yours and the column names need to match your names. 

paul_crawford
Nintex Newbie

Hi Pam Lewis

If I'm not wrong it is very similar to your first requirement?

If so then you would replicate the script to have 2 complete versions of it within the same form. You would just need to make sure that the controls and panels etc were named differently and the functions were named differently

eg:

NWF.FormFiller.Events.RegisterAfterReady(function () {
NWF$(document).ready(function () {
NWF$("#" + varDropdown1stLookup).change(function () {
//clear repeating section1
ClearRSData1stRepeatingSection();
//get repeating section data
GetRSDataFromLookup1stRepeatingSection();
 });

NWF$("#" + varDropdown2ndLookup).change(function () {//clear repeating section2
ClearRSData2ndRepeatingSection();
//get repeating section data
GetRSDataFromLookup2ndRepeatingSection();

 });
});

function ClearRSData1stRepeatingSection() {
//get the repeating section
var rsdata1 = NWF$('.rsdata1stRepeatingSection');
//count number of fields to give number of rows
var labels = NWF$(rsdata1).find('.dwgDimension1stRepeatingSection');

...................

function ClearRSData2ndRepeatingSection() {
//get the repeating section
var rsdata2 = NWF$('.rsdata2ndRepeatingSection');
//count number of fields to give number of rows
var labels = NWF$(rsdata2).find('.dwgDimension2ndRepeatingSection');

...................

etc etc etc.

Hope this helps

Let me know if you have any problems

pam_lewis
Nintex Newbie

thankyou... I thought it had to be something like that.. I'm going attempt to put 'if-elseif'.. around them based on column values not equal to blanks..  around them... I'm at 'intro' level to JS!  

paul_crawford
Nintex Newbie

Hahaha, we all started at the beginning!!!!

pam_lewis
Nintex Newbie

Hi Paul,

ok.. I tried the code addition above (outcome -> no good or nothing) and decided since the 2nd repeating section will read/pull from the same List as the 1st repeating section, there is a possible naming problem.  Maybe due to the column names need to be the same on both lists for the repeating section to populate.  Is there a way to connect List A (lookup/reading from) to the 2nd or 3rd, etc. repeating sections on List B (copied to) same field/column names? 

rubi
Nintex Newbie

Hi Paul, 

thanks for that post - great work!

Only thing is not working for me is to delete the values of the last row. 

NWF$('.XMLSpecifications .nf-repeater-row:last').each(function () {
//get the row
var $row = NWF$(this);
//clear the field value
$row.find('.classMaterial').val('');
$row.find('.classUnit').val('');
$row.find('.classQuantity').val('');
});

Should that also work on lookup fields? 

BR, Rubi

flocke
Nintex Newbie

Hi!

Do you mean that you have an empty section at the end?

Best,

Florian

jpmhuls
Nintex Newbie

This indeed happens to me if there is more than 1 row; for 1 row it works properly. Even worse, not only are all rows gone, the controls below the repeating section get messed up as well.

I've put an alert in the $NWF$.each of the ClearRSData() and for an empty rs it gives 2 alerts (index=0 and index=1); there's a hidden row that seems to be included and I'm wondering if the code in this post takes this into account?

NB: I'm using this functionality to copy metadata from another item (query in js using various filters) after selecting it and pressing a Copy Metadata button.

flocke
Nintex Newbie

Hi,

NWF$('.repStores .nf-repeater-row:last').find('.nf-repeater-deleterow-image').click();

 

I think thisone would help you to delete the last empty row.

let me know if this helps you.

Regards

jpmhuls
Nintex Newbie

Thank you Florian,

My scenario would be a bit like this:

  1. user creates a new item
  2. user fills 3 rows with data in the repeating section
  3. then the user has a change of heart and on the Copy Metadata panel set several filters, selects one exiting item from the filtered dropdown list and presses the Copy Metadata  It is here that I need to clear 2 repeating sections and (not yet implemented) populate them again with existing data from the selected item.

The current reset of the repeating section, using the click() event, deletes all rows.....

It feels to me as if the repeating section in Nintex 2013 Forms v2.11.2.2 works slightly different.........

EDIT: the last row does not need to be deleted, only the values emptied as intended in the code in this post.

EDIT 2: reason why the code is misbehaving in my case is because the panel containing the repeating section is hidden..... So I'll have to temp show it, update it and hide it again.

EDIT 3: temporarily showing the panels did indeed resolve my issue.

sonam29
Nintex Newbie

Hi,

I have similar requirement but I just want one field from repeating sectionA(Form a) to be update in repeating sectionB(form b), and this 2nd repeating section has some other fields which need not be update, those will be entered by user.

Can somebody will give some insight how should i update this?

BR/Sonam 

yashwanth_manda
Nintex Newbie

Hi Paul,

I tried your script and i am unable to run it. When i execute the code, it goes directly into error header. Can you help me out.

jpmhuls
Nintex Newbie

Did anyone figure out how to set the value of a list lookup field in a repeating section? I'm getting as far as setting it based on the item's ID, but on saving the form the validation rules still reports that these lookups are missing a value. The JS snippet I'm currently using is:

$currRow.find("." + currFieldLabel + " select.nf-client-control").val(currFieldValue);

Considering the fact that outside a repeating section one also has to set the Selected attribute, I would guess this is also required within the repeating section. Whatever I try, it does not seem I've found the proper command setup.

NB: I'm copying from another item using a (JS) query which only returns a list lookup ID value (and thus not also the display value). Using the following snippet did not work for me to set the selected value of my list lookup in the repeating section:

var tmpDispVal = NWF.RuntimeFunctions.SPLookup("Currencies","ID",currFieldValue,"Currency").done(function(data) {

    $currRow.find("." + currFieldLabel + " option:contains(" + data +")").attr("selected", true);

});

Also, SPLookup seems to be async..... So any info on a sync version of calling the inline function lookup() from JavaScript would also be welcome.

ms
Nintex Newbie

Hi Paul Crawford, thanks for this wonderful solution. I really like the clean code.

Not sure if you're still monitoring this but I have one question.

In my solution I'm using a list lookup control in the repeating section. This is setup on both lists so that they marry up. They work perfectly in populating the repeating section, however when I save the item the values aren't committed to the multi-line text field XML. All other values are visible in the XML except for the lookup values.

I need a way to commit the value to the lookup field after the jQuery has populated it. I've tried applying ProcessOnChange after setting the lookup field but this doesn't have any effect:

NWF.FormFiller.Functions.ProcessOnChange(NWF$(.ItemType));

Any advice would be appreciated.

ms
Nintex Newbie

I found the solution here: https://community.nintex.com/thread/12582#comment-46255 

I just needed to add a change event after updating the lookup field:

for (var i = 0; i < items.length; i++) {
//get the repeating section last row
NWF$('.ItemsClass .nf-repeater-row:last').each(function() {
var $row = NWF$(this);
//set the field values
$row.find('.ItemType select').val(xmlDoc.getElementsByTagName('.ItemType')[i].childNodes[0].nodeValue);
$row.find('.ItemType select').change();
});
//add new row
NWF$('.Items').find('a').click();
}‍‍‍‍‍‍‍‍‍‍‍
paul_crawford
Nintex Newbie

Send me your form and I can have a look

Paul

Get Outlook for iOS<https://aka.ms/o0ukef>

ms
Nintex Newbie

Thanks Paul, i found the solution shortly after asking the question  

I needed to add a change event after updating the lookup field. I posted the code in the response above.

Appreciate you coming back to me  

rak723
Nintex Newbie

Hi Paul

When i tried to use the ClearData() function it removes all the row in repeating section.

paulinho
Nintex Newbie

Hi Paul

 

Thank you very much for your instructions. I was able to successfully adapt them to my Nintex Forms form for an external list on SharePoint Server 2016.

Unfortunately, I was not yet able to fulfill all the needs with your instructions. Do I get it correctly that on your print screens below their title "Item 1 from ListA" and "Item 2 from ListA" are from the form in display mode? If so, how did you get this working? I mean, in display mode there is obviously no button that the JavaScript code can click to add a new repeating section row. However, I would like to fill the repeating section in display mode also with the results of a REST API request.

 

I thank you or someone else's help in advance.

 

Best regards

Paul