Thursday 15 December 2016

Implementing SharePoint Operations Using React.js - Part Two

Here, you will see how React JavaScript plugins can be plugged in to SharePoint pages for rendering the data.
In my previous post, I explained about the basic terminology required for implementing React JavaScript logic on SharePoint pages.

Note

The core logic is implemented inside the class. The class can be created in two ways:
  • React traditionally provides React.createClass method to create the component classes.
  • Recently updated React JS version allows us to create the classes, using the React.Component method supported, using ES6 modules.
These two methods differ in implementation approaches. In this article, I will create the components, using ES6 modules.


Steps Involved

Upload the necessary plugins onto SharePoint site libraries. Instead of the local copies, the plugins can be directly accessed from cdn sites.

Create the content editor Webpart manually on the site. The custom Web parts can also be used. Inside the Web part, refer to the plugins explicitly.
  1. <script src="https://unpkg.com/react@latest/dist/react.js"></script>  
  2. <script src="https://unpkg.com/react-dom@latest/dist/react-dom.js"></script>  
  3. <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>   
Add the root HTML tag for appending the content, using JSX.
  1. <div id="listInformation"></div>  
JSX content is written inside the script tag, which is of the type text/babel. Babel plugin helps the code to be executed on the Browsers.

Create the class with custom name, using React.Component method. Class should contain a constructor, which has super() method declared. Set the state container with the necessary variables. In this sample, list name, descriptions, template ID and items count are stored.
  1. constructor(){  
  2.      super();  
  3.      this.state = {  
  4.          listInfo: {listName: '',listDescription: '', templateId:0, itemCount: 0}  
  5.      }  
  6.  }  
Since the data needs to be rendered on the page load, one of the life cycle methods is used to retrieve the list information and set it into the state variables. In this sample, the data is retrieved asynchronously. Thus, componentDidMount method is used. The custom function is created for retrieving the list information. 
  1. GetListInfo(){  
  2.     var reactHandler = this;  
  3.   
  4.     var request = new XMLHttpRequest();  
  5.     request.open('GET'"/_api/web/lists/getbytitle('TestList')"true);  
  6.     request.setRequestHeader('Content-Type''application/json; charset=UTF-8');  
  7.           
  8.     //this callback gets called when the server responds to the ajax call  
  9.     request.onreadystatechange = function(){  
  10.         if (request.readyState === 4 && request.status === 200){  
  11.             var returnedJson = JSON.parse(request.responseText);  
  12.               
  13.             reactHandler.setState({  
  14.                 listInfo:  
  15.                 {  
  16.                     listName: returnedJson.Title,  
  17.                     listDescription: returnedJson.Description,  
  18.                     templateId: returnedJson.BaseTemplate,  
  19.                     itemCount: returnedJson.ItemCount  
  20.                 }  
  21.             });  
  22.         }  
  23.         else if (request.readyState === 4 && request.status !== 200){  
  24.             console.log('Error in retrieving data!');  
  25.         }  
  26.     };  
  27.     request.send();  
  28. } 


Note

Event handlers can also be used instead of the method shown above, if the data retrieval is based on the user action.

The render method displays the data. HTML is inserted into this method. The state variables are referred to in this method to display the necessary information.
  1. render(){  
  2.     return(  
  3.     <div>  
  4.         <h2>{this.state.listInfo.listName} List Information:</h2>  
  5.         <p>{this.state.listInfo.listDescription}</p>  
  6.         <p>Template : {this.state.listInfo.templateId}</p>  
  7.         <p>Total Items: {this.state.listInfo.itemCount}</p>  
  8.     </div>  
  9.     );  
  10. }   
The render method is called to render the component data.
  1. ReactDOM.render(<ListJS />, document.getElementById('listInformation'));   
The code snippet given below shows the entire logic to retrieve the list information.
  1. <script src="https://unpkg.com/react@latest/dist/react.js"></script>  
  2. <script src="https://unpkg.com/react-dom@latest/dist/react-dom.js"></script>  
  3. <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>  
  4.   
  5. <div id="listInformation"></div>  
  6. <script type="text/babel">  
  7.       
  8.     class ListJS extends React.Component{  
  9.         constructor(){  
  10.             super();  
  11.             this.state = {  
  12.                 listInfo: {listName: '',listDescription: '', templateId:0, itemCount: 0}  
  13.             }  
  14.         }  
  15.         componentDidMount() {  
  16.             // Custom function to retrieve the list info  
  17.             this.GetListInfo();  
  18.         }  
  19.   
  20.         GetListInfo(){  
  21.             var reactHandler = this;  
  22.   
  23.             var request = new XMLHttpRequest();  
  24.             request.open('GET'"/_api/web/lists/getbytitle('TestList')"true);  
  25.             request.setRequestHeader('Content-Type''application/json; charset=UTF-8');  
  26.                   
  27.             //this callback gets called when the server responds to the ajax call  
  28.             request.onreadystatechange = function(){  
  29.                 if (request.readyState === 4 && request.status === 200){  
  30.                     var returnedJson = JSON.parse(request.responseText);  
  31.                       
  32.                     reactHandler.setState({  
  33.                         listInfo:  
  34.                         {  
  35.                             listName: returnedJson.Title,  
  36.                             listDescription: returnedJson.Description,  
  37.                             templateId: returnedJson.BaseTemplate,  
  38.                             itemCount: returnedJson.ItemCount  
  39.                         }  
  40.                     });  
  41.                 }  
  42.                 else if (request.readyState === 4 && request.status !== 200){  
  43.                     console.log('Error in retrieving data!');  
  44.                 }  
  45.             };  
  46.             request.send();  
  47.         }  
  48.   
  49.         render(){  
  50.             return(  
  51.             <div>  
  52.                 <h2>{this.state.listInfo.listName} List Information:</h2>  
  53.                 <p>{this.state.listInfo.listDescription}</p>  
  54.                 <p>Template : {this.state.listInfo.templateId}</p>  
  55.                 <p>Total Items: {this.state.listInfo.itemCount}</p>  
  56.             </div>  
  57.             );  
  58.         }  
  59.       
  60.     }  
  61.   
  62.     ReactDOM.render(<ListJS />, document.getElementById('listInformation'));  
  63. </script>   
The snapshot given below shows the Webpart, which shows the list information, using the logic stated above.