Skip to content

Commit

Permalink
🐛 Makes .fill work with selects and other modifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
ekwoka committed Mar 30, 2023
1 parent 6142a83 commit e8c227b
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 6 deletions.
9 changes: 4 additions & 5 deletions packages/alpinejs/src/directives/x-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -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') {
// Radio buttons only work properly when they share a name attribute.
Expand All @@ -73,7 +69,10 @@ directive('model', (el, { modifiers, expression }, { effect, cleanup }) => {
let removeListener = isCloning ? () => {} : on(el, event, modifiers, (e) => {
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
// in addition to the cleanup function, x-modelable may call it.
// Also, make this a keyed object if we decide to reintroduce
Expand Down
35 changes: 35 additions & 0 deletions tests/cypress/integration/directives/x-model.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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]));
}
);



2 changes: 1 addition & 1 deletion tests/cypress/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ 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(getData(el,key)).to.deep.equal(value)

export let haveFocus = () => el => expect(el).to.have.focus

Expand Down

0 comments on commit e8c227b

Please sign in to comment.