Forum Discussion

john john's avatar
john john
Steel Contributor
Nov 06, 2021

SPFX web part to add Text and show it inside a Popup when clicking on a button

I am trying to achieve this using SPFX web part:-

  1. The web part will render a Button and has a text field inside its settings.

  2. The user add the Web Part >> edit it >> enter the text inside the text field (inside the setting page) >> save the web part>> then the web part will render a button >> if the user clicks on the button a Popup will be shown with the entered text.

Now i found this link @ https://www.c-sharpcorner.com/article/modal-popup-in-spfx/ which almost achieve what i am looking for, except that the Popup text inside the example is been hard-coded inside the .tsx file.. so what are the steps to make the Popup text configurable inside the web part settings instead of been hard-coded?

Thanks

 

 

 

Here is my `ReactPortalWebPart.ts` file:-

 

import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import {
IPropertyPaneConfiguration,
PropertyPaneTextField
} from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';

import * as strings from 'ReactPortalWebPartStrings';
import ReactPortal from './components/ReactPortal';
import { IReactPortalProps } from './components/IReactPortalProps';

export interface IReactPortalWebPartProps {
description: string;
}

export default class ReactPortalWebPart extends BaseClientSideWebPart<IReactPortalWebPartProps> {

public render(): void {
const element: React.ReactElement<IReactPortalProps> = React.createElement(
ReactPortal,
{
description: this.properties.description
}
);

ReactDom.render(element, this.domElement);
}

protected onDispose(): void {
ReactDom.unmountComponentAtNode(this.domElement);
}

protected get dataVersion(): Version {
return Version.parse('1.0');
}

protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription
},
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneTextField('description', {
label: strings.DescriptionFieldLabel
})
]
}
]
}
]
};
}
}

 


and here is the `ReactPortal.tsx`:-

 

import * as React from 'react';
import { IReactPortalProps } from './IReactPortalProps';
import Myportal from "./Myportal";
export default class ReactPortal extends React.Component<IReactPortalProps, {}> {
public render(): React.ReactElement<IReactPortalProps> {
return (
<div >
<Myportal/>
</div>
);
}
}

 

Here is the `Myportal.tsx`:-

 

 

import* as React from "react";
import usePortal from "react-cool-portal";
import "./mystyle.scss";
const Myportal = () => {
// const { Portal } = usePortal({ containerId: "my-portal-root" });
const { Portal, show, hide } = usePortal({ defaultShow: false,containerId:"my-portal-root" });
const handleClickBackdrop = (e: React.MouseEvent) => {
const { id } = e.target as HTMLDivElement;
if (id === "modal") hide();
};

return (
<div className="App">

<button className="btn" onClick={show} type="button">
Who we are
</button>
&nbsp; &nbsp; &nbsp;
<button className="btn" onClick={show} type="button">
Our value
</button>
<Portal>
<div
id="modal"
className="modal"
onClick={handleClickBackdrop}
tabIndex={-1}
>
<div
className="modal-dialog"
role="dialog"
aria-labelledby="modal-label"
aria-modal="true"
>
<div className="modal-header">

<button
className="modal-close"
onClick={hide}
type="button"
aria-label="Close"
>
<span aria-hidden="true">×</span>
</button>
</div>
<div className="modal-body">
<h1> Who we are</h1>
<h3>.................................................</h3>
Our overriding purpose is to dramatically improve the reliability, efficiency........
</div>
</div>
</div>
</Portal>
</div>

);
};
export default Myportal;

 

  • john john 

    You need to pass the text to display variable (which looks like the description property in the property panel) into the MyPortal React element.  It is already being passed into the ReactPortal React component as part of the IReactPortalProps object, so you just need to pass that through to MyPortal as an attribute.

     

    First, change line 4 in MyPortal.tsx to 

     

    const Myportal = (textToDisplay: string) => {

     

     

    To use the parameter, place it in the return object. It looks like you want to replace line 49 in MyPortal.tsx with

     

    {textToDisplay}

     

     

    To pass the description property into MyPortal, replace line 8 in ReactPortal.tsx with 

     

    <Myportal textToDisplay={props.description}/>

     

     

    I hope this help show how to pass properties into React function components. If this helps, please consider marking this as the approved solution.

     

    Good luck,

    Don Kirkham

  • john john 

    You need to pass the text to display variable (which looks like the description property in the property panel) into the MyPortal React element.  It is already being passed into the ReactPortal React component as part of the IReactPortalProps object, so you just need to pass that through to MyPortal as an attribute.

     

    First, change line 4 in MyPortal.tsx to 

     

    const Myportal = (textToDisplay: string) => {

     

     

    To use the parameter, place it in the return object. It looks like you want to replace line 49 in MyPortal.tsx with

     

    {textToDisplay}

     

     

    To pass the description property into MyPortal, replace line 8 in ReactPortal.tsx with 

     

    <Myportal textToDisplay={props.description}/>

     

     

    I hope this help show how to pass properties into React function components. If this helps, please consider marking this as the approved solution.

     

    Good luck,

    Don Kirkham

    • john john's avatar
      john john
      Steel Contributor

      Don Kirkhamok thanks a lot for the help.. but how i can show the Description field as Multi-line of text that accept HTML code? or if i can render it as Rich Text Editor? as i need the text inside the Popup to be rich text rather than been just a text-only.. can i achieve this?

      • Don Kirkham's avatar
        Don Kirkham
        MVP
        This can be done, but it is well beyond the scope of your original question.

        I recommend that you look at the samples available in Microsoft PnP. There is a Rich Text control that could display your text, but editing it in a popup is not easy. There is not a Rich Text Property Pane control, but it is possible to create a custom control with a popup that has the Rich Text control in it, for editing.

        PnP is a great source for all kinds of samples and code to shortcut the developer experience, so I recommend going through as much of it as you can. (Including a lot of instructional videos.)

        Best of luck,
        Don

Resources