This blogs explains the step by step procedure to create a multi select checkbox using Sharepoint framework client side webpart (SPFx). I am using "Office UI Fabric React" controls to style the buttons. The values are stored as a semicolon separated in SharePoint list.

Code Usage
I have created a React component and named it as "Dialog.tsx" as shown below.
Import the below node modules to your solution. Here, I have used UrlQueryParameterCollection to retrieve the ListItemId which is passed as a querystring parameter.
  1. import * as React from 'react';
  2. import { ISpFxRichTextEditorProps } from '../ISpFxRichTextEditorProps';
  3. import { PrimaryButton, DefaultButton, DialogType, Dialog, DialogFooter, TextField, Label } from 'office-ui-fabric-react';
  4. import * as $ from "jquery";
  5. import { UrlQueryParameterCollection } from '@microsoft/sp-core-library';
Declare the state variables as shown below.
  1. export interface IDialogState {
  2. hideDialog: boolean;
  3. spanID:string;
  4. dialogID: string;
  5. standard:string;
  6. isDraggable: boolean;
  7. typeOfWorkTemparr:any[];
  8. typeArr:any[];
  9. }
Declare global arrays to hold the value.
  1. var typeofworkarr=[];
  2. var multiTypeOfWorkChkBox=[];
Bind events in constructor class as shown below
  1. public constructor(props: ISpFxRichTextEditorProps) {
  2. super(props);
  3. this.HandleTypeOfArray=this.HandleTypeOfArray.bind(this);
  4. }
Initiate the state variables and populate the type of work values on load.
  1. public state: IDialogState = {
  2. hideDialog: this.props.dialogOpen,
  3. isDraggable: false,
  4. spanID: this.props.spanID,
  5. dialogID: this.props.id,
  6. standard: this.props.standard,
  7. /** Type of Work Values */
  8. typeOfWorkTemparr: [{
  9. name: 'Revision',
  10. key: 'Revision',
  11. label: 'Revision',
  12. isChecked: false
  13. }, {
  14. name: 'Design',
  15. key: 'Design',
  16. label: 'Design',
  17. isChecked: false
  18. }, {
  19. name: 'Maintainence',
  20. key: 'Maintainence',
  21. label: 'Maintainence',
  22. isChecked: false
  23. }, {
  24. name: 'Scan Print',
  25. key: 'Scan Print',
  26. label: 'Scan Print',
  27. isChecked: false
  28. }, {
  29. name: 'Locate Print',
  30. key: 'Locate Print',
  31. label: 'Locate Print',
  32. isChecked: false
  33. }, {
  34. name: 'File Print On Drive',
  35. key: 'File Print On Drive',
  36. label: 'File Print On Drive',
  37. isChecked: false
  38. }, {
  39. name: 'Plot/Print',
  40. key: 'Plot/Print',
  41. label: 'Plot/Print',
  42. isChecked: false
  43. }],
  44. typeArr: []
  45. };
Get the values of Dialog Label and sub text label from parent component.
  1. private labelId: string = getId('dialogLabel');
  2. private subTextId: string = getId('subTextLabel');
