Browse Source

:bug: Makes .fill work with selects and other modifiers (#3495)

Eric Kwoka 2 năm trước cách đây
mục cha
commit
61afc45b14

+ 4 - 5
packages/alpinejs/src/directives/x-model.js

@@ -46,10 +46,6 @@ directive('model', (el, { modifiers, expression }, { effect, cleanup }) => {
             })
             })
         }
         }
     }
     }
-
-    if (modifiers.includes('fill') && el.hasAttribute('value') && (getValue() === null || getValue() === '')) {
-        setValue(el.value)
-    }
     
     
     if (typeof expression === 'string' && el.type === 'radio') {
     if (typeof expression === 'string' && el.type === 'radio') {
         // Radio buttons only work properly when they share a name attribute.
         // Radio buttons only work properly when they share a name attribute.
@@ -73,7 +69,10 @@ directive('model', (el, { modifiers, expression }, { effect, cleanup }) => {
     let removeListener = isCloning ? () => {} : on(el, event, modifiers, (e) => {
     let removeListener = isCloning ? () => {} : on(el, event, modifiers, (e) => {
         setValue(getInputValue(el, modifiers, e, getValue()))
         setValue(getInputValue(el, modifiers, e, getValue()))
     })
     })
-
+    
+    if (modifiers.includes('fill') && [null, ''].includes(getValue())) {
+        el.dispatchEvent(new Event(event, {}));
+    }
     // Register the listener removal callback on the element, so that
     // Register the listener removal callback on the element, so that
     // in addition to the cleanup function, x-modelable may call it.
     // in addition to the cleanup function, x-modelable may call it.
     // Also, make this a keyed object if we decide to reintroduce
     // Also, make this a keyed object if we decide to reintroduce

+ 35 - 0
tests/cypress/integration/directives/x-model.spec.js

@@ -151,5 +151,40 @@ test('x-model with fill modifier takes input value on null or empty string',
     }
     }
 )
 )
 
 
+test('x-model with fill modifier works with select/radio elements',
+    html`
+        <div x-data="{ a: null, b: null, c: null, d: null }">
+            <select x-model.fill="a">
+                <option value="123">123</option>
+                <option value="456" selected>456</option>
+            </select>
+            <select x-model.fill="b" multiple>
+                <option value="123" selected>123</option>
+                <option value="456" selected>456</option>
+            </select>
+        </div>
+    `,
+    ({ get }) => {
+        get('[x-data]').should(haveData('a', '456'));
+        get('[x-data]').should(haveData('b', ['123', '456']));
+    }
+);
+
+test('x-model with fill modifier respects number modifier',
+    html`
+        <div x-data="{ a: null, b: null, c: null, d: null }">
+            <input type="text" x-model.fill.number="a" value="456" / >
+            <select x-model.fill.number="b" multiple>
+                <option value="123" selected>123</option>
+                <option value="456" selected>456</option>
+            </select>
+        </div>
+    `,
+    ({ get }) => {
+        get('[x-data]').should(haveData('a', 456));
+        get('[x-data]').should(haveData('b', [123,456]));
+    }
+);
+
 
 
 
 

+ 4 - 1
tests/cypress/utils.js

@@ -87,7 +87,10 @@ function injectHtmlAndBootAlpine(cy, templateAndPotentiallyScripts, callback, pa
     })
     })
 }
 }
 
 
-export let haveData = (key, value) => ([ el ]) => expect(root(el)._x_dataStack[0][key]).to.equal(value)
+export let haveData =
+    (key, value) =>
+    ([el]) =>
+        expect(root(el)._x_dataStack[0][key]).to.deep.equal(value);
 
 
 export let haveFocus = () => el => expect(el).to.have.focus
 export let haveFocus = () => el => expect(el).to.have.focus