bigskysoftware / htmx

</> htmx - high power tools for HTML
https://htmx.org
Other
38k stars 1.29k forks source link

Rework "find" extended CSS selector #1597

Open Telroshan opened 1 year ago

Telroshan commented 1 year ago

I must admit I'm not very satisfied with the current find keyword closest seems obvious because it's going to retrieve the closeST element, so obviously only one.

But when it comes to find, maybe is it because I'm not a native English speaker, but I "feel" it differently depending on the context

I find it confusing because the word find itself doesn't indicate if it's going to be one, or many elements

So, would it make sense to add a new keyword to make that clearer ? Which would btw add the feature of listening on multiple elements using from as mentioned above Examples that come to mind:

Feel free to suggest other ideas, especially given that my English isn't that great

For retro-compatibility, I would then suggest to keep find being an alias of whatever new keyword that would replace it, but deprecate it / undocument it

Let me know

xhaggi commented 1 year ago

Calling find in querySelectorAllExt seems wrong to me, because the function name querySelectorAllExt suggests something else. For next and previous, querySelectorAll is also used. What if we use findAll as a quick fix here? This way you could use :first-child if you are only interested in the first element e.g. from:find input:first-child.

BTW: renaming find to children sounds reasonable to me.

Edit: I was wrong, next and previous return a single item. I would also expect both to return a list of elements.

Telroshan commented 1 year ago

Considering the following situation:

<div hx-trigger="input from:find input">
    <div>Something</div>
    <input type="text">
    <input type="text">
</div>

With the current find keyword, the parent div woud listen for the input event on the first of the two text inputs.

With your PR though:

So I'm afraid it wouldn't fix the issue here

I agree with you that next and previous should allow the user to retrieve multiple elements if they want to, but here for retro-compatibility purposes as well, I think we'd better add another keyword to differentiate single element retrieval from multiple elements retrieval

xhaggi commented 1 year ago

Meh, you're absolutely right. I don't know why I thought it would return the first element. So let's first discuss what approach we want to take here before I adjust the related PR to it.

What if we used a function-like syntax similar to CSS pseudo-classes :has(), :not(), but without the colons? The old syntax will be deprecated and removed in 2.0.

closest(<selector>) (do we need first-closest() and closest() or does it not make sense?) first-child(<selector>) children(<selector>) first-next(<selector>) next(<selector>) first-previous(<selector>) previous(<selector>)

<div hx-trigger="input from:first-child(input[type="submit"])"></div>
Telroshan commented 1 year ago

I like those ideas

xhaggi commented 1 year ago

I think closest should return only one element

I agree.

I'm not sure about that function syntax with parentheses instead of the current one that is in the form clause

The function syntax feels more natural to me and encloses the selector, as is done in CSS with :has(), etc. But yes, it's a matter of taste. Without we have to rename next() and previous() to something else to be backward compatible.

<div hx-trigger="input from:first-child(input[type="submit"])"></div>

vs.

<div hx-trigger="input from:first-child input[type="submit"]"></div>

I'm worried about the potential confusion that users could face between a first-child clause that wouldn't behave like CSS's :first-child, but maybe am I worrying too much here

Don't worry, the documentation will clarify this :stuck_out_tongue_winking_eye:

Telroshan commented 1 year ago

Either rename next/previous as you said, but we could also

andryyy commented 1 year ago

When using multiple keywords a one-time legacy name info could be helpful, shown in the console.

yaakovLowenstein commented 9 months ago

I've been looking for a find-all selector. Is there any chance of this happening?

papertokyo commented 3 months ago

I spent a lot of time trying to troubleshoot my app due to the lack of a this or children selector.

I have two forms with the same set of inputs; one is for mobile and the other is for desktop, with layouts different enough that the markup cannot be combined.

What I would expect to be able to do is put an hx-trigger attribute on a form element that listens only to child inputs, to avoid conflicting with the other duplicate form in the DOM. Using an ID selector works, but doesn't feel as clean as the rest of HTMX's syntax, so being able to accomplish this kind of scoping with this or children would be welcome.