Skip to content

Commit

Permalink
Fix #7522: Autocomplete allow selectedItemTemplate in both modes (#7564)
Browse files Browse the repository at this point in the history
  • Loading branch information
melloware authored Jan 6, 2025
1 parent 1a50364 commit f2f5d2a
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 10 deletions.
31 changes: 26 additions & 5 deletions components/doc/autocomplete/templatedoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ export function TemplateDoc(props) {
);
};

const selectedItemTemplate = (item) => {
return `${item.name} (${item.code.toUpperCase()})`;
};

const panelFooterTemplate = () => {
const isCountrySelected = (filteredCountries || []).some((country) => country.name === selectedCountry);

Expand All @@ -58,7 +62,7 @@ export function TemplateDoc(props) {
const code = {
basic: `
<AutoComplete field="name" value={selectedCountry} suggestions={filteredCountries}
completeMethod={search} onChange={(e) => setSelectedCountry(e.value)} itemTemplate={itemTemplate} panelFooterTemplate={panelFooterTemplate} />
completeMethod={search} onChange={(e) => setSelectedCountry(e.value)} itemTemplate={itemTemplate} panelFooterTemplate={panelFooterTemplate} selectedItemTemplate={selectedItemTemplate} />
`,
javascript: `
import React, { useEffect, useState } from 'react';
Expand Down Expand Up @@ -117,14 +121,18 @@ export default function TemplateDemo() {
);
};
const selectedItemTemplate = (item) => {
return item.name + ' (' + item.code.toUpperCase() + ')';
};
useEffect(() => {
CountryService.getCountries().then((data) => setCountries(data));
}, []);
return (
<div className="card flex justify-content-center">
<AutoComplete field="name" value={selectedCountry} suggestions={filteredCountries}
completeMethod={search} onChange={(e) => setSelectedCountry(e.value)} itemTemplate={itemTemplate} panelFooterTemplate={panelFooterTemplate} />
completeMethod={search} onChange={(e) => setSelectedCountry(e.value)} itemTemplate={itemTemplate} panelFooterTemplate={panelFooterTemplate} selectedItemTemplate={selectedItemTemplate} />
</div>
)
}
Expand Down Expand Up @@ -175,6 +183,10 @@ export default function TemplateDemo() {
</div>
);
};
const selectedItemTemplate = (item: Country) => {
return item.name + ' (' + item.code.toUpperCase() + ')';
};
const panelFooterTemplate = () => {
const isCountrySelected = (filteredCountries || []).some( country => country['name'] === selectedCountry );
Expand All @@ -198,7 +210,7 @@ export default function TemplateDemo() {
return (
<div className="card flex justify-content-center">
<AutoComplete field="name" value={selectedCountry} suggestions={filteredCountries}
completeMethod={search} onChange={(e: AutoCompleteChangeEvent) => setSelectedCountry(e.value)} itemTemplate={itemTemplate} panelFooterTemplate={panelFooterTemplate} />
completeMethod={search} onChange={(e: AutoCompleteChangeEvent) => setSelectedCountry(e.value)} itemTemplate={itemTemplate} panelFooterTemplate={panelFooterTemplate} selectedItemTemplate={selectedItemTemplate} />
</div>
)
}
Expand All @@ -217,11 +229,20 @@ export default function TemplateDemo() {
<DocSectionText {...props}>
<p>
Custom content can be displayed as an option using <i>itemTemplate</i> property that references a function with a suggestion option as a parameter and returns an element. Similarly <i>selectedItemTemplate</i> property is available
to customize the chips in multiple mode using the same approach. Note that <i>selectedItemTemplate</i> is only available in multiple mode at the moment.
to customize the chips in <i>multiple</i> mode and the text in <i>single</i> mode using the same approach.
</p>
</DocSectionText>
<div className="card flex justify-content-center">
<AutoComplete field="name" value={selectedCountry} suggestions={filteredCountries} completeMethod={search} onChange={(e) => setSelectedCountry(e.value)} itemTemplate={itemTemplate} panelFooterTemplate={panelFooterTemplate} />
<AutoComplete
field="name"
value={selectedCountry}
suggestions={filteredCountries}
completeMethod={search}
onChange={(e) => setSelectedCountry(e.value)}
itemTemplate={itemTemplate}
panelFooterTemplate={panelFooterTemplate}
selectedItemTemplate={selectedItemTemplate}
/>
</div>
<DocSectionCode code={code} service={['CountryService']} />
</>
Expand Down
6 changes: 3 additions & 3 deletions components/lib/autocomplete/AutoComplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,10 @@ export const AutoComplete = React.memo(

if (typeof value === 'string') return value;

const valueFromTemplate = ObjectUtils.getJSXElement(props.selectedItemTemplate, value);
if (props.selectedItemTemplate) {
const valueFromTemplate = ObjectUtils.getJSXElement(props.selectedItemTemplate, value);

if (typeof valueFromTemplate === 'string') {
return valueFromTemplate;
return props.multiple || typeof valueFromTemplate === 'string' ? valueFromTemplate : value;
}

if (props.field) {
Expand Down
4 changes: 2 additions & 2 deletions components/lib/autocomplete/autocomplete.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -404,9 +404,9 @@ export interface AutoCompleteProps extends Omit<React.DetailedHTMLProps<React.In
*/
scrollHeight?: string | undefined;
/**
* Template of a selected item.
* Template of a selected item. In multiple mode, it is used to customize the chips using a ReactNode. In single mode, it is used to customize the text using a string.
*/
selectedItemTemplate?: string | undefined | null | ((value: any) => string | undefined | null);
selectedItemTemplate?: React.ReactNode | string | undefined | null | ((value: any) => React.ReactNode | string | undefined | null);
/**
* Whether to show the empty message or not.
* @defaultValue false
Expand Down

0 comments on commit f2f5d2a

Please sign in to comment.