Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
123 views
in Technique[技术] by (71.8m points)

javascript - how to indicate loaging/searching on Office FabricUI TagPicker for large data sets?

I am using the TagPicker to get data dynamically and present a set of the results that matches with the term. The issue is that looking into the docs there is not clear indication how to determine that the component data is loading or searching. The interface that had those was dropped (ISuggestionsProps) and the loadingText prop does not seem to work for me or I am probably using it wrong.

here is how I was able to load data from a list into the tagpicker:

const filterSuggestedTags = async (filterText: string, tagList: ITag[]) => {
    //* possibly here to call an api if needed?
    if (filterText) {
      const url = 'url'
      const resp = await fetch(url,{method:'GET',headers:{Accept:'application/json; odata=verbose'}})
      return (await resp.json()).d.results.map(item => ({ key: item, name: item.Title }));
    } else return []
  };

codepen: https://codepen.io/deleite/pen/MWjBMjY?editors=1111

This obviously has a lot of problems, first and the worst every keystroke is a promise fired. So, question is how to call an api using the search term and result the suggestions?

Thank you all.

question from:https://stackoverflow.com/questions/65649408/how-to-indicate-loaging-searching-on-office-fabricui-tagpicker-for-large-data-se

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I am ussing Office ui Fabric react v5 ("office-ui-fabric-react": "^5.135.5"). I am using TagPicker to laod external API data (long resolve time, large data set). Loading suggestions is delayed for 700ms (after key pressed). Loading suggestions is fired after 3 chars are typed. During loading there is loading circle visible. I am loading suggestion in pages for 20 suggestions, if there is more items to be loaded on the bottom there is Loading more anchor which loads another page and add new suggestions to already loaded. I had to extend IBasePickerSuggestionsProps interface for moreSuggestionsAvailable?: boolean; in BasePicker.types.d.ts based on this issue: https://github.com/microsoft/fluentui/issues/6582

Doc: https://developer.microsoft.com/en-us/fluentui#/components/pickers

Codepen: https://codepen.io/matej4386/pen/ZEpqwQv

Here is my code:

const {disabled} = this.props;
const {
selectedItems,
    errorMessage
} = this.state;   
<TagPicker 
onResolveSuggestions={this.onFilterChanged}
getTextFromItem={this.getTextFromItem}
resolveDelay={700}
pickerSuggestionsProps={{
    suggestionsHeaderText: strings.suggestionsHeaderText,
    noResultsFoundText: strings.noresultsFoundText,
    searchForMoreText: strings.moreSuggestions,
    moreSuggestionsAvailable: this.state.loadmore
}}
onGetMoreResults={this.onGetMoreResults}
onRenderSuggestionsItem={this.onRenderSuggestionsItem}
selectedItems={selectedItems}
onChange={this.onItemChanged}
itemLimit={1}
disabled={disabled}
inputProps={{
    placeholder: strings.TextFormFieldPlaceholder
}} 
/>
private onFilterChanged = async (filterText: string, tagList:IPickerItem[]) => {
if (filterText.length >= 3) {
  let resolvedSugestions: IPickerItem[] = await this.loadListItems(filterText);

  const {
    selectedItems
  } = this.state;

  // Filter out the already retrieved items, so that they cannot be selected again
  if (selectedItems && selectedItems.length > 0) {
    let filteredSuggestions = [];
    for (const suggestion of resolvedSugestions) {
      const exists = selectedItems.filter(sItem => sItem.key === suggestion.key);
      if (!exists || exists.length === 0) {
        filteredSuggestions.push(suggestion);
      }
    }
    resolvedSugestions = filteredSuggestions;
  }
  if (resolvedSugestions) {
    this.setState({
      errorMessage: "",
      showError: false,
      suggestions: resolvedSugestions,
      loadmore: true,
      loadMorePageNumber: 1
    });

    return resolvedSugestions;
  } else {
    return [];
  }
} else {
  return null
}
}
private onGetMoreResults = async (filterText: string, selectedItems?: any[]): Promise<IPickerItem[]> => {
let arrayItems: IPickerItem[] = [];
try {
  
    let listItems: IOrganization[] = await this.GetOrganizations(this.Identity[0].id, filterText, 1);
  ...
private loadListItems = async (filterText: string): Promise<IPickerItem[]> => {
let { webUrl, filter, substringSearch } = this.props;
let arrayItems: IPickerItem[] = [];

try {
...

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...