From fd5b2c854f27dbdcd1846a519b9ebe1d52389519 Mon Sep 17 00:00:00 2001 From: denniskuhn Date: Thu, 22 Jul 2021 18:07:06 +1200 Subject: [PATCH 1/3] Added onNewTerm called when enter is pressed --- .../taxonomyPicker/ITaxonomyPicker.ts | 7 ++- .../taxonomyPicker/TaxonomyPicker.tsx | 57 ++++++++++++++++--- src/controls/taxonomyPicker/TermPicker.tsx | 38 +++++++++++-- 3 files changed, 90 insertions(+), 12 deletions(-) diff --git a/src/controls/taxonomyPicker/ITaxonomyPicker.ts b/src/controls/taxonomyPicker/ITaxonomyPicker.ts index fe1da4b46..0f99bfb46 100644 --- a/src/controls/taxonomyPicker/ITaxonomyPicker.ts +++ b/src/controls/taxonomyPicker/ITaxonomyPicker.ts @@ -1,4 +1,4 @@ -import { IPickerTerms } from './ITermPicker'; +import { IPickerTerm, IPickerTerms } from './ITermPicker'; import { ITermSet, ITerm } from '../../services/ISPTermStorePickerService'; import { ITermActions } from './termActions/ITermsActions'; import SPTermStorePickerService from '../../services/SPTermStorePickerService'; @@ -104,6 +104,11 @@ export interface ITaxonomyPickerProps { */ onGetErrorMessage?: (value: IPickerTerms) => string | Promise; + /** + * Called when text is in the input field and the enter key is pressed. + */ + onNewTerm?: (value: IPickerTerm) => void; + /** * Static error message displayed below the text field. Use onGetErrorMessage to dynamically change the error message displayed (if any) based on the current value. errorMessage and onGetErrorMessage are mutually exclusive (errorMessage takes precedence). */ diff --git a/src/controls/taxonomyPicker/TaxonomyPicker.tsx b/src/controls/taxonomyPicker/TaxonomyPicker.tsx index c179271fc..cc34535a2 100644 --- a/src/controls/taxonomyPicker/TaxonomyPicker.tsx +++ b/src/controls/taxonomyPicker/TaxonomyPicker.tsx @@ -17,6 +17,7 @@ import TermParent from './TermParent'; import FieldErrorMessage from '../errorMessage/ErrorMessage'; import { initializeIcons } from '@uifabric/icons'; import * as telemetry from '../../common/telemetry'; +import { EmptyGuid } from '../../common/Constants'; /** * Image URLs / Base64 @@ -363,22 +364,63 @@ export class TaxonomyPicker extends React.Component { + const errorMessage = await this.props.onGetErrorMessage( + [ + { + key: EmptyGuid, + name: targetValue, + path: targetValue, + termSet: this.termsService.cleanGuid(this.props.termsetNameOrID) + } + ] + ); + + if (!!errorMessage) { + this.setState({ + errorMessage: errorMessage + }); + } + else { + this.setState({ + errorMessage: null + }); + } + return !errorMessage; + } + + private onNewTerm = (newLabel: string) => { + this.props.onNewTerm( + { + key: EmptyGuid, + name: newLabel, + path: newLabel, + termSet: this.termsService.cleanGuid(this.props.termsetNameOrID) + } + ); + } + /** * Triggers when taxonomy picker control loses focus */ - private onBlur(event: React.FocusEvent): void { + private async onBlur(event: React.FocusEvent): Promise { const { validateInput } = this.props; if (!!validateInput) { // Perform validation of input text, only if taxonomy picker is configured with validateInput={true} property. const target: HTMLInputElement = event.target as HTMLInputElement; const targetValue = !!target ? target.value : null; - if (!!targetValue) { - this.invalidTerm = targetValue; - } - else { - this.invalidTerm = null; + + if(!!this.props.onGetErrorMessage && !!targetValue) { + await this.validateOnGetErrorMessage(targetValue); + } else { + if (!!targetValue) { + this.invalidTerm = targetValue; + } + else { + this.invalidTerm = null; + } + this.validateInputText(); } - this.validateInputText(); } } @@ -534,6 +576,7 @@ export class TaxonomyPicker extends React.Component> { @@ -17,6 +18,7 @@ export class TermBasePicker extends BasePicker & LegacyRef; } export interface ITermPickerProps { @@ -30,6 +32,8 @@ export interface ITermPickerProps { disableChildrenOfDisabledParents?: boolean; placeholder?: string; + /** Called when text is in the input field and the enter key is pressed. */ + onNewTerm?: (newLabel: string) => void; onChanged: (items: IPickerTerm[]) => void; onInputChange: (input: string) => string; onBlur: (ev: React.FocusEvent) => void; @@ -201,6 +205,7 @@ export default class TermPicker extends React.Component { + const picker = this.state.elRef as unknown as TermBasePicker; + const autoFill = picker?.['input']?.current as Autofill; + if (autoFill) { + autoFill['_value'] = ''; + autoFill.setState({ displayValue: '' }); + } else { + throw new Error(`TermPicker.TermBasePicker.render.clearDisplayValue no autoFill to reset displayValue`); + } + }; + + const inputProps: IInputProps = { placeholder: placeholder }; + + if(onNewTerm) { + inputProps.onKeyDown = (e: KeyboardEvent) => { + if (e && e.key === 'Enter' && (! (e.ctrlKey || e.altKey || e.shiftKey)) && e.target?.['value'] ) { + onNewTerm(e.target['value']); + clearDisplayValue(); + } + }; + } + return (
{ + if (!this.state.elRef) { + this.setState({ elRef }); + } + }} disabled={disabled} onResolveSuggestions={this.onFilterChanged} onRenderSuggestionsItem={this.onRenderSuggestionsItem} @@ -224,9 +256,7 @@ export default class TermPicker extends React.Component
); From 1d51934ac447dee8f27dbfc4d7d501151809fcbd Mon Sep 17 00:00:00 2001 From: denniskuhn Date: Fri, 23 Jul 2021 17:18:12 +1200 Subject: [PATCH 2/3] Add TaxonomyPicker onNewTerm to the documentation --- .../docs/controls/TaxonomyPicker.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/documentation/docs/controls/TaxonomyPicker.md b/docs/documentation/docs/controls/TaxonomyPicker.md index 369cb25b3..9bcdf1181 100644 --- a/docs/documentation/docs/controls/TaxonomyPicker.md +++ b/docs/documentation/docs/controls/TaxonomyPicker.md @@ -51,6 +51,21 @@ private onTaxPickerChange(terms : IPickerTerms) { } ``` +- With the `onNewTerm` property you can capture the event, when text is in the input field and +enter/return as pressed. With a controlled TaxonomyPicker, this enables you to create the term +and have the same flow as in SharePoint Keywords fields. + +```typescript + const onNewTerm = (value: IPickerTerm): void => { + if(value?.name && EmptyGuid === value.key ){ + console.log(`TaxonmyPicker.onNewTerm name=${value.name}`, value ); + // Create keyword + } else { + console.error(`TaxonmyPicker.onNewTerm name=${value?.name}`, value ); + } + }; +``` + ## Term actions Since version `1.12.0`, you can apply term actions to all terms or specific ones. Term actions could for instance be used to retrieve the labels of the term, or retrieve other information. These term actions can be implemented as follows: @@ -158,6 +173,7 @@ The TaxonomyPicker control can be configured with the following properties: | allowMultipleSelections | boolean | no | Defines if the user can select only one or many term sets. Default value is false. | | termsetNameOrID | string | yes | The name or Id of your TermSet that you would like the Taxonomy Picker to chose terms from. | | onChange | function | no | captures the event of when the terms in the picker has changed. | +| onNewTerm | function | no | captures the event when text is in the input field and the user presses return | | isTermSetSelectable | boolean | no | Specify if the TermSet itself is selectable in the tree view. | | disabledTermIds | string[] | no | Specify which terms should be disabled in the term set so that they cannot be selected. | | disableChildrenOfDisabledParents | boolean | no | Specify if you want to disable the child terms when their parent is disabled. | From d98e83bc768f6c46a0a886de450f9ac79ee8b1d5 Mon Sep 17 00:00:00 2001 From: Joel Rodrigues <19577724+joelfmrodrigues@users.noreply.github.com> Date: Tue, 27 Jul 2021 22:57:27 +0100 Subject: [PATCH 3/3] Update TaxonomyPicker.md --- docs/documentation/docs/controls/TaxonomyPicker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/documentation/docs/controls/TaxonomyPicker.md b/docs/documentation/docs/controls/TaxonomyPicker.md index 9bcdf1181..400c1ff3f 100644 --- a/docs/documentation/docs/controls/TaxonomyPicker.md +++ b/docs/documentation/docs/controls/TaxonomyPicker.md @@ -52,7 +52,7 @@ private onTaxPickerChange(terms : IPickerTerms) { ``` - With the `onNewTerm` property you can capture the event, when text is in the input field and -enter/return as pressed. With a controlled TaxonomyPicker, this enables you to create the term +enter/return is pressed. With a controlled TaxonomyPicker, this enables you to create the term and have the same flow as in SharePoint Keywords fields. ```typescript