Search code examples
htmlhtml-tablehyperscript

Hyperscript table selection with select all functionality


I have a small problem and I don't know how to solve it. I want to build a table selection with select all functionality in hyperscript. It's working with one table, but I want to make it work with multiple tables on one page (with templating, so I don't want to use very different ids) so I added in closest <table/>. For most things it's working. For example this is working code for a button above the table:

on selectionChanged
    if length of <input[id^='select_row_']:checked/> === 1 in closest <table/>
        remove @disabled from me
    else
        add @disabled to me
end

In all my rows I do this:

on click
    send selectionChanged to previous <button[id^='delete_button']/>
    send selectionChanged to previous <button[id^='edit_button']/>
    send selectionChanged to previous <input[id^='select_all_']/>
end

This correctly changes the state of the select all input. But if I click the select all checkbox it only changes the ckecked state of the rows to true once and does not change it back.

The code for the select all input is:

on click
    set <input[id^='select_row_']/>'s checked to my.checked in closest <table/>
    send selectionChanged to previous <button[id^='delete_button']/>
    send selectionChanged to previous <button[id^='edit_button']/>
end
    on selectionChanged
        set my.checked to length of <input[id^='select_row_']:checked/> === length of <input[id^='select_row_']/> in closest <table/>
end

The weird thing is that if I remove the in closest <table/> in this code it does work fine, the problem with that is that if I click the select all input of another table it does also select all the rows from other tables.

I would really appreciate a hint. Did I misunderstand the syntax? Thank you.

Update: I thought I found the answer. I don't actually know why it makes a difference but this code is working first but when all rows where selected one by one you can't deselect again:

on click
    if my.checked
        add @checked to <input[id^='select_row_']/> in closest <table/>
    else
        remove @checked from <input[id^='select_row_']/> in closest <table/>
    end
    send selectionChanged to previous <button[id^='delete_button']/>
    send selectionChanged to previous <button[id^='edit_button']/>
    end
    on selectionChanged
        set my.checked to length of <input[id^='select_row_']:checked/> === length of <input[id^='select_row_']/> in closest <table/>
end"

The second case (below on selectionChanged) was and is working correctly without change, but the state of the rows I have to change by adding and removing the checked attribute as a whole, not only setting checked to true or false.

So instead of:

set <input[id^='select_row_']/>'s checked to my.checked in closest <table/>

I now use:

if my.checked
    add @checked to <input[id^='select_row_']/> in closest <table/>
else
    remove @checked from <input[id^='select_row_']/> in closest <table/>
end

This code does change the state correctly from:

<input[id^='select_row_']/> type="checkbox" ...>

to:

<input[id^='select_row_']/> type="checkbox" ... checked="undefined">

and back, and adding checked="undefined" also shows as checked rows, but removing it does not show a change, so all rows stay selected (but as mentioned only in the case I already checked all rows one by one).


Solution

  • Ok, I think now I found the answer. When putting brackets aroung the css selector and adding in closest <table/> inside these brackets everything works as expected:

    set (<input[id^='select_row_']/> in closest <table/>)'s checked to my.checked
    

    With this knowledge I also found out that for the button this code is correct (not the one from my question):

    on selectionChanged
        if length of (<input[id^='select_row_']:checked/> in closest <form/>) === 1
            remove @disabled from me
        else
            add @disabled to me
    end
    

    There were two mistakes: First of all the button was not in the table but in the outer form and in addition brackets were missing with in closest <form/> directly next to the css selector.