PnPjs is a JavaScript library that provides a fluent API for interacting with SharePoint and Microsoft 365. It simplifies the development of client-side code for SharePoint and Microsoft 365 by abstracting away the complexities of the underlying REST APIs. With PnPjs, developers can perform common operations such as querying lists, creating sites, managing user profiles, etc., using simple and familiar JavaScript syntax.
Read more about PnPjs library.
This library is included with Plumsail Forms for SharePoint and in this article we’ll showcase how it can be used on your forms.
Tip
By default, sp variable is connected to the current site the form is located at, but you can use Web(url) to connect to any site on the tenant:
let web = new Web('{SiteURL}');
You can get any item in any list with the following code, which can then be used to populate fields on the form:
let item = await sp.web.lists.getByTitle('My List').items .getById(1) .get(); console.log(item);
You can get items without knowing their ID with a filter, for example, you can get all items where Category Choice field is equal Bug Report:
let items = await sp.web.lists.getByTitle('My List').items .filter("Category eq 'Bug Report'") .get(); console.log(items);
You can also filter by current user, like this:
const user = await sp.web.currentUser.get(); let items = await sp.web.lists.getByTitle('My List').items .filter('Manager eq ' + user.Id) .get(); console.log(items);
Some fields might not be retrieved without specifying them. Use select to specify what fields to retrieve, and expand to get values from complex fields like Lookup or Person:
let items = await sp.web.lists.getByTitle('Tickets').items .select('Title', 'Id', 'Supervisors/Name') .expand('Supervisors') .filter("Title eq 'Example A'") .get(); // see if we got something if (items.length > 0) { //save names from the first item to a separate array const names = items[0].Approvers.map(a => a.Name); //set current Ticket Title, ID and Supervisors fields with values from Tickets list fd.field('TicketTitle').value = items[0].Title; fd.field('TicketID').value = items[0].Id; fd.field('TicketSupervisors').value = names; }
You can populate a dropdown with items from a list with the following code:
const items = await sp.web.lists.getByTitle('My List').items.select('Title').get(); fd.field('DropDown1').widget.setDataSource({ data: items.map(i => i.Title) });
Find more information about this in the How to populate dropdown field in SharePoint form with data from list located in another site article.
If you need to change an existing item, you can update its values with the following code:
const parentItemId = fd.itemId; let childItemId = fd.field('ChildID').value; let childItem = await sp.web.lists.getByTitle('Child List').items .getById(childItemId) .update({ LookupFieldNameId: parentItemId });
You can also create a new item and specify values for its fields with the following:
const title = fd.field('Title').value; const category = fd.field('Category').value; let item = await sp.web.lists.getByTitle('My List').items .add({ Title: title, Category: category });
If you want to run a request, before current form gets saved, you can replace Save button’s functionality to first run the request, and then save on success:
fd.spRendered(() => { //replace toolbar button Save fd.toolbar.buttons[0].click = async () => { const employee = fd.field('Manager').value; const status = fd.field('Status').value; if (employee && employee.Key) { const item = await sp.web.lists.getByTitle('Employee List').items .filter('Employee eq ' + employee.Key) .update({ Status: status }); //save on success fd.save(); } } });
You can check if an item already exists before saving with the following code:
let itemExists = false; fd.spRendered(() => { //replace toolbar button Save fd.toolbar.buttons[0].click = async () => { const filter = `Title eq '${fd.field('Title').value}'`; const items = await sp.web.lists.getByTitle('My List').items.filter(filter).getAll(); if(items.length > 0){ itemExists = true; fd.isValid; } else { itemExists = false; fd.save(); } } fd.validators.push({ name: 'ItemExistsValidator', error: 'Item already exists', validate: () => !itemExists }); });