Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x-model.boolean modifier #3532

Merged
merged 3 commits into from
Nov 11, 2023
Merged

Conversation

gdebrauwer
Copy link
Contributor

In a project I had a select with 2 options: one was value, the other was false. But currently that is not very easy to work with, because alpine.js either just returns a string ('true'/'false' when option values are strings) or an integer (1/0 when option values are integers). This also causes issues when entangling it with a boolean property on a Livewire component. To fix this, I added a boolean modifier to x-model`.

<select x-model.boolean="bar">
    <option value="true">yes</option>
    <option value="false">no</option>
</select>

}

if ([0, '0', 'false', false].includes(rawValue)) {
return false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking "How could we do this with only one comparison?" and my brain went to

Boolean(JSON.parse(rawValue.toString()))

But surely that would stupid right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that does not work, because if the rawValue is not 1/0/true/false, then we want to just return that raw value. With that code, I don't think that is possible 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I do see that. To me though, the use case of this modifier seems fundamentally contradictory to ever having it be any other values. I'd rather have it fail early (at a json parsing error) than continue to have the bad value end up somewhere else somehow.

But that's an opinionated design.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The x-model.number works like that as well so I thought it might be best to let it behave in the same way

function safeParseNumber(rawValue) {
let number = rawValue ? parseFloat(rawValue) : null
return isNumeric(number) ? number : rawValue
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense 👍

@calebporzio
Copy link
Collaborator

Going to close this because it adds a fair bit of code and I haven't heard much demand for it.

Here's a workaround for now:

<div x-data="{
        bar: false,
        get selectedBar() {
            return this.bar.toString()
        },
        set selectedBar(value) {
            this.bar = value === 'true' ? true : false
        },
    }">
        <select x-model="selectedBar">
            <option value="true">yes</option>
            <option value="false">no</option>
        </select>
    </div>

@calebporzio calebporzio reopened this Nov 11, 2023
@calebporzio
Copy link
Collaborator

Thanks for this PR. I've resurrected it and fixed a small bug and we're good to go. Thanks!

@calebporzio calebporzio merged commit 95b4b7f into alpinejs:main Nov 11, 2023
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants