Skip to content

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!

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