Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "office-ui-fabric-react",
"comment": "Pickers: Allow onItemSelected to return null",
"type": "patch"
}
],
"packageName": "office-ui-fabric-react",
"email": "law@microsoft.com"
}
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,12 @@ export class BasePicker<T, P extends IBasePickerProps<T>> extends BaseComponent<

@autobind
protected addItem(item: T) {
const processedItem: T | PromiseLike<T> = this.props.onItemSelected ? (this.props.onItemSelected as any)(item) : item;
const processedItem: T | PromiseLike<T> | null =
this.props.onItemSelected ? (this.props.onItemSelected as any)(item) : item;

if (processedItem === null) {
return;
}

const processedItemObject: T = processedItem as T;
const processedItemPromiseLike: PromiseLike<T> = processedItem as PromiseLike<T>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,10 @@ export interface IBasePickerProps<T> extends React.Props<any> {
*/
removeButtonAriaLabel?: string;
/**
* A callback to process a selection after the user selects something from the picker.
* A callback to process a selection after the user selects something from the picker. If the callback returns null,
* the item will not be added to the picker.
*/
onItemSelected?: (selectedItem?: T) => T | PromiseLike<T>;
onItemSelected?: (selectedItem?: T) => T | PromiseLike<T> | null;
/**
* The items that the base picker should currently display as selected. If this is provided then the picker will act as a controlled component.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import * as React from 'react';
import { autobind } from '../../../Utilities';
import {
autobind,
BaseComponent
} from '../../../Utilities';
import { TagPicker } from 'office-ui-fabric-react/lib/components/pickers/TagPicker/TagPicker';
import { Checkbox } from 'office-ui-fabric-react/lib/Checkbox';
import { ITagPickerDemoPageState } from 'office-ui-fabric-react/lib/components/pickers/examples/ITagPickerDemoPageState';
Expand All @@ -24,7 +27,9 @@ const _testTags = [
'yellow'
].map(item => ({ key: item, name: item }));

export class TagPickerBasicExample extends React.Component<{}, ITagPickerDemoPageState> {
export class TagPickerBasicExample extends BaseComponent<{}, ITagPickerDemoPageState> {
private _picker: TagPicker;

constructor(props: {}) {
super(props);
this.state = {
Expand All @@ -41,6 +46,7 @@ export class TagPickerBasicExample extends React.Component<{}, ITagPickerDemoPag
checked={ this.state.isPickerDisabled }
onChange={ this._onDisabledButtonClick }
/>
Filter items in suggestions: This picker will filter added items from the search suggestions.
<TagPicker
onResolveSuggestions={ this._onFilterChanged }
getTextFromItem={ this._getTextFromItem }
Expand All @@ -58,6 +64,27 @@ export class TagPickerBasicExample extends React.Component<{}, ITagPickerDemoPag
'aria-label': 'Tag Picker'
} }
/>
<br />
Filter items on selected: This picker will show already-added suggestions but will not add duplicate tags.
<TagPicker
componentRef={ this._resolveRef('_picker') }
onResolveSuggestions={ this._onFilterChangedNoFilter }
onItemSelected={ this._onItemSelected }
getTextFromItem={ this._getTextFromItem }
pickerSuggestionsProps={
{
suggestionsHeaderText: 'Suggested Tags',
noResultsFoundText: 'No Color Tags Found'
}
}
itemLimit={ 2 }
disabled={ this.state.isPickerDisabled }
inputProps={ {
onBlur: (ev: React.FocusEvent<HTMLInputElement>) => console.log('onBlur called'),
onFocus: (ev: React.FocusEvent<HTMLInputElement>) => console.log('onFocus called'),
'aria-label': 'Tag Picker'
} }
/>
</div>
);
}
Expand All @@ -75,7 +102,21 @@ export class TagPickerBasicExample extends React.Component<{}, ITagPickerDemoPag

@autobind
private _onFilterChanged(filterText: string, tagList: { key: string, name: string }[]) {
return filterText ? _testTags.filter(tag => tag.name.toLowerCase().indexOf(filterText.toLowerCase()) === 0).filter(item => !this._listContainsDocument(item, tagList)) : [];
return filterText ? _testTags.filter(tag => tag.name.toLowerCase().indexOf(filterText.toLowerCase()) === 0)
.filter(tag => !this._listContainsDocument(tag, tagList)) : [];
}

@autobind
private _onFilterChangedNoFilter(filterText: string, tagList: { key: string, name: string }[]) {
return filterText ? _testTags.filter(tag => tag.name.toLowerCase().indexOf(filterText.toLowerCase()) === 0) : [];
}

@autobind
private _onItemSelected(item: any) {
if (this._listContainsDocument(item, this._picker.items)) {
return null;
}
return item;
}

private _listContainsDocument(tag: { key: string, name: string }, tagList: { key: string, name: string }[]) {
Expand Down