Add / Update Checkbox field using PnP

Good Afternoon,

We have a button on a form that creates a new version of the item and we are utilising PnP to perform this and I am struggling to get the correct syntax to get the value from a Multiple Select / Checkbox field on the form and then create a new item utilising the data. My code is below: -

The internal name of the multiple select field is - Contract_x0020_Systems

// Function to Raise Renewal for the Contract
function raiseRenewalContract () {
	if (confirm('Are you sure you wish to raise a Renewal for this Contract?')) {
		doNotRedirect = true;
		//fd.save();
		var refParts = fd.field('Title').value.split('-');
		var newVersion = parseFloat(refParts[2]) + 1;
		var newReference = refParts[0] + '-' + refParts[1] + '-' + newVersion;
		var correspondenceCompanyNameId = fd.field('Correspondence_x0020_Company_x00').value.LookupId;
		var correspondenceAddressNameId = fd.field('Correspondence_x0020_Address_x00').value.LookupId;
		var correspondenceContactNameId = fd.field('Correspondence_x0020_Contact_x00').value.LookupId;
		var siteCompanyNameId = fd.field('Company_x0020_Name').value.LookupId;
		var siteAddressNameId = fd.field('Address_x0020_Name').value.LookupId;
		var siteContactNameId = fd.field('Contact_x0020_Name').value.LookupId;
		var wrsCompanyId = fd.field('WRS_x0020_Company').value.LookupId;
		var wrsCompanyName = fd.field('WRS_x0020_Company').value.LookupValue;
		var responsibility = retrieveResponisibilityPersonOrGroupFieldByFilter(correspondenceCompanyNameId,wrsCompanyName);
		var customerAccountManagerId = responsibility.UserId;
		var dateRaised = new Date();
		var quotedContractLength = parseFloat(fd.field('Quoted_x0020_Contract_x0020_Leng').value);
		var parts = fd.field('Renewal_x0020_Due_x0020_Date').value.split('/');
		var string = parts[1] + '/' + parts[0] + '/' + parts[2];
		var proposedStartDate = new Date(string);
		var renewalDate = new Date(string);
		renewalDate.setMonth(renewalDate.getMonth() + quotedContractLength);
		var endDate = new Date(string);
		endDate.setMonth(endDate.getMonth() + quotedContractLength);
		endDate.setDate(endDate.getDate() - 1);
		debugger;
		var contractOption = fd.field('Contract_x0020_Option').value;
		var contractSystems = fd.field('Contract_x0020_Systems').value;
        var cctvDetails = fd.field('CCTV_x0020__x002d__x0020_Detail').value;
		var list = pnp.sp.web.lists.getByTitle("Solutions%20Maintenance%20Contracts");
		list.items.add({
			Title: newReference,
			Correspondence_x0020_Company_x00Id: correspondenceCompanyNameId,
			Correspondence_x0020_Address_x00Id: correspondenceAddressNameId,
			Correspondence_x0020_Contact_x00Id: correspondenceContactNameId,
			Company_x0020_NameId: siteCompanyNameId,
			Address_x0020_NameId: siteAddressNameId,
			Contact_x0020_NameId: siteContactNameId,
			WRS_x0020_CompanyId: wrsCompanyId,
			Customer_x0020_Account_x0020_ManId: customerAccountManagerId,
			Date_x0020_Raised: dateRaised,
			Contract_x0020_Issue_x0020_Type: 'Renewal',
			Quoted_x0020_Contract_x0020_Leng: quotedContractLength,
			Contract_x0020_Start_x0020_Date: proposedStartDate,
			Contract_x0020_End_x0020_Date: endDate,
			Renewal_x0020_Due_x0020_Date: renewalDate,
			Forecast_x0020_Date: proposedStartDate,
			Forecast_x0020_Probability: '3 - Ongoing',
			Contract_x0020_Option: contractOption,
			Contract_x0020_Systems: contractSystems,
			CCTV_x0020__x002d__x0020_Detail: cctvDetails
		}).then(function(){
		    console.log("Created!");
		});
	}
}

