Skip to content

Commit

Permalink
fix(Autocomplete): ensure correct value selection during data change (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
tujoworker authored Nov 8, 2023
1 parent 1cd6be4 commit d229ec2
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 3 deletions.
16 changes: 14 additions & 2 deletions packages/dnb-eufemia/src/components/autocomplete/Autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,12 @@ class AutocompleteInstance extends React.PureComponent {
})
}

resetValue = () => {
this.context.drawerList.setState({
_value: 're-evaluate', // ensure "state.selected_item = getCurrentIndex(...)" inside "prepareDerivedState" does run
})
}

updateData = (rawData) => {
// invalidate the local cache now,
// because we get else the same after we show the new result
Expand All @@ -763,7 +769,11 @@ class AutocompleteInstance extends React.PureComponent {
if (parseFloat(itemIndex) > -1) {
const newItem = rawData[itemIndex]
const oldItem = this.context.drawerList.original_data[itemIndex]
if (newItem?.selected_key !== oldItem?.selected_key) {
if (
typeof newItem?.selectedKey !== 'undefined'
? newItem?.selectedKey !== oldItem?.selectedKey
: newItem?.selected_key !== oldItem?.selected_key
) {
this.resetSelectionItem()
}
}
Expand All @@ -778,14 +788,15 @@ class AutocompleteInstance extends React.PureComponent {
() => {
const { typedInputValue } = this.state

if (typedInputValue && typedInputValue.length > 0) {
if (typedInputValue?.length > 0) {
// run with side effects, to get preselection of active_item
const filteredData =
this.runFilterWithSideEffects(typedInputValue)
if (this.countData(filteredData) === 0) {
this.showNoOptionsItem()
}
} else {
this.resetValue()
this.resetActiveItem()
if (this.context.drawerList.opened) {
this.showAllItems()
Expand Down Expand Up @@ -1008,6 +1019,7 @@ class AutocompleteInstance extends React.PureComponent {
attributes,
dataList: this.context.drawerList.data,
updateData: this.updateData,
resetValue: this.resetValue,
showAllItems: this.showAllItems,
setVisible: this.setVisible,
setHidden: this.setHidden,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2315,6 +2315,71 @@ describe('Autocomplete component', () => {
'dnb-autocomplete--default',
])
})

it('should set correct value in input', () => {
const data = [
{
selectedKey: '+93',
selected_value: 'AF (+93)',
content: '+93 Afghanistan',
},
{
selectedKey: '+47',
selected_value: 'NO (+47)',
content: '+47 Norge',
},
{
selectedKey: '+46',
selected_value: 'SE (+46)',
content: '+46 Sverige',
},
{
selectedKey: '+41',
selected_value: 'CH (+41)',
content: '+41 Sveits',
},
]
const MockComponent = () => {
const [value, setValue] = React.useState('+47')

return (
<Autocomplete
data={[data[1]]}
value={value}
mode="async"
on_change={({ data }) => setValue(data.selectedKey)}
on_focus={({ updateData }) => updateData(data)}
search_numbers
no_animation
/>
)
}

render(<MockComponent />)

const inputElement: HTMLInputElement = document.querySelector('input')

expect(inputElement.value).toEqual('NO (+47)')

// open
fireEvent.keyDown(inputElement, {
key: 'Enter',
keyCode: 13,
})

expect(
document.querySelectorAll('li.dnb-drawer-list__option')[0]
.textContent
).toBe('+47 Norge')

fireEvent.focus(inputElement)
fireEvent.change(inputElement, { target: { value: '+41' } })
fireEvent.click(
document.querySelectorAll('li.dnb-drawer-list__option')[0]
)

expect(inputElement.value).toEqual('CH (+41)')
})
})

describe('Autocomplete markup', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,10 @@ export const prepareDerivedState = (props, state) => {
if (props.value === 'initval') {
state.selected_item = null
} else {
state.selected_item = getCurrentIndex(props.value, state.data)
state.selected_item = getCurrentIndex(
props.value,
state.original_data
)
}

if (typeof props.on_state_update === 'function') {
Expand Down

0 comments on commit d229ec2

Please sign in to comment.