Skip to content

Commit b27fb2c

Browse files
committed
Added property to disable children #82
1 parent 62609d0 commit b27fb2c

File tree

9 files changed

+76
-25
lines changed

9 files changed

+76
-25
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
**Enhancements**
66

7-
- Added a property to the `TaxonomyPicker` to specify which terms are disabled/not-selectable [#82](https://github.com/SharePoint/sp-dev-fx-controls-react/issues/82)
7+
- Added a properties to the `TaxonomyPicker` to specify which terms are disabled/not-selectable [#82](https://github.com/SharePoint/sp-dev-fx-controls-react/issues/82)
88

99
## 1.4.0
1010

docs/documentation/docs/about/release-notes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
**Enhancements**
66

7-
- Added a property to the `TaxonomyPicker` to specify which terms are disabled/not-selectable [#82](https://github.com/SharePoint/sp-dev-fx-controls-react/issues/82)
7+
- Added a properties to the `TaxonomyPicker` to specify which terms are disabled/not-selectable [#82](https://github.com/SharePoint/sp-dev-fx-controls-react/issues/82)
88

99
## 1.4.0
1010

docs/documentation/docs/controls/TaxonomyPicker.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ The TaxonomyPicker control can be configured with the following properties:
6969
| onChange | function | no | captures the event of when the terms in the picker has changed. |
7070
| isTermSetSelectable | boolean | no | Specify if the TermSet itself is selectable in the tree view. |
7171
| disabledTermIds | string[] | no | Specify which terms should be disabled in the term set so that they cannot be selected. |
72+
| disableChildrenOfDisabledParents | boolean | no | Specify if you want to disable the child terms when their parent is disabled. |
7273
| anchorId | string | no | Set the anchorid to a child term in the TermSet to be able to select terms from that level and below. |
7374

7475
Interface `IPickerTerm`

src/controls/taxonomyPicker/ITaxonomyPicker.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ export interface ITaxonomyPickerProps {
4444
* Specify which terms should be disabled in the term set so that they cannot be selected
4545
*/
4646
disabledTermIds?: string[];
47+
/**
48+
* Specify if you want to disable the child terms when their parent is disabled
49+
*/
50+
disableChildrenOfDisabledParents?: boolean;
4751
/**
4852
* Whether the property pane field is enabled or not.
4953
*/
@@ -85,6 +89,7 @@ export interface ITermChanges {
8589
changedCallback: (term: ITerm, checked: boolean) => void;
8690
activeNodes?: IPickerTerms;
8791
disabledTermIds?: string[];
92+
disableChildrenOfDisabledParents?: boolean;
8893
}
8994

9095

@@ -108,6 +113,7 @@ export interface ITermProps extends ITermChanges {
108113
termset: string;
109114
term: ITerm;
110115
multiSelection: boolean;
116+
disabled: boolean;
111117
}
112118

113119
export interface ITermState {

src/controls/taxonomyPicker/TaxonomyPicker.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,8 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
240240
isTermSetSelectable={this.props.isTermSetSelectable}
241241
onChanged={this.termsFromPickerChanged}
242242
allowMultipleSelections={this.props.allowMultipleSelections}
243-
disabledTermIds={this.props.disabledTermIds} />
243+
disabledTermIds={this.props.disabledTermIds}
244+
disableChildrenOfDisabledParents={this.props.disableChildrenOfDisabledParents} />
244245
</td>
245246
<td className={styles.termFieldRow}>
246247
<IconButton disabled={this.props.disabled} iconProps={{ iconName: 'Tag' }} onClick={this.onOpenPanel} />
@@ -283,6 +284,7 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
283284
termSetSelectedChange={this.termSetSelectedChange}
284285
activeNodes={this.state.activeNodes}
285286
disabledTermIds={this.props.disabledTermIds}
287+
disableChildrenOfDisabledParents={this.props.disableChildrenOfDisabledParents}
286288
changedCallback={this.termsChanged}
287289
multiSelection={this.props.allowMultipleSelections} />
288290
</div>

src/controls/taxonomyPicker/Term.tsx

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,6 @@ export default class Term extends React.Component<ITermProps, ITermState> {
4848
}
4949
}
5050

51-
/**
52-
* Check if the current term needs to be disabled
53-
*/
54-
private checkIfTermIsDisabled(): boolean {
55-
// Check if disabled term IDs are provided
56-
if (this.props.disabledTermIds && this.props.disabledTermIds.length > 0) {
57-
// Check if the current term ID exists in the disabled term IDs array
58-
return this.props.disabledTermIds.indexOf(this.props.term.Id) !== -1;
59-
}
60-
61-
return false;
62-
}
63-
6451
/**
6552
* Default React render
6653
*/
@@ -73,7 +60,7 @@ export default class Term extends React.Component<ITermProps, ITermState> {
7360
<div className={`${styles.listItem} ${styles.term}`} style={styleProps}>
7461
<Checkbox
7562
checked={this.state.selected}
76-
disabled={this.props.term.IsDeprecated || this.checkIfTermIsDisabled()}
63+
disabled={this.props.term.IsDeprecated || this.props.disabled}
7764
className={this.props.term.IsDeprecated ? styles.termDisabled : styles.termEnabled}
7865
label={this.props.term.Name}
7966
onChange={this._handleChange} />

src/controls/taxonomyPicker/TermParent.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as React from 'react';
22
import { Spinner, SpinnerType } from 'office-ui-fabric-react/lib/Spinner';
33
import { ITermParentProps, ITermParentState } from './ITaxonomyPicker';
4-
import { ITerm, ITermSet } from '../../services/ISPTermStorePickerService';
4+
import { ITerm } from '../../services/ISPTermStorePickerService';
55
import { EXPANDED_IMG, COLLAPSED_IMG, TERMSET_IMG, TERM_IMG } from './TaxonomyPicker';
66
import Term from './Term';
77

@@ -87,11 +87,29 @@ export default class TermParent extends React.Component<ITermParentProps, ITermP
8787
// Check if the terms have been loaded
8888
if (this.state.loaded) {
8989
if (this._terms.length > 0) {
90+
let disabledPaths = [];
9091
termElm = (
9192
<div style={styleProps}>
9293
{
9394
this._terms.map(term => {
94-
return <Term key={term.Id} term={term} termset={this.props.termset.Id} activeNodes={this.props.activeNodes} changedCallback={this.props.changedCallback} multiSelection={this.props.multiSelection} disabledTermIds={this.props.disabledTermIds} />;
95+
// debugger;
96+
let disabled = false;
97+
if (this.props.disabledTermIds && this.props.disabledTermIds.length > 0) {
98+
// Check if the current term ID exists in the disabled term IDs array
99+
disabled = this.props.disabledTermIds.indexOf(term.Id) !== -1;
100+
if (disabled) {
101+
// Push paths to the disabled list
102+
disabledPaths.push(term.PathOfTerm);
103+
}
104+
}
105+
106+
if (this.props.disableChildrenOfDisabledParents) {
107+
// Check if parent is disabled
108+
const parentPath = disabledPaths.filter(p => term.PathOfTerm.indexOf(p) !== -1);
109+
disabled = parentPath && parentPath.length > 0;
110+
}
111+
112+
return <Term key={term.Id} term={term} termset={this.props.termset.Id} activeNodes={this.props.activeNodes} changedCallback={this.props.changedCallback} multiSelection={this.props.multiSelection} disabled={disabled} />;
95113
})
96114
}
97115
</div>

src/controls/taxonomyPicker/TermPicker.tsx

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { IWebPartContext } from '@microsoft/sp-webpart-base';
88
import * as strings from 'ControlStrings';
99
import { Icon } from 'office-ui-fabric-react';
1010
import { ApplicationCustomizerContext } from '@microsoft/sp-application-base';
11+
import { ITermSet } from '../../services/ISPTermStorePickerService';
1112

1213
export class TermBasePicker extends BasePicker<IPickerTerm, IBasePickerProps<IPickerTerm>>
1314
{
@@ -26,11 +27,13 @@ export interface ITermPickerProps {
2627
allowMultipleSelections : boolean;
2728
isTermSetSelectable?: boolean;
2829
disabledTermIds?: string[];
30+
disableChildrenOfDisabledParents?: boolean;
2931

3032
onChanged: (items: IPickerTerm[]) => void;
3133
}
3234

3335
export default class TermPicker extends React.Component<ITermPickerProps, ITermPickerState> {
36+
private allTerms: ITermSet = null;
3437

3538
/**
3639
* Constructor method
@@ -126,14 +129,45 @@ export default class TermPicker extends React.Component<ITermPickerProps, ITermP
126129
}
127130
// Filter out the terms which are already set
128131
const filteredTerms = [];
132+
const { disabledTermIds, disableChildrenOfDisabledParents } = this.props;
129133
for (const term of terms) {
134+
let canBePicked = true;
135+
130136
// Check if term is not disabled
131-
if (this.props.disabledTermIds && this.props.disabledTermIds.length > 0 && this.props.disabledTermIds.indexOf(term.key) !== -1) {
132-
break;
137+
if (disabledTermIds && disabledTermIds.length > 0) {
138+
// Check if current term need to be disabled
139+
if (disabledTermIds.indexOf(term.key) !== -1) {
140+
canBePicked = false;
141+
} else {
142+
// Check if child terms need to be disabled
143+
if (disableChildrenOfDisabledParents) {
144+
// Check if terms were already retrieved
145+
if (!this.allTerms) {
146+
this.allTerms = await termsService.getAllTerms(this.props.termPickerHostProps.termsetNameOrID);
147+
}
148+
149+
// Check if there are terms retrieved
150+
if (this.allTerms.Terms && this.allTerms.Terms.length > 0) {
151+
// Find the disabled parents
152+
const disabledParents = this.allTerms.Terms.filter(t => disabledTermIds.indexOf(t.Id) !== -1);
153+
// Check if disabled parents were found
154+
if (disabledParents && disabledParents.length > 0) {
155+
// Check if the current term lives underneath a disabled parent
156+
const findTerm = disabledParents.filter(pt => term.path.indexOf(pt.PathOfTerm) !== -1);
157+
if (findTerm && findTerm.length > 0) {
158+
canBePicked = false;
159+
}
160+
}
161+
}
162+
}
163+
}
133164
}
134-
// Only retrieve the terms which are not yet tagged
135-
if (tagList.filter(tag => tag.key === term.key).length === 0) {
136-
filteredTerms.push(term);
165+
166+
if (canBePicked) {
167+
// Only retrieve the terms which are not yet tagged
168+
if (tagList.filter(tag => tag.key === term.key).length === 0) {
169+
filteredTerms.push(term);
170+
}
137171
}
138172
}
139173
return filteredTerms;

src/webparts/controlsTest/components/ControlsTest.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,10 @@ export default class ControlsTest extends React.Component<IControlsTestProps, IC
223223
allowMultipleSelections={true}
224224
termsetNameOrID="b3e9b754-2593-4ae6-abc2-35345402e186"
225225
// anchorId="0ec2f948-3978-499e-9d3f-e51c4494d44c"
226-
disabledTermIds={["943fd9f0-3d7c-415c-9192-93c0e54573fb", "0e415292-cce5-44ac-87c7-ef99dd1f01f4"]}
226+
// disabledTermIds={["943fd9f0-3d7c-415c-9192-93c0e54573fb", "0e415292-cce5-44ac-87c7-ef99dd1f01f4"]}
227+
disabledTermIds={["943fd9f0-3d7c-415c-9192-93c0e54573fb", "73d18756-20af-41de-808c-2a1e21851e44", "0e415292-cce5-44ac-87c7-ef99dd1f01f4"]}
228+
// disabledTermIds={["cd6f6d3c-672d-4244-9320-c1e64cc0626f", "0e415292-cce5-44ac-87c7-ef99dd1f01f4"]}
229+
disableChildrenOfDisabledParents={true}
227230
panelTitle="Select Term"
228231
label="Taxonomy Picker"
229232
context={this.props.context}

0 commit comments

Comments
 (0)