1
1
import * as React from 'react' ;
2
2
import { PrimaryButton , DefaultButton , IconButton } from 'office-ui-fabric-react/lib/Button' ;
3
3
import { Panel , PanelType } from 'office-ui-fabric-react/lib/Panel' ;
4
+ import { Autofill } from 'office-ui-fabric-react/lib/components/Autofill/Autofill' ;
4
5
import { Spinner , SpinnerType } from 'office-ui-fabric-react/lib/Spinner' ;
5
6
import { Label } from 'office-ui-fabric-react/lib/Label' ;
6
7
import TermPicker from './TermPicker' ;
@@ -32,6 +33,7 @@ export const TERM_IMG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQC
32
33
export class TaxonomyPicker extends React . Component < ITaxonomyPickerProps , ITaxonomyPickerState > {
33
34
private termsService : SPTermStorePickerService ;
34
35
private previousValues : IPickerTerms = [ ] ;
36
+ private invalidTerm : string = null ;
35
37
private cancel : boolean = true ;
36
38
37
39
/**
@@ -55,6 +57,9 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
55
57
this . onSave = this . onSave . bind ( this ) ;
56
58
this . termsChanged = this . termsChanged . bind ( this ) ;
57
59
this . termsFromPickerChanged = this . termsFromPickerChanged . bind ( this ) ;
60
+ this . onInputChange = this . onInputChange . bind ( this ) ;
61
+ this . onBlur = this . onBlur . bind ( this ) ;
62
+
58
63
this . termsService = new SPTermStorePickerService ( this . props , this . props . context ) ;
59
64
}
60
65
@@ -101,7 +106,6 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
101
106
* it checks, if all entries still exist in term store. if allowMultipleSelections is true. it have to validate all values
102
107
*/
103
108
private async validateTerms ( ) : Promise < void > {
104
-
105
109
const {
106
110
hideDeprecatedTags,
107
111
hideTagsNotAvailableForTagging,
@@ -141,8 +145,6 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
141
145
* Loads the list from SharePoint current web site
142
146
*/
143
147
private loadTermStores ( ) : void {
144
-
145
-
146
148
if ( this . props . termActions && this . props . termActions . initialize ) {
147
149
this . props . termActions . initialize ( this . termsService ) ;
148
150
// this.props.termActions.actions.forEach(x => {
@@ -276,7 +278,59 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
276
278
this . validate ( terms ) ;
277
279
}
278
280
281
+ /**
282
+ * Shows an error message for any invalid input inside taxonomy picker control
283
+ */
284
+ private validateInputText ( ) : void {
285
+ // Show error message, if any unresolved value exists inside taxonomy picker control
286
+ if ( ! ! this . invalidTerm ) {
287
+ // An unresolved value exists
288
+ this . setState ( {
289
+ errorMessage : strings . TaxonomyPickerInvalidTerms . replace ( '{0}' , this . invalidTerm )
290
+ } ) ;
291
+ }
292
+ else {
293
+ // There are no unresolved values
294
+ this . setState ( {
295
+ errorMessage : null
296
+ } ) ;
297
+ }
298
+ }
299
+
300
+ /**
301
+ * Triggers when input of taxonomy picker control changes
302
+ */
303
+ private onInputChange ( input : string ) : string {
304
+ if ( ! input ) {
305
+ const { validateInput } = this . props ;
306
+ if ( ! ! validateInput ) {
307
+ // Perform validation of input text, only if taxonomy picker is configured with validateInput={true} property.
308
+ this . invalidTerm = null ;
309
+ this . validateInputText ( ) ;
310
+ }
311
+ }
312
+ return input ;
313
+ }
279
314
315
+ /**
316
+ * Triggers when taxonomy picker control loses focus
317
+ */
318
+ private onBlur ( event : React . FocusEvent < HTMLElement | Autofill > ) : void {
319
+ const { validateInput } = this . props ;
320
+ if ( ! ! validateInput ) {
321
+ // Perform validation of input text, only if taxonomy picker is configured with validateInput={true} property.
322
+ const target : HTMLInputElement = event . target as HTMLInputElement ;
323
+ const targetValue = ! ! target ? target . value : null ;
324
+ if ( ! ! targetValue ) {
325
+ this . invalidTerm = targetValue ;
326
+ }
327
+ else {
328
+ this . invalidTerm = null ;
329
+ }
330
+ this . validateInputText ( ) ;
331
+ }
332
+ }
333
+
280
334
/**
281
335
* Gets the given node position in the active nodes collection
282
336
* @param node
@@ -318,7 +372,6 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
318
372
}
319
373
320
374
private validate = async ( value : IPickerTerms ) : Promise < void > => {
321
-
322
375
//
323
376
// checking if there are any invalid nodes left after initial validation
324
377
//
@@ -390,7 +443,8 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
390
443
disabled,
391
444
isTermSetSelectable,
392
445
allowMultipleSelections,
393
- disabledTermIds, disableChildrenOfDisabledParents,
446
+ disabledTermIds,
447
+ disableChildrenOfDisabledParents,
394
448
placeholder,
395
449
panelTitle,
396
450
anchorId,
@@ -419,6 +473,8 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
419
473
value = { activeNodes }
420
474
isTermSetSelectable = { isTermSetSelectable }
421
475
onChanged = { this . termsFromPickerChanged }
476
+ onInputChange = { this . onInputChange }
477
+ onBlur = { this . onBlur }
422
478
allowMultipleSelections = { allowMultipleSelections }
423
479
disabledTermIds = { disabledTermIds }
424
480
disableChildrenOfDisabledParents = { disableChildrenOfDisabledParents }
0 commit comments