Declare the Render function as shown below
  1. public render() {
  2. const {
  3. hideDialog
  4. } = this.state;
  5. let inputchkbox;
  6. let inputcontrols;
  7. let selectBox;
  8. /* input control starts here*/
  9. if (this.state.spanID == "spnTypeOfWork") {
  10. inputchkbox = this.state.typeOfWorkTemparr.map((item, i) => {
  11. return ( < Label key = {
  12. item.key
  13. } > < input type = "checkbox"
  14. ref = {
  15. 'ref_' + i
  16. }
  17. id = {
  18. item.name
  19. }
  20. name = {
  21. item.name
  22. }
  23. onChange = {
  24. this.HandleTypeOfArray
  25. }
  26. value = {
  27. item.name
  28. }
  29. checked = {
  30. item.isChecked
  31. }
  32. /> {
  33. item.name
  34. } < /Label>)
  35. });
  36. }
  37. /* input control ends here*/
  38. /* select control starts here*/
  39. if (this.state.spanID == "spnTypeOfWork") {
  40. selectBox = < div > {
  41. inputchkbox
  42. } < /div>;
  43. }
  44. /* select control ends here*/
  45. return ( < div > < Dialog hidden = {
  46. hideDialog
  47. }
  48. onDismiss = {
  49. this.closeDialog
  50. }
  51. dialogContentProps = {
  52. {
  53. type: DialogType.normal,
  54. title: this.props.value,
  55. subText: "",
  56. styles: {
  57. title: {
  58. backgroundColor: "blue",
  59. height: 10,
  60. marginBottom: 10,
  61. paddingBottom: 22
  62. }
  63. }
  64. }
  65. }
  66. modalProps = {
  67. {
  68. titleAriaId: this.labelId,
  69. subtitleAriaId: this.subTextId,
  70. isBlocking: false,
  71. styles: {
  72. main: {
  73. height: 350,
  74. width: 500
  75. }
  76. },
  77. }
  78. } > {
  79. selectBox
  80. } < DialogFooter > < PrimaryButton onClick = {
  81. this.saveDialog
  82. }
  83. text = "Save" / > < DefaultButton onClick = {
  84. this.closeDialog
  85. }
  86. text = "Cancel" / > < /DialogFooter> < /Dialog> < /div> );
  87. }
Reload the container on componemtDidMount.
  1. /* Initiate load containers */
  2. public componentDidMount(): void {
  3. if(this.state.spanID == "spnTypeOfWork"){
  4. this.ReLoadTypeOfWorkContainer();
  5. }
  6. }
  7. /** Type of Area Selection Starts */
  8. /** Load Area container based on values */
  9. public ReLoadTypeOfWorkContainer() {
  10. try {
  11. let queryParms = new UrlQueryParameterCollection(window.location.href);
  12. let itemID: number = parseInt(queryParms.getValue("ListItemID"));
  13. if (itemID != null && itemID > 0) {
  14. /*Set Priority values on page load*/
  15. this.SetTypeofWorkOnLoad();
  16. } else {
  17. /*Reset Type of work values based on selection*/
  18. let typeofWorkArrValues = this.state.typeOfWorkTemparr
  19. $.each(multiTypeOfWorkChkBox, function (index, value) {
  20. typeofWorkArrValues = [];
  21. typeofWorkArrValues = value;
  22. });
  23. this.setState({ typeOfWorkTemparr: typeofWorkArrValues });
  24. }
  25. } catch (error) {
  26. console.log("Error in ReLoadTypeOfWorkContainer : " + error);
  27. }
  28. }
  29. /* Handle Type of Array section */
  30. public HandleTypeOfArray(event: any):void{
  31. try{
  32. if (event.target.checked == false) {
  33. for (var i = 0; i < typeofworkarr.length; i++) {
  34. if (typeofworkarr[i] === event.target.value) {
  35. typeofworkarr.splice(i, 1);
  36. }
  37. }
  38. }
  39. if (event.target.checked) {
  40. if (typeofworkarr.indexOf(event.target.value) == -1) {
  41. typeofworkarr.push(event.target.value)
  42. }
  43. }
  44. else {
  45. for (var i = 0; i < typeofworkarr.length; i++) {
  46. if (typeofworkarr[i] === event.target.value) {
  47. typeofworkarr.splice(i, 1);
  48. }
  49. }
  50. }
  51. let typeofworkArr = this.state.typeOfWorkTemparr
  52. typeofworkArr.forEach(types => {
  53. if (types.name === event.target.value) {
  54. types.isChecked = event.target.checked
  55. }
  56. })
  57. multiTypeOfWorkChkBox.push(typeofworkArr);
  58. this.setState({ typeOfWorkTemparr: typeofworkArr });
  59. }catch(error){
  60. console.log("Error in HandleTypeOfArray : " + error);
  61. }
  62. }
  63. /** Type of Area Ends */
This function is to update the checkbox selection by retrieving the previously selected checkbox data from SharePoint list.
  1. /**Set Type of work on Load */
  2. private SetTypeofWorkOnLoad(): void {
  3. try {
  4. var finalArray=[];
  5. if ($("#" + this.state.spanID).html() !== "") {
  6. var htmlstring = this.RemovedPtagString($("#" + this.state.spanID).html()).split(',');
  7. var tempPriorArr = htmlstring;
  8. let prioritArrValues = this.state.typeOfWorkTemparr
  9. $.each(prioritArrValues, function (index, item) {
  10. if (tempPriorArr.indexOf(item.name) > -1) {
  11. item.isChecked = true;
  12. }
  13. });
  14. this.setState({ typeOfWorkTemparr: prioritArrValues });
  15. }
  16. } catch (error) {
  17. console.log("Error in SetValuesOnLoad : " + error);
  18. }
  19. }
  20. }
This function is to close the dialog window.
  1. /*Close dialog window*/
  2. private closeDialog = (): void => {
  3. this.setState({ hideDialog: true });
  4. this.props.onUpdate();
  5. }
Save the selected data and send it to parent callback function as shown below.
  1. /*Save operation based on span id selection*/
  2. private saveDialog = (): void => {
  3. if(this.state.spanID == "spnTypeOfWork"){
  4. this.SaveTypeOfWork();
  5. }
  6. }
  7. /*save type of work on save button click */
  8. private SaveTypeOfWork(){
  9. try {
  10. let queryParms = new UrlQueryParameterCollection(window.location.href);
  11. let itemID: number = parseInt(queryParms.getValue("ListItemID"));
  12. if (itemID != null && itemID > 0) {
  13. typeofworkarr = [];
  14. let prioritArrValues = this.state.typeOfWorkTemparr
  15. $.each(prioritArrValues, function (index, item) {
  16. if (item.isChecked == true) {
  17. typeofworkarr.push(item.name);
  18. }
  19. });
  20. this.setState({ checkboxesarr: prioritArrValues });
  21. }
  22. let tempvariable: string = '';
  23. typeofworkarr.forEach(element => {
  24. tempvariable = tempvariable + "<p>" + element + "</p>";
  25. });
  26. var txtValue = tempvariable.indexOf(',') == 0 ? tempvariable.substr(1) : tempvariable;
  27. $("#" + this.state.spanID).html(txtValue);
  28. this.setState({ hideDialog: true });
  29. this.props.onUpdate(this.props.value);
  30. } catch (error) {
  31. console.log("Error in SaveTypeOfWork" + error);
  32. }
  33. }
Remove HTML <P> tag from HTML string,
  1. /*Remove p tag from html string */
  2. private RemovedPtagString(removedPString): string {
  3. let newString;
  4. try {
  5. let item = removedPString.replace(/<p[^>]*>/g, "").replace(/<\/p>/g, ",");
  6. item = item.replace(",,", ",");
  7. newString = item.indexOf(",") == 0 ? item.substring(1) : item;
  8. newString = newString.slice(0, -1);
  9. } catch (error) { console.log("Error in removedPtagString : " + error ); }
  10. return newString;
  11. }
Using "DialogBox.tsx" component in parent.
Import "DialogBox.tsx" reusable component in your parent file as shown below.
Note
I have placed the DialoBox.tsx file under ReactDialogBox folder and hence the below path.
If you are not using Folder structure you can directly import the child component without giving the folder name.
  1. import DialogBox from './ReactDialogBox/DialogBox';
Declare the state variable in your parent state as shown below.
  1. export interface ISpFxRichTextEditorState {
  2. clicked: boolean;
  3. listName: string;
  4. dialogTitle: string;
  5. spanID: string;
  6. DialogId: string;
  7. standard:string;
  8. isValidArea:string;
  9. toolpriorityinput:string;
  10. Safety:string;
  11. }