Thanks

Hello @Tony_Duke,

The trick is to set the value in the new item. The syntax should be as following.

ChoiceField: {
      results: [ 'Choice #2', 'Choice #3' ]
    }

So your code will be as below.

// Function to Raise Renewal for the Contract
function raiseRenewalContract () {
	if (confirm('Are you sure you wish to raise a Renewal for this Contract?')) {
		doNotRedirect = true;
		//fd.save();
		var refParts = fd.field('Title').value.split('-');
		var newVersion = parseFloat(refParts[2]) + 1;
		var newReference = refParts[0] + '-' + refParts[1] + '-' + newVersion;
		var correspondenceCompanyNameId = fd.field('Correspondence_x0020_Company_x00').value.LookupId;
		var correspondenceAddressNameId = fd.field('Correspondence_x0020_Address_x00').value.LookupId;
		var correspondenceContactNameId = fd.field('Correspondence_x0020_Contact_x00').value.LookupId;
		var siteCompanyNameId = fd.field('Company_x0020_Name').value.LookupId;
		var siteAddressNameId = fd.field('Address_x0020_Name').value.LookupId;
		var siteContactNameId = fd.field('Contact_x0020_Name').value.LookupId;
		var wrsCompanyId = fd.field('WRS_x0020_Company').value.LookupId;
		var wrsCompanyName = fd.field('WRS_x0020_Company').value.LookupValue;
		var responsibility = retrieveResponisibilityPersonOrGroupFieldByFilter(correspondenceCompanyNameId,wrsCompanyName);
		var customerAccountManagerId = responsibility.UserId;
		var dateRaised = new Date();
		var quotedContractLength = parseFloat(fd.field('Quoted_x0020_Contract_x0020_Leng').value);
		var parts = fd.field('Renewal_x0020_Due_x0020_Date').value.split('/');
		var string = parts[1] + '/' + parts[0] + '/' + parts[2];
		var proposedStartDate = new Date(string);
		var renewalDate = new Date(string);
		renewalDate.setMonth(renewalDate.getMonth() + quotedContractLength);
		var endDate = new Date(string);
		endDate.setMonth(endDate.getMonth() + quotedContractLength);
		endDate.setDate(endDate.getDate() - 1);
		debugger;
		var contractOption = fd.field('Contract_x0020_Option').value;
		var contractSystems = fd.field('Contract_x0020_Systems').value;
        var cctvDetails = fd.field('CCTV_x0020__x002d__x0020_Detail').value;
		var list = pnp.sp.web.lists.getByTitle("Solutions%20Maintenance%20Contracts");
		list.items.add({
			Title: newReference,
			Correspondence_x0020_Company_x00Id: correspondenceCompanyNameId,
			Correspondence_x0020_Address_x00Id: correspondenceAddressNameId,
			Correspondence_x0020_Contact_x00Id: correspondenceContactNameId,
			Company_x0020_NameId: siteCompanyNameId,
			Address_x0020_NameId: siteAddressNameId,
			Contact_x0020_NameId: siteContactNameId,
			WRS_x0020_CompanyId: wrsCompanyId,
			Customer_x0020_Account_x0020_ManId: customerAccountManagerId,
			Date_x0020_Raised: dateRaised,
			Contract_x0020_Issue_x0020_Type: 'Renewal',
			Quoted_x0020_Contract_x0020_Leng: quotedContractLength,
			Contract_x0020_Start_x0020_Date: proposedStartDate,
			Contract_x0020_End_x0020_Date: endDate,
			Renewal_x0020_Due_x0020_Date: renewalDate,
			Forecast_x0020_Date: proposedStartDate,
			Forecast_x0020_Probability: '3 - Ongoing',
			Contract_x0020_Option: contractOption,
			Contract_x0020_Systems:{
			     results: contractSystems			
			},
			CCTV_x0020__x002d__x0020_Detail: cctvDetails
		}).then(function(){
		    console.log("Created!");
		});
	}
}

Thank you Margarita that work perfectly.

