Few changes to make webpart configurable

This commit is contained in:
Siddharth 2019-10-10 01:12:09 +05:30
parent d130360b33
commit b484d85206
11 changed files with 3263 additions and 936 deletions

View File

@ -2,7 +2,8 @@
## Summary ## Summary
This is sample webpart which showcase how to implement Google reCaptcha v2 in SPFx. CAPTCHA is used to prevent bots from automatically submitting forms with SPAM or other unwanted content. This is sample webpart which showcase how to implement Google reCaptcha v2 in SPFx. CAPTCHA is used to prevent bots from automatically submitting forms with SPAM or other unwanted content. If we are building a custom input form to get feedback, newsletter subscription or contact us form using SPFx webpart. We might have to implement SPAM protection using some CAPTCHA resolving technique. This sample can come in handy to extend it for your
business requirement if you need to implement CAPTCHA in SPFx webpart.
* Please refer this [link](https://www.c-sharpcorner.com/article/google-recaptcha-in-sharepoint-framework-webpartspfx/) to know 'How to build this from Scratch' * Please refer this [link](https://www.c-sharpcorner.com/article/google-recaptcha-in-sharepoint-framework-webpartspfx/) to know 'How to build this from Scratch'
@ -47,7 +48,8 @@ react-recaptcha | Siddharth Vaghasia([siddh_me](https://twitter.com/siddh_me/))
Version|Date|Comments Version|Date|Comments
-------|----|-------- -------|----|--------
1.0.0|Sept 26, 2019|Initial release 1.0.0|Oct 10, 2019|Implemented few changes
1.0.0|Oct 08, 2019|Initial release
## Disclaimer ## Disclaimer
@ -68,6 +70,7 @@ Version|Date|Comments
This Web Part illustrates the following concepts on top of the SharePoint Framework: This Web Part illustrates the following concepts on top of the SharePoint Framework:
* Using react framework in SPFx webpart * Using react framework in SPFx webpart
* Using [PnP Placeholder control](https://sharepoint.github.io/sp-dev-fx-controls-react/controls/Placeholder/) to configure webpart.
* Using [react-google-recaptcha](https://github.com/dozoisch/react-google-recaptcha) npm package in SPFx webpart * Using [react-google-recaptcha](https://github.com/dozoisch/react-google-recaptcha) npm package in SPFx webpart
* Validate if captcha is resolved before submiting data. * Validate if captcha is resolved before submiting data.

View File

@ -13,6 +13,7 @@
}, },
"externals": {}, "externals": {},
"localizedResources": { "localizedResources": {
"RecaptchaWebPartStrings": "lib/webparts/recaptcha/loc/{locale}.js" "RecaptchaWebPartStrings": "lib/webparts/recaptcha/loc/{locale}.js",
"ControlStrings": "node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js"
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -11,34 +11,35 @@
"test": "gulp test" "test": "gulp test"
}, },
"dependencies": { "dependencies": {
"@microsoft/sp-core-library": "1.8.2", "@microsoft/sp-core-library": "1.9.1",
"@microsoft/sp-lodash-subset": "1.8.2", "@microsoft/sp-lodash-subset": "1.9.1",
"@microsoft/sp-office-ui-fabric-core": "1.8.2", "@microsoft/sp-office-ui-fabric-core": "1.9.1",
"@microsoft/sp-property-pane": "1.8.2", "@microsoft/sp-property-pane": "1.9.1",
"@microsoft/sp-webpart-base": "1.8.2", "@microsoft/sp-webpart-base": "1.9.1",
"@pnp/spfx-controls-react": "1.14.0",
"@types/es6-promise": "0.0.33", "@types/es6-promise": "0.0.33",
"@types/react": "16.7.22", "@types/react": "16.8.8",
"@types/react-dom": "16.8.0", "@types/react-dom": "16.8.3",
"@types/react-google-recaptcha": "^1.1.0", "@types/react-google-recaptcha": "^1.1.0",
"@types/webpack-env": "1.13.1", "@types/webpack-env": "1.13.1",
"office-ui-fabric-react": "6.143.0", "office-ui-fabric-react": "6.189.2",
"react": "16.7.0", "react": "16.8.5",
"react-async-script": "^1.1.1", "react-async-script": "^1.1.1",
"react-dom": "16.7.0", "react-dom": "16.8.5",
"react-google-recaptcha": "^2.0.1" "react-google-recaptcha": "^2.0.1"
}, },
"resolutions": { "resolutions": {
"@types/react": "16.7.22" "@types/react": "16.8.8"
}, },
"devDependencies": { "devDependencies": {
"@microsoft/sp-build-web": "1.8.2", "@microsoft/rush-stack-compiler-2.9": "0.7.16",
"@microsoft/sp-tslint-rules": "1.8.2", "@microsoft/sp-build-web": "1.9.1",
"@microsoft/sp-module-interfaces": "1.8.2", "@microsoft/sp-module-interfaces": "1.9.1",
"@microsoft/sp-webpart-workbench": "1.8.2", "@microsoft/sp-tslint-rules": "1.9.1",
"@microsoft/rush-stack-compiler-2.9": "0.7.7", "@microsoft/sp-webpart-workbench": "1.9.1",
"gulp": "~3.9.1",
"@types/chai": "3.4.34", "@types/chai": "3.4.34",
"@types/mocha": "2.2.38", "@types/mocha": "2.2.38",
"ajv": "~5.2.2" "ajv": "~5.2.2",
"gulp": "~3.9.1"
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 KiB

After

Width:  |  Height:  |  Size: 454 KiB

View File

@ -21,7 +21,7 @@
"description": { "default": "This is sample webpart to showcase usage of reCaptcha in spfx webpart" }, "description": { "default": "This is sample webpart to showcase usage of reCaptcha in spfx webpart" },
"officeFabricIconFontName": "Page", "officeFabricIconFontName": "Page",
"properties": { "properties": {
"description": "recaptcha" "sitekey": ""
} }
}] }]
} }