Declare the props in your parent props as shown below.
  1. export interface ISpFxRichTextEditorProps {
  2. id?:string;
  3. value?:string;
  4. dialogOpen?:boolean;
  5. spanID?:string;
  6. listName?:string;
  7. standardText?:string;
  8. onUpdate?:any;
  9. standard?:string;
  10. }
In the parent constructor class, declare the below state variables
  1. constructor(props: ISpFxRichTextEditorProps, state: ISpFxRichTextEditorState) {
  2. super(props);
  3. this.state = {
  4. clicked: false,
  5. listName: "",
  6. dialogTitle: "",
  7. spanID: "",
  8. DialogId: "",
  9. standard:"",
  10. isValidArea:"",
  11. toolpriorityinput:"",
  12. Safety:""
  13. };
  14. }
Call the dialog box in your render method of parent component.
  1. public render(){
  2. return (
  3. <div>
  4. <div className="width3">
  5. <div className="modal-area">
  6. <div className="modal-heading">
  7. <span>
  8. <b>Type of Work</b>
  9. {/* <span className="mandatary">*</span> */}
  10. </span>
  11. <span
  12. className="add-area float-right document-icons-area "
  13. onClick={() =>
  14. this.handleClick(
  15. "TypeWork",
  16. "Select Type of Work",
  17. "spnTypeOfWork",
  18. "typeWorkDlgId"
  19. )
  20. }
  21. >
  22. <Icon
  23. iconName="CalculatorAddition"
  24. className="ms-IconExample"
  25. />
  26. <label>Add</label>
  27. </span>
  28. </div>
  29. <div className="modal-adding">
  30. <div id="spnTypeOfWork" />
  31. </div>
  32. <div className="modal-box">
  33. {this.state.clicked ? (
  34. <DialogBox
  35. id={this.state.DialogId}
  36. value={this.state.dialogTitle}
  37. dialogOpen={false}
  38. onUpdate={this.onUpdate}
  39. spHttpClient={this.props.spHttpClient}
  40. siteUrl={this.props.siteUrl}
  41. listName={this.state.listName}
  42. spanID={this.state.spanID}
  43. standardText={this.state.standard}
  44. />
  45. ) : null}
  46. </div>
  47. </div>
  48. </div>
  49. </div>
  50. );
  51. }
Handle click event as shown below.
  1. /* Open dialog on click event */
  2. private handleClick(
  3. listName: string,
  4. dialogTitle: string,
  5. spanID: string,
  6. DlgId: string
  7. ): void {
  8. this.setState({
  9. clicked: true,
  10. listName: listName,
  11. dialogTitle: dialogTitle,
  12. spanID: spanID,
  13. DialogId: DlgId
  14. });
  15. }
"onUpdate" function acts as call back from child component to parent component, which usually transfers the data from child to parent.
In the below function, I am storing the selected check box values in state variable named "Safety".
  1. /*Dialog on update function*/
  2. private onUpdate = dlgOutput => {
  3. try{
  4. this.setState({
  5. clicked: false
  6. });
  7. this.setState({Safety:$("#spnTypeOfWork").html()});
  8. }catch(error){
  9. console.log("Error in onUpdate function : " + error);
  10. }
  11. }
To replace <p> tag with semicolon use the below code.
Eg
Before - <p>Test</p><p>Sample</p>
After - Test;Sample;
  1. public ReplaceParaWithSemiColon(stringValue):string{
  2. try{
  3. if(stringValue !== ""){
  4. if(stringValue.indexOf('<p>') >-1 ){
  5. stringValue = stringValue.replace(/<p>/g, "").replace(/<\/p>/g,";");
  6. stringValue = stringValue.substr(0, stringValue.length - 1);
  7. }
  8. }
  9. return stringValue;
  10. }catch(error){
  11. console.log("Error in ReplaceParaWithSemiColon : " + error);
  12. }
  13. }
