Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save giuleon/afd41900bb2ab34c91a075be00e154a0 to your computer and use it in GitHub Desktop.
Save giuleon/afd41900bb2ab34c91a075be00e154a0 to your computer and use it in GitHub Desktop.
SharePoint Framework field customizer - Office UI Fabric toggle and pnp js core library in action
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { Log } from '@microsoft/sp-core-library';
import { override } from '@microsoft/decorators';
import {
CellFormatter,
BaseFieldCustomizer,
IFieldCustomizerCellEventParameters
} from '@microsoft/sp-listview-extensibility';
import { SPPermission } from "@microsoft/sp-page-context";
import pnp, { List, ItemUpdateResult, Item } from 'sp-pnp-js';
import * as strings from 'toggleStrings';
import Toggle from './components/Toggle';
import { IToggleProps } from './components/IToggleProps'
/**
* If your field customizer uses the ClientSideComponentProperties JSON input,
* it will be deserialized into the BaseExtension.properties object.
* You can define an interface to describe it.
*/
export interface IToggleProperties {
// This is an example; replace with your own property
sampleText?: string;
}
const LOG_SOURCE: string = 'ToggleFieldCustomizer';
export default class ToggleFieldCustomizer
extends BaseFieldCustomizer<IToggleProperties> {
@override
public onInit(): Promise<void> {
// Add your custom initialization to this method. The framework will wait
// for the returned promise to resolve before firing any BaseFieldCustomizer events.
Log.info(LOG_SOURCE, 'Activated ToggleFieldCustomizer with properties:');
Log.info(LOG_SOURCE, JSON.stringify(this.properties, undefined, 2));
Log.info(LOG_SOURCE, `The following string should be equal: "Toggle" and "${strings.Title}"`);
return Promise.resolve<void>();
}
@override
public onRenderCell(event: IFieldCustomizerCellEventParameters): void {
// Use this method to perform your custom cell rendering. The CellFormatter is a utility
// that you can use to convert the cellValue to a text string.
const value: string = event.cellValue;
const id: string = event.row.getValueByName('ID').toString();
const hasPermissions: boolean = this.context.pageContext.list.permissions.hasPermission(SPPermission.editListItems);
const toggle: React.ReactElement<{}> =
React.createElement(Toggle, { checked: value, id: id, disabled: !hasPermissions, onChanged: this.onToggleValueChanged.bind(this) } as IToggleProps);
ReactDOM.render(toggle, event.cellDiv);
}
@override
public onDisposeCell(event: IFieldCustomizerCellEventParameters): void {
// This method should be used to free any resources that were allocated during rendering.
// For example, if your onRenderCell() called ReactDOM.render(), then you should
// call ReactDOM.unmountComponentAtNode() here.
ReactDOM.unmountComponentAtNode(event.cellDiv);
super.onDisposeCell(event);
}
private onToggleValueChanged(value: boolean, id: string): void {
let etag: string = undefined;
pnp.sp.web.lists.getByTitle(this.context.pageContext.list.title).items.getById(parseInt(id)).get(undefined, {
headers: {
'Accept': 'application/json;odata=minimalmetadata'
}
})
.then((item: Item): Promise<any> => {
etag = item["odata.etag"];
return Promise.resolve((item as any) as any);
})
.then((item: any): Promise<ItemUpdateResult> => {
let updateObj: any = {};
updateObj[this.context.field.internalName] = value;
return pnp.sp.web.lists.getByTitle(this.context.pageContext.list.title)
.items.getById(parseInt(id)).update(updateObj, etag);
})
.then((result: ItemUpdateResult): void => {
console.log(`Item with ID: ${id} successfully updated`);
}, (error: any): void => {
console.log('Loading latest item failed with error: ' + error);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment