PnP Date Time Picker Control In SharePoint Framework

PnP React Controls

 
Patterns and Practices (PnP) provides a list of reusable React controls to developers for building solutions such as webparts and extensions using SharePoint Framework.
 
Refer to this link to get the list of React controls for SPFx.
 
You will see how to use PnP Date Time Picker control in SPFx webpart.
 

PnP Date Time Picker Control

 
This control allows you to select dates from a calendar and optionally the time of day using dropdown controls. You can configure the control to use a 12 or 24-hour clock. Refer to this link for more details.
 
PnP Date Time Picker Control In SharePoint Framework 
 
In this article, you will see how to perform the following tasks,
  • Prerequisites
  • Create SPFx solution
  • Implement Date Time Picker Control solution
  • Deploy the solution
  • Test the webpart
Prerequisites

Create SPFx solution

 
Open Node.js command prompt.
 
Create a new folder.
 
>md spfx-pnpreact-datetimepicker
 
Navigate to the folder.
 
> cd spfx-pnpreact-datetimepicker
 
Execute the following command to create SPFx webpart.
 
>yo @microsoft/sharepoint
 
Enter all the required details to create a new solution. Yeoman generator will perform the scaffolding process and once it is completed, lock down the version of project dependencies by executing the following command.
 
>npm shrinkwrap
 
Execute the following command to open the solution in the code editor.
 
>code .
 

Implement Date Time Picker Control solution

 
Execute the following command to install the PnP React Controls NPM package.
 
>npm install @pnp/spfx-controls-react –save
 
Execute the following command to install the pnp sp library.
 
>npm install @pnp/sp –save
 
Create a new ts file named as “IDatetimepickercontrolState.ts” under Components folder (src\webparts\datetimepickercontrol\components\IDatetimepickercontrolState.ts) and update the code as shown below.
  1. import { MessageBarType } from 'office-ui-fabric-react';   
  2.   
  3. export interface IDatetimepickercontrolState{  
  4.     projectTitle: string;  
  5.     projectDescription: string;  
  6.     startDate: Date;  
  7.     endDate: Date;  
  8.     showMessageBar: boolean;      
  9.     messageType?: MessageBarType;      
  10.     message?: string;    
  11. }  
Open the props file (src\webparts\datetimepickercontrol\components\IDatetimepickercontrolProps.ts) and update the code as shown below.
  1. import {WebPartContext} from '@microsoft/sp-webpart-base';  
  2.   
  3. export interface IDatetimepickercontrolProps {  
  4.   description: string;  
  5.   context: WebPartContext;  
  6. }  
Open the webpart file “src\webparts\datetimepickercontrol\DatetimepickercontrolWebPart.ts” and update the render method.
  1. public render(): void {  
  2.    const element: React.ReactElement<IDatetimepickercontrolProps> = React.createElement(  
  3.      Datetimepickercontrol,  
  4.      {  
  5.        description: this.properties.description,  
  6.        context: this.context  
  7.      }  
  8.    );  
  9.   
  10.    ReactDom.render(element, this.domElement);  
  11.  }  
Open the component file “src\webparts\datetimepickercontrol\components\Datetimepickercontrol.tsx” and import the following modules.
  1. import { IDatetimepickercontrolState } from './IDatetimepickercontrolState';  
  2. import { TextField } from 'office-ui-fabric-react/lib/TextField';  
  3. import { MessageBar, MessageBarType, IStackProps, Stack } from 'office-ui-fabric-react';  
  4. import { autobind } from 'office-ui-fabric-react';  
  5. import { DateTimePicker, DateConvention, TimeConvention, TimeDisplayControlType } from '@pnp/spfx-controls-react/lib/dateTimePicker';  
  6. import { sp } from "@pnp/sp";  
  7. import "@pnp/sp/webs";  
  8. import "@pnp/sp/lists";  
  9. import "@pnp/sp/items";  
Update the render method as shown below.
  1.  public render(): React.ReactElement<IDatetimepickercontrolProps> {  
  2.   return (  
  3.   
  4.     <div className={styles.row}>  
  5.       <h1>Create New Project</h1>  
  6.       {  
  7.         this.state.showMessageBar  
  8.           ?  
  9.           <div className="form-group">  
  10.             <Stack {...verticalStackProps}>  
  11.               <MessageBar messageBarType={this.state.messageType}>{this.state.message}</MessageBar>  
  12.             </Stack>  
  13.           </div>  
  14.           :  
  15.           null  
  16.       }  
  17.       <div className={styles.row}>  
  18.         <TextField label="Project Title" required onChanged={this.__onchangedTitle} />  
  19.         <TextField label="Project Description" required onChanged={this.__onchangedDescription} />  
  20.         <DateTimePicker label="Start Date"  
  21.           dateConvention={DateConvention.DateTime}  
  22.           timeConvention={TimeConvention.Hours12}  
  23.           timeDisplayControlType={TimeDisplayControlType.Dropdown}  
  24.           showLabels={false}  
  25.           value={this.state.startDate}  
  26.           onChange={this.__onchangedStartDate}  
  27.         />  
  28.         <DateTimePicker label="End Date"  
  29.           dateConvention={DateConvention.Date}  
  30.           timeConvention={TimeConvention.Hours12}  
  31.           timeDisplayControlType={TimeDisplayControlType.Dropdown}  
  32.           showLabels={false}  
  33.           value={this.state.endDate}  
  34.           onChange={this.__onchangedEndDate}  
  35.         />  
  36.         <div className={styles.button}>  
  37.           <button type="button" className="btn btn-primary" onClick={this.__createItem}>Submit</button>  
  38.         </div>  
  39.       </div>  
  40.     </div>  
  41.   );  
  42. }  
Create the constructor in the component file.
  1. export default class Datetimepickercontrol extends React.Component<IDatetimepickercontrolProps, IDatetimepickercontrolState> {    
  2.   constructor(props: IDatetimepickercontrolProps, state: IDatetimepickercontrolState) {    
  3.     super(props);    
  4.     sp.setup({    
  5.       spfxContext: this.props.context    
  6.     });    
  7.     this.state = {    
  8.       projectTitle: '',    
  9.       projectDescription: '',    
  10.       startDate: new Date(),    
  11.       endDate: new Date(),    
  12.       showMessageBar: false    
  13.     };    
  14.   }    
Create the helper methods in the component file.
  1.  @autobind  
  2.   private __onchangedTitle(title: any): void {  
  3.     this.setState({ projectTitle: title });  
  4.   }  
  5.   
  6.   @autobind  
  7.   private __onchangedDescription(description: any): void {  
  8.     this.setState({ projectDescription: description });  
  9.   }  
  10.   
  11.   @autobind  
  12.   private __onchangedStartDate(date: any): void {  
  13.     this.setState({ startDate: date });  
  14.   }  
  15.   
  16.   @autobind  
  17.   private __onchangedEndDate(date: any): void {  
  18.     this.setState({ endDate: date });  
  19.   }  
  20.   
  21.   @autobind  
  22.   private async __createItem() {  
  23.     try {  
  24.       await sp.web.lists.getByTitle('Project Details').items.add({  
  25.         Title: this.state.projectTitle,  
  26.         Description: this.state.projectDescription,  
  27.         StartDate: this.state.startDate,  
  28.         EndDate: this.state.endDate  
  29.       });  
  30.       this.setState({  
  31.         message: "Item: " + this.state.projectTitle + " - created successfully!",  
  32.         showMessageBar: true,  
  33.         messageType: MessageBarType.success  
  34.       });  
  35.     }  
  36.     catch (error) {  
  37.       this.setState({  
  38.         message: "Item " + this.state.projectTitle + " creation failed with error: " + error,  
  39.         showMessageBar: true,  
  40.         messageType: MessageBarType.error  
  41.       });  
  42.     }  
  43.   }  
Updated React component (src\webparts\datetimepickercontrol\components\Datetimepickercontrol.tsx),
  1. import * as React from 'react';  
  2. import styles from './Datetimepickercontrol.module.scss';  
  3. import { IDatetimepickercontrolProps } from './IDatetimepickercontrolProps';  
  4. import { IDatetimepickercontrolState } from './IDatetimepickercontrolState';  
  5. import { escape } from '@microsoft/sp-lodash-subset';  
  6. import { TextField } from 'office-ui-fabric-react/lib/TextField';  
  7. import { MessageBar, MessageBarType, IStackProps, Stack } from 'office-ui-fabric-react';  
  8. import { autobind } from 'office-ui-fabric-react';  
  9. import { DateTimePicker, DateConvention, TimeConvention, TimeDisplayControlType } from '@pnp/spfx-controls-react/lib/dateTimePicker';  
  10. import { sp } from "@pnp/sp";  
  11. import "@pnp/sp/webs";  
  12. import "@pnp/sp/lists";  
  13. import "@pnp/sp/items";  
  14.   
  15. const verticalStackProps: IStackProps = {  
  16.   styles: { root: { overflow: 'hidden', width: '100%' } },  
  17.   tokens: { childrenGap: 20 }  
  18. };  
  19.   
  20. export default class Datetimepickercontrol extends React.Component<IDatetimepickercontrolProps, IDatetimepickercontrolState> {  
  21.   constructor(props: IDatetimepickercontrolProps, state: IDatetimepickercontrolState) {  
  22.     super(props);  
  23.     sp.setup({  
  24.       spfxContext: this.props.context  
  25.     });  
  26.     this.state = {  
  27.       projectTitle: '',  
  28.       projectDescription: '',  
  29.       startDate: new Date(),  
  30.       endDate: new Date(),  
  31.       showMessageBar: false  
  32.     };  
  33.   }  
  34.   
  35.   public render(): React.ReactElement<IDatetimepickercontrolProps> {  
  36.     return (  
  37.   
  38.       <div className={styles.row}>  
  39.         <h1>Create New Project</h1>  
  40.         {  
  41.           this.state.showMessageBar  
  42.             ?  
  43.             <div className="form-group">  
  44.               <Stack {...verticalStackProps}>  
  45.                 <MessageBar messageBarType={this.state.messageType}>{this.state.message}</MessageBar>  
  46.               </Stack>  
  47.             </div>  
  48.             :  
  49.             null  
  50.         }  
  51.         <div className={styles.row}>  
  52.           <TextField label="Project Title" required onChanged={this.__onchangedTitle} />  
  53.           <TextField label="Project Description" required onChanged={this.__onchangedDescription} />  
  54.           <DateTimePicker label="Start Date"  
  55.             dateConvention={DateConvention.DateTime}  
  56.             timeConvention={TimeConvention.Hours12}  
  57.             timeDisplayControlType={TimeDisplayControlType.Dropdown}  
  58.             showLabels={false}  
  59.             value={this.state.startDate}  
  60.             onChange={this.__onchangedStartDate}  
  61.           />  
  62.           <DateTimePicker label="End Date"  
  63.             dateConvention={DateConvention.Date}  
  64.             timeConvention={TimeConvention.Hours12}  
  65.             timeDisplayControlType={TimeDisplayControlType.Dropdown}  
  66.             showLabels={false}  
  67.             value={this.state.endDate}  
  68.             onChange={this.__onchangedEndDate}  
  69.           />  
  70.           <div className={styles.button}>  
  71.             <button type="button" className="btn btn-primary" onClick={this.__createItem}>Submit</button>  
  72.           </div>  
  73.         </div>  
  74.       </div>  
  75.     );  
  76.   }  
  77.   @autobind  
  78.   private __onchangedTitle(title: any): void {  
  79.     this.setState({ projectTitle: title });  
  80.   }  
  81.   
  82.   @autobind  
  83.   private __onchangedDescription(description: any): void {  
  84.     this.setState({ projectDescription: description });  
  85.   }  
  86.   
  87.   @autobind  
  88.   private __onchangedStartDate(date: any): void {  
  89.     this.setState({ startDate: date });  
  90.   }  
  91.   
  92.   @autobind  
  93.   private __onchangedEndDate(date: any): void {  
  94.     this.setState({ endDate: date });  
  95.   }  
  96.   
  97.   @autobind  
  98.   private async __createItem() {  
  99.     try {  
  100.       await sp.web.lists.getByTitle('Project Details').items.add({  
  101.         Title: this.state.projectTitle,  
  102.         Description: this.state.projectDescription,  
  103.         StartDate: this.state.startDate,  
  104.         EndDate: this.state.endDate  
  105.       });  
  106.       this.setState({  
  107.         message: "Item: " + this.state.projectTitle + " - created successfully!",  
  108.         showMessageBar: true,  
  109.         messageType: MessageBarType.success  
  110.       });  
  111.     }  
  112.     catch (error) {  
  113.       this.setState({  
  114.         message: "Item " + this.state.projectTitle + " creation failed with error: " + error,  
  115.         showMessageBar: true,  
  116.         messageType: MessageBarType.error  
  117.       });  
  118.     }  
  119.   }  
  120. }    

Deploy the solution

 
Execute the following commands to bundle and package the solution.
 
>gulp bundle --ship
>gulp package-solution --ship
 
Navigate to tenant app catalog – Example: https://c986.sharepoint.com/sites/appcatalog/SitePages/Home.aspx
 
Go to Apps for SharePoint library and upload the package file (sharepoint\solution\spfx-pnpreact-datetimepicker.sppkg). Click Deploy.
 
PnP Date Time Picker Control In SharePoint Framework 
 

Test the webpart

 
Navigate to the SharePoint site and add the app.
 
PnP Date Time Picker Control In SharePoint Framework 
 

Result

 
Navigate to the page and add the webpart. Enter all the details and click submit, a new item gets created in the SharePoint list.
 
PnP Date Time Picker Control In SharePoint Framework 
 

Summary

 
Thus, in this article, you saw how to use PnP Date Time Picker Control in SharePoint Framework.