Complete code of a child component "DialogBox.tsx" is depicted below
  1. import * as React from 'react';
  2. import { ISpFxRichTextEditorProps } from '../ISpFxRichTextEditorProps';
  3. import { PrimaryButton, DefaultButton, DialogType, Dialog, DialogFooter, TextField, Label } from 'office-ui-fabric-react';
  4. import * as $ from "jquery";
  5. import { UrlQueryParameterCollection } from '@microsoft/sp-core-library';
  6. export interface IDialogState {
  7. hideDialog: boolean;
  8. spanID:string;
  9. dialogID: string;
  10. standard:string;
  11. isDraggable: boolean;
  12. typeOfWorkTemparr:any[];
  13. typeArr:any[];
  14. }
  15. /*Type of Work Array Global Declarations*/
  16. var typeofworkarr=[];
  17. var multiTypeOfWorkChkBox=[];
  18. export default class DialogBox extends React.Component<ISpFxRichTextEditorProps, any>
  19. {
  20. public constructor(props: ISpFxRichTextEditorProps) {
  21. super(props);
  22. this.HandleTypeOfArray=this.HandleTypeOfArray.bind(this);
  23. }
  24. public state: IDialogState = {
  25. hideDialog: this.props.dialogOpen,
  26. isDraggable: false,
  27. spanID: this.props.spanID,
  28. dialogID: this.props.id,
  29. standard:this.props.standard,
  30. typeOfWorkTemparr:[{
  31. name: 'Revision',
  32. key: 'Revision',
  33. label: 'Revision',
  34. isChecked: false
  35. },
  36. {
  37. name: 'Design',
  38. key: 'Design',
  39. label: 'Design',
  40. isChecked: false
  41. },
  42. {
  43. name: 'Maintainence',
  44. key: 'Maintainence',
  45. label: 'Maintainence',
  46. isChecked: false
  47. },
  48. {
  49. name: 'Scan Print',
  50. key: 'Scan Print',
  51. label: 'Scan Print',
  52. isChecked: false
  53. },
  54. {
  55. name: 'Locate Print',
  56. key: 'Locate Print',
  57. label: 'Locate Print',
  58. isChecked: false
  59. },
  60. {
  61. name: 'File Print On Drive',
  62. key: 'File Print On Drive',
  63. label: 'File Print On Drive',
  64. isChecked: false
  65. },
  66. {
  67. name: 'Plot/Print',
  68. key: 'Plot/Print',
  69. label: 'Plot/Print',
  70. isChecked: false
  71. }
  72. ],
  73. typeArr :[]
  74. };
  75. private labelId: string = getId('dialogLabel');
  76. private subTextId: string = getId('subTextLabel');
  77. public render() {
  78. const { hideDialog } = this.state;
  79. let inputchkbox;
  80. let inputcontrols;
  81. let selectBox;
  82. /* input control ends here*/
  83. if (this.state.spanID == "spnTypeOfWork") {
  84. inputchkbox = this.state.typeOfWorkTemparr.map((item, i) => {
  85. return (<Label key={item.key}>
  86. <input type="checkbox" ref={'ref_' + i} id={item.name} name={item.name} onChange={this.HandleTypeOfArray} value={item.name} checked={item.isChecked} />
  87. {item.name}
  88. </Label>)
  89. });
  90. }
  91. /* input control ends here*/
  92. /* select control starts here*/
  93. if(this.state.spanID == "spnTypeOfWork"){
  94. selectBox = <div>{inputchkbox}</div>;
  95. }
  96. /* select control ends here*/
  97. return (
  98. <div>
  99. <Dialog
  100. hidden={hideDialog}
  101. onDismiss={this.closeDialog}
  102. dialogContentProps={{
  103. type: DialogType.normal,
  104. title: this.props.value,
  105. subText: "",
  106. styles: { title: { backgroundColor: "blue", height: 10, marginBottom: 10, paddingBottom: 22 } }
  107. }}
  108. modalProps={{
  109. titleAriaId: this.labelId,
  110. subtitleAriaId: this.subTextId,
  111. isBlocking: false,
  112. styles: { main: { height: 350, width: 500 } },
  113. }}>
  114. {selectBox}
  115. <DialogFooter>
  116. <PrimaryButton onClick={this.saveDialog} text="Save" />
  117. <DefaultButton onClick={this.closeDialog} text="Cancel" />
  118. </DialogFooter>
  119. </Dialog>
  120. </div>
  121. );
  122. }
  123. /* Initiate load containers */
  124. public componentDidMount(): void {
  125. if(this.state.spanID == "spnTypeOfWork"){
  126. this.ReLoadTypeOfWorkContainer();
  127. }
  128. }
  129. /** Type of Area Selection Starts */
  130. /** Load Area container based on values */
  131. public ReLoadTypeOfWorkContainer() {
  132. try {
  133. let queryParms = new UrlQueryParameterCollection(window.location.href);
  134. let itemID: number = parseInt(queryParms.getValue("ListItemID"));
  135. if (itemID != null && itemID > 0) {
  136. /*Set Priority values on page load*/
  137. this.SetTypeofWorkOnLoad();
  138. } else {
  139. /*Reset Type of work values based on selection*/
  140. let typeofWorkArrValues = this.state.typeOfWorkTemparr
  141. $.each(multiTypeOfWorkChkBox, function (index, value) {
  142. typeofWorkArrValues = [];
  143. typeofWorkArrValues = value;
  144. });
  145. this.setState({ typeOfWorkTemparr: typeofWorkArrValues });
  146. }
  147. } catch (error) {
  148. console.log("Error in ReLoadTypeOfWorkContainer : " + error);
  149. }
  150. }
  151. /* Handle Type of Array section */
  152. public HandleTypeOfArray(event: any):void{
  153. try{
  154. if (event.target.checked == false) {
  155. for (var i = 0; i < typeofworkarr.length; i++) {
  156. if (typeofworkarr[i] === event.target.value) {
  157. typeofworkarr.splice(i, 1);
  158. }
  159. }
  160. }
  161. if (event.target.checked) {
  162. if (typeofworkarr.indexOf(event.target.value) == -1) {
  163. typeofworkarr.push(event.target.value)
  164. }
  165. }
  166. else {
  167. for (var i = 0; i < typeofworkarr.length; i++) {
  168. if (typeofworkarr[i] === event.target.value) {
  169. typeofworkarr.splice(i, 1);
  170. }
  171. }
  172. }
  173. let typeofworkArr = this.state.typeOfWorkTemparr
  174. typeofworkArr.forEach(types => {
  175. if (types.name === event.target.value) {
  176. types.isChecked = event.target.checked
  177. }
  178. })
  179. multiTypeOfWorkChkBox.push(typeofworkArr);
  180. this.setState({ typeOfWorkTemparr: typeofworkArr });
  181. }catch(error){
  182. console.log("Error in HandleTypeOfArray : " + error);
  183. }
  184. }
  185. /** Type of Area Ends */
  186. /*Close dialog window*/
  187. private closeDialog = (): void => {
  188. this.setState({ hideDialog: true });
  189. this.props.onUpdate();
  190. }
  191. /*Save operation based on span id selection*/
  192. private saveDialog = (): void => {
  193. if(this.state.spanID == "spnTypeOfWork"){
  194. this.SaveTypeOfWork();
  195. }
  196. }
  197. /*save proirity on save button click */
  198. private SaveTypeOfWork(){
  199. try {
  200. let queryParms = new UrlQueryParameterCollection(window.location.href);
  201. let itemID: number = parseInt(queryParms.getValue("ListItemID"));
  202. if (itemID != null && itemID > 0) {
  203. typeofworkarr = [];
  204. let prioritArrValues = this.state.typeOfWorkTemparr
  205. $.each(prioritArrValues, function (index, item) {
  206. if (item.isChecked == true) {
  207. typeofworkarr.push(item.name);
  208. }
  209. });
  210. }
  211. let tempvariable: string = '';
  212. typeofworkarr.forEach(element => {
  213. tempvariable = tempvariable + "<p>" + element + "</p>";
  214. });
  215. var txtValue = tempvariable.indexOf(',') == 0 ? tempvariable.substr(1) : tempvariable;
  216. $("#" + this.state.spanID).html(txtValue);
  217. this.setState({ hideDialog: true });
  218. this.props.onUpdate(this.props.value);
  219. } catch (error) {
  220. console.log("Error in SaveTypeOfWork" + error);
  221. }
  222. }
  223. /*Other Functions*/
  224. /*Remove p tag from html string */
  225. private RemovedPtagString(removedPString): string {
  226. let newString;
  227. try {
  228. let item = removedPString.replace(/<p[^>]*>/g, "").replace(/<\/p>/g, ",");
  229. item = item.replace(",,", ",");
  230. newString = item.indexOf(",") == 0 ? item.substring(1) : item;
  231. newString = newString.slice(0, -1);
  232. } catch (error) { console.log("Error in removedPtagString : " + error ); }
  233. return newString;
  234. }
  235. /**Set Type of work on Load */
  236. private SetTypeofWorkOnLoad(): void {
  237. try {
  238. var finalArray=[];
  239. if ($("#" + this.state.spanID).html() !== "") {
  240. var htmlstring = this.RemovedPtagString($("#" + this.state.spanID).html()).split(',');
  241. var tempPriorArr = htmlstring;
  242. let prioritArrValues = this.state.typeOfWorkTemparr
  243. $.each(prioritArrValues, function (index, item) {
  244. if (tempPriorArr.indexOf(item.name) > -1) {
  245. item.isChecked = true;
  246. }
  247. });
  248. this.setState({ typeOfWorkTemparr: prioritArrValues });
  249. }
  250. } catch (error) {
  251. console.log("Error in SetTypeofWorkOnLoad : " + error);
  252. }
  253. }
  254. }