View File

@ -10,9 +10,11 @@ import {
import * as strings from 'RecaptchaWebPartStrings'; import * as strings from 'RecaptchaWebPartStrings';
import Recaptcha from './components/Recaptcha'; import Recaptcha from './components/Recaptcha';
import { IRecaptchaProps } from './components/IRecaptchaProps'; import { IRecaptchaProps } from './components/IRecaptchaProps';
import { WebPartContext } from '@microsoft/sp-webpart-base';
export interface IRecaptchaWebPartProps { export interface IRecaptchaWebPartProps {
description: string; sitekey: string;
} }
export default class RecaptchaWebPart extends BaseClientSideWebPart<IRecaptchaWebPartProps> { export default class RecaptchaWebPart extends BaseClientSideWebPart<IRecaptchaWebPartProps> {
@ -21,7 +23,9 @@ export default class RecaptchaWebPart extends BaseClientSideWebPart<IRecaptchaWe
const element: React.ReactElement<IRecaptchaProps > = React.createElement( const element: React.ReactElement<IRecaptchaProps > = React.createElement(
Recaptcha, Recaptcha,
{ {
description: this.properties.description sitekey: this.properties.sitekey,
displayMode: this.displayMode,
context: this.context
} }
); );
@ -47,8 +51,8 @@ export default class RecaptchaWebPart extends BaseClientSideWebPart<IRecaptchaWe
{ {
groupName: strings.BasicGroupName, groupName: strings.BasicGroupName,
groupFields: [ groupFields: [
PropertyPaneTextField('description', { PropertyPaneTextField('sitekey', {
label: strings.DescriptionFieldLabel label: strings.SiteKeyFieldLabel
}) })
] ]
} }

View File

@ -1,3 +1,8 @@
import { WebPartContext } from '@microsoft/sp-webpart-base';
import { DisplayMode } from '@microsoft/sp-core-library';
export interface IRecaptchaProps { export interface IRecaptchaProps {
description: string; sitekey: string;
displayMode: DisplayMode;
context: WebPartContext;
} }

View File

@ -5,7 +5,9 @@ import { escape } from '@microsoft/sp-lodash-subset';
import ReCAPTCHA from 'react-google-recaptcha'; import ReCAPTCHA from 'react-google-recaptcha';
import * as ReactDom from 'react-dom'; import * as ReactDom from 'react-dom';
import { TextField, MaskedTextField,PrimaryButton,MessageBar, MessageBarType } from 'office-ui-fabric-react'; import { TextField, MaskedTextField,PrimaryButton,MessageBar, MessageBarType } from 'office-ui-fabric-react';
import { Placeholder } from "@pnp/spfx-controls-react/lib/Placeholder"
import { DisplayMode } from '@microsoft/sp-core-library';
import * as strings from 'RecaptchaWebPartStrings';
export default class Recaptcha extends React.Component<IRecaptchaProps, {}> { export default class Recaptcha extends React.Component<IRecaptchaProps, {}> {
@ -14,23 +16,45 @@ export default class Recaptcha extends React.Component<IRecaptchaProps, {}> {
public render(): React.ReactElement<IRecaptchaProps> { public render(): React.ReactElement<IRecaptchaProps> {
return ( return (
<div className={ styles.recaptcha }> <div className={ styles.recaptcha }>
{/* Show Placeholder control, when description web part property is not set */}
{this.props.sitekey == "" &&
<Placeholder iconName='Edit'
iconText='Configure your web part'
description='Please configure the web part.'
buttonLabel='Configure'
hideButton={this.props.displayMode === DisplayMode.Read}
onConfigure={() => this._onConfigure()} />
}
{/* Show description web part property, when set */}
{this.props.sitekey &&
<div>
<p> <p>
<TextField label="Enter your name" styles={{ fieldGroup: { width: 300 } }} /> <TextField label="Enter your name" styles={{ fieldGroup: { width: 300 } }} />
</p> </p>
<ReCAPTCHA ref={ (el) => { this.captcha = el; } } <ReCAPTCHA ref={ (el) => { this.captcha = el; } }
sitekey="6LeZV7oUAAAAALiIfCUnnrlXE0fYrcyvM9JHVN72" sitekey={escape(this.props.sitekey)}
onChange={this.onChange} /> onChange={this.onChange} />
<p> <p>
<div id="messageContainer" ref={(elm) => { this._messageContainer = elm; }}> <p ref={(elm) => { this._messageContainer = elm; }}>
</div> </p>
</p> </p>
<PrimaryButton text="Submit" onClick={() => this.buttonClicked()} /> <PrimaryButton text={strings.SubmitButtonLabel} onClick={() => this.buttonClicked()} />
</div>
}
</div> </div>
); );
} }
private _onConfigure() {
// Context of the web part
this.props.context.propertyPane.open();
}
public buttonClicked(): void { public buttonClicked(): void {
if(this.captcha.getValue()) if(this.captcha.getValue())
{ {

View File

@ -1,7 +1,8 @@
define([], function() { define([], function() {
return { return {
"PropertyPaneDescription": "Description", "PropertyPaneDescription": "Please enter Site key to use reCaptcha",
"BasicGroupName": "Group Name", "BasicGroupName": "Basic",
"DescriptionFieldLabel": "Description Field" "SiteKeyFieldLabel": "Site Key",
"SubmitButtonLabel" : "Submit"
} }
}); });

View File

@ -1,7 +1,8 @@
declare interface IRecaptchaWebPartStrings { declare interface IRecaptchaWebPartStrings {
PropertyPaneDescription: string; PropertyPaneDescription: string;
BasicGroupName: string; BasicGroupName: string;
DescriptionFieldLabel: string; SiteKeyFieldLabel: string;
SubmitButtonLabel:string;
} }
declare module 'RecaptchaWebPartStrings' { declare module 'RecaptchaWebPartStrings' {