1 Like

I am essentially trying to do the same thing... but it's not working. Since I need to use the ID created by the parent form (this is a creation form) do I need to build in a pause so it has time to save? I looked in the console and it does not report any errors.

Thanks as always for your help!!

fd.spSaved(function (result) {var ContractorNumber = fd.field('Contractor_x0020_Number');
var LastName = fd.field('Last_x0020_Name').value;
var FirstName = fd.field('First_x0020_Name:').value;
var PhoneNumber = fd.field('Phone_x0020_Number').value;
var EmailAddress = fd.field('Email_x0020_Address').value;
var AddressOne = fd.field('Address_x0020_Line_x0020_1').value;
var Address2 = fd.field('Address_x0020_Line_x0020_2').value;
var City = fd.field('City').value;
var State = fd.field('State').value;
var ZipCode = fd.field('ZipCode');
var LicenseNumber = fd.field('License_x0020_Number').value;
var LicenseState = fd.field('License_x0020_State').value;
var DateOfBirth = fd.field('Date_x0020_of_x0020_Birth').value;

	var list = pnp.sp.web.lists.getByTitle("Drivers");
	list.items.add({
		ContractorID: ContractorNumber,
		Last_x0020_Name: LastName,
		First_x0020_Name: FirstName,
		Phone_x0020_Number: PhoneNumber,
		Email_x0020_Address: EmailAddress,
		Address_x0020_Line_x0020_1: AddressOne,
		Address_x0020_Line_x0020_2: AddressTwo,
		City: City,
		State: State,
		Zip_x0020_Code: ZipCode,
		License_x0020_Number: LicenseNumber,
		License_x0020_State: LicenseState,
		Date_x0020_of_x0020_Birth: DateOfBirth })
});

Hi djbeaudin,

I could be wrong here but I think the only values you can access in the saved handler is the ID of the item you just created, so you'd need to do something like this:

sp.web.lists.getByTitle().items.getById(result.ID).get().then(function(item){

   var list = pnp.sp.web.lists.getByTitle("Drivers");
   list.items.add({ 
           City: item.City
           // etc....
   });

});

Hope that makes sense, you essentially need to get the item you just created, and use the item.value of each field to set the values in the new item in the Drivers list.

Not sure if my syntax is the best there, I think maybe you can do it by chaining .then, my syntax nests the second call inside the first. Works for me but maybe not the best pattern to use.

Kind regards
Andy

1 Like

That makes sense. I will give it a try.

Forgot to indicate, you obviously need the name of the current list in the GetByTitle. Whoops.

I got it to work (mostly) but the list I am adding to has a lookup on it. I am passing the ID for the lookup, but it's not accepting it... any help is appreciated... Is there something different I should be doing with the lookup? This code is fired by a button...

this is the code:

var firstName = fd.field('First_x0020_Name').value;
var lastName = fd.field('Last_x0020_Name').value;
var email = fd.field('Email_x0020_Address').value;
var id = fd.field('ID').value;
var list = pnp.sp.web.lists.getByTitle("Drivers");
list.items.add({First_x0020_Name: firstName,
Last_x0020_Name: lastName,
Email_x0020_Address: email,
ContractorID: id
});
fd.control('SPDataTable1').refresh();

If the name of the Lookup field is 'ContractorID', then in a PnP call to update the field you should append an 'Id' on the end.

So the field would be called 'ContractorIDId' - if you pass that field an integer value it should update.

Regards,
Andy

1 Like

That was it!!! Thank you so much. It works perfectly!

Hi @mnikitina/@abolam/@djbeaudin/@Tony_Duke.

Trying to update the date fields of multiple selected list items but am having difficulty doing so as it only updates one of the selected list items only and not the rest. Possibly due to the asynchronous nature of pnp requests? Any suggestions on how to fix?