Complete code of a parent component "Parent.tsx" is depicted below,
  1. import * as React from 'react';
  2. import { ISpFxRichTextEditorProps } from './ISpFxRichTextEditorProps';
  3. import { ISpFxRichTextEditorState } from './ISpFxRichTextEditorState';
  4. import { UrlQueryParameterCollection } from '@microsoft/sp-core-library';
  5. import { css, DefaultButton, IButtonProps, IStyle, Label, PrimaryButton, DialogType, Dialog, DialogFooter, format, Icon, TextField } from 'office-ui-fabric-react';
  6. import DialogBox from './ReactDialogBox/DialogBox';
  7. export default class SpFxRichTextEditor extends React.Component<ISpFxRichTextEditorProps, ISpFxRichTextEditorState> {
  8. constructor(props: ISpFxRichTextEditorProps, state: ISpFxRichTextEditorState) {
  9. super(props);
  10. this.state = {
  11. clicked: false,
  12. listName: "",
  13. dialogTitle: "",
  14. spanID: "",
  15. DialogId: "",
  16. standard:"",
  17. isValidArea:"",
  18. toolpriorityinput:"",
  19. Safety:""
  20. };
  21. }
  22. /* Open dialog on click event */
  23. private handleClick(
  24. listName: string,
  25. dialogTitle: string,
  26. spanID: string,
  27. DlgId: string
  28. ): void {
  29. this.setState({
  30. clicked: true,
  31. listName: listName,
  32. dialogTitle: dialogTitle,
  33. spanID: spanID,
  34. DialogId: DlgId
  35. });
  36. }
  37. public render(){
  38. return (
  39. <div>
  40. <div className="width3">
  41. <div className="modal-area">
  42. <div className="modal-heading">
  43. <span>
  44. <b>Type of Work</b>
  45. {/* <span className="mandatary">*</span> */}
  46. </span>
  47. <span
  48. className="add-area float-right document-icons-area "
  49. onClick={() =>
  50. this.handleClick(
  51. "TypeWork",
  52. "Select Type of Work",
  53. "spnTypeOfWork",
  54. "typeWorkDlgId"
  55. )
  56. }
  57. >
  58. <Icon
  59. iconName="CalculatorAddition"
  60. className="ms-IconExample"
  61. />
  62. <label>Add</label>
  63. </span>
  64. </div>
  65. <div className="modal-adding">
  66. <div id="spnTypeOfWork" />
  67. </div>
  68. <div className="modal-box">
  69. {this.state.clicked ? (
  70. <DialogBox
  71. id={this.state.DialogId}
  72. value={this.state.dialogTitle}
  73. dialogOpen={false}
  74. onUpdate={this.onUpdate}
  75. spHttpClient={this.props.spHttpClient}
  76. siteUrl={this.props.siteUrl}
  77. listName={this.state.listName}
  78. spanID={this.state.spanID}
  79. standardText={this.state.standard}
  80. />
  81. ) : null}
  82. </div>
  83. </div>
  84. </div>
  85. </div>
  86. );
  87. }
  88. /*Dialog on update function*/
  89. private onUpdate = dlgOutput => {
  90. try{
  91. this.setState({
  92. clicked: false
  93. });
  94. this.setState({Safety:$("#spnTypeOfWork").html()});
  95. }catch(error){
  96. console.log("Error in onUpdate function : " + error);
  97. }
  98. }
  99. /*Replace semicolon with paragraph */
  100. public ReplaceSemiColon(stringValue):string{
  101. try{
  102. var htmlString='';
  103. var temp = [];
  104. if(stringValue !== ""){
  105. if(stringValue.indexOf(';') > -1){
  106. temp = stringValue.split(';')
  107. $.each(temp,function(index,value){
  108. htmlString = htmlString + "<p>" + value + "</p>"
  109. });
  110. }
  111. }
  112. return htmlString;
  113. }catch(error){
  114. console.log("Error in ReplaceSemiColon : " + error);
  115. }
  116. }
  117. /*Replace paragraph with semicolon */
  118. public ReplaceParaWithSemiColon(stringValue):string{
  119. try{
  120. if(stringValue !== ""){
  121. if(stringValue.indexOf('<p>') >-1 ){
  122. stringValue = stringValue.replace(/<p>/g, "").replace(/<\/p>/g,";");
  123. stringValue = stringValue.substr(0, stringValue.length - 1);
  124. }
  125. }
  126. return stringValue;
  127. }catch(error){
  128. console.log("Error in ReplaceParaWithSemiColon : " + error);
  129. }
  130. }
  131. }
