Skip to content

Commit c65c4a6

Browse files
committed
fix(PrimeAutoComplete): improve v-model synchronization and handle paste events with local state
1 parent c6783f9 commit c65c4a6

File tree

3 files changed

+36
-16
lines changed

3 files changed

+36
-16
lines changed

dev/pages/inputs/AutoComplete.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ const schema
5757
},
5858
{
5959
$formkit: 'primeAutoComplete',
60-
id: 'chips',
61-
name: 'chips',
60+
id: 'chips2',
61+
name: 'chips2',
6262
multiple: true,
6363
typeahead: false,
6464
label: 'Chips - Paste separated values by comma or semicolon',

src/components/PrimeAutoComplete.vue

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
<script setup lang='ts'>
22
import type { FormKitFrameworkContext } from '@formkit/core'
33
import type { AutoCompleteCompleteEvent, AutoCompleteProps } from 'primevue/autocomplete'
4-
54
import type { PropType } from 'vue'
6-
import { ref } from 'vue'
5+
import { ref, watch } from 'vue'
76
import { useFormKitInput } from '../composables'
87
98
export interface FormKitPrimeAutoCompleteProps {
@@ -35,11 +34,30 @@ const suggestions = ref(['', {}])
3534
suggestions.value = []
3635
const loading = ref(false)
3736
37+
// Local value for v-model
38+
const localValue = ref(props.context._value)
39+
40+
// Sync localValue with context._value
41+
watch(
42+
() => props.context._value,
43+
(newVal) => {
44+
localValue.value = newVal
45+
},
46+
)
47+
48+
// Emit changes from localValue to context
49+
watch(
50+
localValue,
51+
(newVal) => {
52+
if (newVal !== props.context._value) {
53+
props.context._value = newVal
54+
props.context?.node?.input?.(newVal)
55+
}
56+
},
57+
)
58+
3859
/**
3960
* Searches for suggestions based on the input query.
40-
* If options and optionLabel are provided, it filters the options.
41-
* Otherwise, it calls the complete function from the context to fetch suggestions.
42-
* @param event - The AutoCompleteCompleteEvent containing the query.
4361
*/
4462
async function search(event: AutoCompleteCompleteEvent) {
4563
if (props.context?.options && props.context?.optionLabel) {
@@ -64,7 +82,6 @@ async function search(event: AutoCompleteCompleteEvent) {
6482
6583
/**
6684
* Handles paste event to transform a string separated by any of the provided separators into multiple items.
67-
* @param event - The paste event from the input.
6885
*/
6986
function handlePaste(event: ClipboardEvent) {
7087
if (!props.context?.multiple)
@@ -76,21 +93,20 @@ function handlePaste(event: ClipboardEvent) {
7693
const separators = Array.isArray(props.context?.separators) && props.context.separators.length > 0
7794
? props.context.separators
7895
: [',']
79-
// Create a regex to split by any separator, escaping special regex characters
8096
const regex = new RegExp(`[${separators.map(s => s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')).join('')}]`)
8197
if (pastedText && regex.test(pastedText)) {
8298
event.preventDefault()
8399
const items = pastedText
84100
.split(regex)
85101
.map(item => item.trim())
86102
.filter(item => item.length > 0)
87-
if (Array.isArray(props.context._value)) {
88-
props.context._value.push(...items)
103+
// Use a local ref, never mutate context._value directly
104+
if (Array.isArray(localValue.value)) {
105+
localValue.value = [...localValue.value, ...items]
89106
}
90107
else {
91-
props.context._value = items
108+
localValue.value = items
92109
}
93-
props.context?.node?.input?.(props.context?._value)
94110
}
95111
}
96112
</script>
@@ -99,7 +115,7 @@ function handlePaste(event: ClipboardEvent) {
99115
<div class="p-formkit">
100116
<AutoComplete
101117
:id="context.id"
102-
v-model="context._value"
118+
v-model="localValue"
103119
v-bind="context?.attrs"
104120
:disabled="!!context?.disabled"
105121
:class="context?.attrs?.class"

src/composables/useFormKitRepeater.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@ export function useFormKitRepeater() {
1010
}
1111

1212
function addListGroupFunctions(data: any, addNodeDefaultObject: object = {}) {
13+
// Swap elements immutably
1314
const swapElements = (array: any[], index1: number, index2: number) => {
14-
array[index1] = array.splice(index2, 1, array[index1])[0]
15-
return array
15+
const newArray = [...array]
16+
const temp = newArray[index1]
17+
newArray[index1] = newArray[index2]
18+
newArray[index2] = temp
19+
return newArray
1620
}
1721

1822
data.addNode = (parentNode: any) => (): void => {

0 commit comments

Comments
 (0)