var date1 = new Date();
var date2 = new Date();
// ADD UPDATEDATES BUTTON TO ADD ONE YEAR TO DATE FIELDS FOR SELECTED LIST ITEMS
var UpdateButton = {
text: 'Roll Forward Year',
class: 'btn-secondary',
visible: false,
icon: 'FastForward',
iconType: 0,
click: function() {
//get array of itemIDs of all the selected items
var itemIDs = fd.control('SPDataTable1').selectedItems;
var list = pnp.sp.web.lists.getByTitle("SPDataTable1");

	// loop through each of the selected items to update the date fields by adding a year to them
	for (var i=0; i<= itemIDs.length; i++) {
		console.log("update selecteditemIDs: " + itemIDs[i]);
		
		//retrieve all information about selected item
		list.items.getById(itemIDs[i]).get().then(function(item){
			//create update object
			var updateObj = {};
			//update DueDate and EndDate date fields in current "updateObj"
			var d = new Date(item.DueDate);
			var d_year = d.getFullYear();
			var d_month = d.getMonth();
			var d_day = d.getDate();
			var d_hours = d.getHours()
			var d_minutes = d.getMinutes();
			var e = new Date(item.EndDate);
			var e_year = e.getFullYear();
			var e_month = e.getMonth();
			var e_day = e.getDate();
			var e_hours = e.getHours()
			var e_minutes = e.getMinutes();
			updateObj.DueDate = new Date(d_year + 1, d_month, d_day, d_hours, d_minutes).toISOString();
			updateObj.EndDate = new Date(e_year + 1, e_month, e_day, e_hours, e_minutes).toISOString();
			date1 = updateObj.DueDate;
			date2 = updateObj.EndDate;
			
			console.log("date1 DueDate: " + date1);
			console.log("date2 EndDate: " + date2);
			list.items.getById(itemIDs[i]).update(updateObj);
			fd.control('SPDataTable1').refresh();
			UpdateButton.visible = false;
		});
	}
}

}

Error in console: Uncaught (in promise) Error: Error making HttpClient request in queryable [409] ::> {"odata.error":{"code":"-2130575305, Microsoft.SharePoint.SPException","message":{"lang":"en-US","value":"Save Conflict.\n\nYour changes conflict with those made concurrently by another user. If you want your changes to be applied, click Back in your Web browser, refresh the page, and resubmit your changes."}}}

Thanks,
stormanh

Hello @stormanh,

You can use Moment.js library to add time to date. Add this code to JavaScript editor:

requirejs.config({
    paths: {
        moment: "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min"
    }
});

fd.spRendered(function() {
//your code is here

And add something like this code to the new button click function to update selected items:

require(['moment'], function(moment) {
     var itemIDs = fd.control('SPDataTable1').selectedItems.map(function(item){ return item.ID} );
     var list = pnp.sp.web.lists.getByTitle("ListName");
     
     itemIDs.forEach(function(itemID, index){
            list.items.getById(itemID).get().then(function(item){
            date = moment(item.Date);
            newDate = date.add(1, 'years').format();
            return newDate;
    }).then(function(newDate){
        list.items.getById(itemID).update({
            Date: newDate
        })
    });
 })

setTimeout(function(){ fd.control('SPDataTable1').refresh(); }, 3000);

});

Hi @mnikitina.

I get the following error in the console with the sample code provided: [SharePoint Forms] Error in custom JS:SyntaxError: missing ) after argument list

Thanks,
stormanh

Hello @stormanh,

Are you getting the error on form load or on button click?

Please share the code that you are using in JavaScript Editor.

Hi @mnikitina.

Yes, the error occurs on form load. Below is the code:

// Define fd globally in this parent form
window.fd = fd;

// Make pnp-js available in browser's console
window.pnp = pnp;

// Make jQuery available in browser's console
window.$ = $;

// Get external JS
requirejs.config({
    paths: {
        moment: "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min"
    }
});


fd.spRendered(function() {
    // Initialize button object
    var rollforwardUpdateButton = {
        text: 'Roll Forward Update',
        class: 'btn-secondary',
        visible: false,
        icon: 'FastForward',
        iconType: 0,
        DueDateToLender: '',
        PeriodEndDate: '',
        click: function() {
                        
            require(['moment'], function(moment) {
                var itemIDs = fd.control('SPDataTable1').selectedItems.map(function(item){ return item.ID} );
                var list = pnp.sp.web.lists.getByTitle("Deliverables");
                //alert("Selected items:" + itemIDs.length);    
 
                itemIDs.forEach(function(itemID, index){
                    list.items.getById(itemID).get().then(function(item){
                        date1 = moment(item.DueDateToLender);
                        rollforwardUpdateButton.DueDateToLender = date1.add(1, 'years').format();
                        date2 = moment(item.PeriodEndDate);
                        rollforwardUpdateButton.PeriodEndDate = date2.add(1, 'years').format();
                        return rollforwardUpdateButton;
                    }).then(function(rollforwardUpdateButton){
                        list.items.getById(itemID).update({
                        DueDateToLender: rollforwardUpdateButton.DueDateToLender,
                        PeriodEndDate: rollforwardUpdateButton.PeriodEndDate
                    })
                });
             })
            setTimeout(function(){ fd.control('SPDataTable1').refresh(); }, 3000);
            rollforwardUpdateButton.visible = false;
        }
    }

    // SPDataTable1 on ready
    fd.control('SPDataTable1').ready().then(function(dt) {
        //set dialog size
        dt.dialogOptions = {
            width: 1600,
            height: 820
        }
        dt.buttons[0].visible = false; //hide default add new item button
        dt.buttons.push(rollforwardUpdateButton);
        dt.$watch('selectedItems', function(items) {
            rollforwardUpdateButton.visible = items && items.length >= 2; //only show rollforward copy button when 2 or more items are selected
        });
    });

});

Hello @stormanh,

It was syntax errors in the code. Please find the corrected code below:

// Define fd globally in this parent form
window.fd = fd;

// Make pnp-js available in browser's console
window.pnp = pnp;

// Make jQuery available in browser's console
window.$ = $;

// Get external JS
requirejs.config({
    paths: {
        moment: "https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min"
    }
});


fd.spRendered(function() {
    // Initialize button object
    var rollforwardUpdateButton = {
        text: 'Roll Forward Update',
        class: 'btn-secondary',
        visible: false,
        icon: 'FastForward',
        iconType: 0,
        DueDateToLender: '',
        PeriodEndDate: '',
        click: function() {
                        
            require(['moment'], function(moment) {
                var itemIDs = fd.control('SPDataTable1').selectedItems.map(function(item){ return item.ID} );
                var list = pnp.sp.web.lists.getByTitle("Deliverables");
                //alert("Selected items:" + itemIDs.length);    
 
                itemIDs.forEach(function(itemID, index){
                    list.items.getById(itemID).get().then(function(item){
                        date1 = moment(item.DueDateToLender);
                        rollforwardUpdateButton.DueDateToLender = date1.add(1, 'years').format();
                        date2 = moment(item.PeriodEndDate);
                        rollforwardUpdateButton.PeriodEndDate = date2.add(1, 'years').format();
                        return rollforwardUpdateButton;
                    }).then(function(rollforwardUpdateButton){
                        list.items.getById(itemID).update({
                        DueDateToLender: rollforwardUpdateButton.DueDateToLender,
                        PeriodEndDate: rollforwardUpdateButton.PeriodEndDate
                    })
                });
             })
            setTimeout(function(){ fd.control('SPDataTable1').refresh(); }, 3000);
            rollforwardUpdateButton.visible = false;
        });
    }
    }

    // SPDataTable1 on ready
    fd.control('SPDataTable1').ready().then(function(dt) {
        //set dialog size
        dt.dialogOptions = {
            width: 1600,
            height: 820
        }
        dt.buttons[0].visible = false; //hide default add new item button
        dt.buttons.push(rollforwardUpdateButton);
        dt.$watch('selectedItems', function(items) {
            rollforwardUpdateButton.visible = items && items.length >= 2; //only show rollforward copy button when 2 or more items are selected
        });
    });

});
1 Like