Below are the sample styles used to create a multi selection check box.
CSS
  1. .ms-Dialog-header .ms-Dialog-title {
  2. background-color:#da291c;
  3. color: #fff;
  4. padding: 8px;
  5. height: 40px;
  6. box-sizing: border-box;
  7. line-height: 1;
  8. font-weight: bold;
  9. font-size: 20px;
  10. }
  11. .ms-Dialog-header .ms-Button {
  12. color: #fff;
  13. position: relative;
  14. top: -6px;
  15. float: right;
  16. right: 0px;
  17. min-width:0em;
  18. }
  19. .ms-Dialog-header .ms-Button:hover,.ms-Dialog-header .ms-Button:active, .ms-Dialog-header .ms-Button:focus {
  20. background: none !important;
  21. }
  22. .ms-Dialog-header {
  23. margin-right: 40px;
  24. }
  25. .modal-heading {
  26. border: 1px solid #ccc;
  27. padding: 10px;
  28. background: #f1f1f1;
  29. }
  30. .modal-adding {
  31. border: 1px solid #ccc;
  32. background: #fff;
  33. padding: 10px;
  34. min-height: 100px;
  35. }
  36. .ms-Button-flexContainer {
  37. float: left;
  38. }
Output
Please feel free to share your comments.
I hope this helps!!!!!