Read all lists/views/fields using pnpjs in spfx webpart
Recently I started exploring pnp js with spfx webparts. I wanted to explore few things which are more of basic functionality for any webparts. In this Post I'll explain
- How to read all the lists from a site and bind to dropdown in spfx webpart
- Read all the views for a selected list and bind to 2nd dropdown.
- Get all the fields/columns for a selected view and render then as checkboxes in spfx webpart.
import {sp, Web, List} from '@pnp/sp';
First step is to declare 3 collections for above 3 requirements so that you can use them in getPropertyPageConfiguration() method.
private listDropDownOptions: IPropertyPaneDropdownOption[];
private viewDropDownOptions: IPropertyPaneDropdownOption[];
private fieldsListCollection = [];
Use these collections in getPropertyPageConfiguration() method.
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription
},
groups: [
{
groupName: strings.BasicGroupName,
/**
* Instead of calling group
fields here, we will call method which will return back preoperties to render.
*/
groupFields: [
PropertyPaneTextField('description', {
label: strings.DescriptionFieldLabel
})
]
},
{
groupName:strings.ListInformationGroup,
groupFields:[
PropertyPaneDropdown('listDropdown',{
label:strings.ListTitle,
options:this.listDropDownOptions
}),
PropertyPaneDropdown("viewDropdown",{
label:strings.SelectedView,
options:this.viewDropDownOptions
})
],
},
{
groupName: "Fields",
groupFields:this.fieldsListCollection
}
]
}
]
};
Next step is to setup the context
protected onInit() : Promise<void>{
this.listDropDownOptions = [];
this.viewDropDownOptions = [];
return super.onInit().then(_ => {
sp.setup({
spfxContext
: this.context
});
});
}
Now, using pnpjs read all the lists from the web and add them to listDropdown collection. Here is how you can do it. You might need to filter the hidden lists as they are not required.
//get all the lists
from the site and populate the dropdown
private GetLists():Promise<any>{
return sp.web.lists.filter('Hidden eq false').get().then((data) =>{
console.log("Total number of
lists are " + data.length);
return data;
});
Once you have returned all the lists from web, you need to add this to the listDropDownOptions collection which we have bound to the lists dropdown. This is how it can be done.
protected onPropertyPaneConfigurationStart():void{
this.listsDropdownDisabled = !this.listDropDownOptions;
this.context.statusRenderer.displayLoadingIndicator(this.domElement, 'lists');
//
loads list name into list dropdown
this.GetLists().then((response) =>{
for(let i=0 ; i< response.length;i++){
//now
populate the listdropdown array
this.listDropDownOptions.push({key:response[i].Title,text:response[i].Title});
}
this.listsDropdownDisabled = false;
this.context.propertyPane.refresh();
this.context.statusRenderer.clearLoadingIndicator(this.domElement);
this.render();
});
}
Now, if you run your webpart you will have all the lists from the web rendered in the Lists dropdown.
Next step is to get all the views for the selected list from the dropdown and populate them in Views dropdown.
//get all the views
for the selected list
private getViewsForSelectedList():Promise<any>{
if (!this.properties.selectedList) {
//
resolve to empty options since no list has been selected
return Promise.resolve();
}
//reset
the view value
this.properties.selectedView = undefined;
var list = sp.web.lists.getByTitle(this.properties.selectedList);
//get
all the views of the selected list.
return sp.web.lists.getByTitle(this.properties.selectedList).views.get().then((data) =>{
console.log("Total number of
views are " + data.length);
return data;
});
}
Now, we have all the views retrieved we need to get all the fields for the selected view in the dropdown.
private getFieldsForSelectedView():Promise<any>{
if (!this.properties.selectedView) {
//
resolve to empty options since no list has been selected
return Promise.resolve();
}
const filter = `Hidden eq false and
ReadOnlyField eq false`;
//get
all the fields of the selected view.
return sp.web.lists.getByTitle(this.properties.selectedList).views.getByTitle(this.properties.selectedView).fields.select('Items').filter(filter).get().then((data) =>{
console.log("Total number of
fields are " + data.length);
return data;
});
}
Once we have all the views and fields, we need to populate them to the dropdown. For fields we need to create the collection of PropertyPaneCheckbox object and add that to array.
protected onPropertyPaneFieldChanged(propertyPath: string, oldValue:any, newValue:any):void{
if(propertyPath ==='listDropdown' && newValue){
super.onPropertyPaneFieldChanged(propertyPath, oldValue, newValue);
this.properties.selectedList = newValue;
//get
previously selected value
const previousViewValue :string = this.properties.selectedView;
//reset
the view dropdown to clear the old values.
this.viewDropDownOptions = [];
this.fieldsListCollection =[];
//reset
the view value
//this.properties.selectedView
= undefined;
this.onPropertyPaneFieldChanged('viewDropdown' , previousViewValue, this.properties.selectedView);
this.getViewsForSelectedList().then((response) =>{
for(let i=0 ; i< response.length;i++){
//now
populate the listdropdown array
this.viewDropDownOptions.push({key:response[i].Title,text:response[i].Title});
}
//this.listsDropdownDisabled
= false;
this.context.propertyPane.refresh();
this.context.statusRenderer.clearLoadingIndicator(this.domElement);
this.render();
});
}
//get all the fields for a view and add to array
else if(propertyPath==='viewDropdown' && newValue){
this.properties.selectedView = newValue;
this.getFieldsForSelectedView().then((response) => {
const fields = (response as any).Items.results || (response as any).Items;
this.fieldsListCollection =[];
for(let f=0;f< fields.length;f++){
this.fieldsListCollection.push(
PropertyPaneCheckbox(
fields[f],
{text:fields[f]}
)
);
}
this.context.propertyPane.refresh();
});
}
else {
super.onPropertyPaneFieldChanged(propertyPath, oldValue, newValue);
}
}
Here is the final result how it will look like.
Happy coding..
Happy SharePointing...
Comments
Post a Comment