linmasahiro / vue3-table-lite

A simple and lightweight data table component for Vue.js 3. Features sorting, paging, row check, dynamic data rendering, supported TypeScript, and more.
https://vue3-lite-table.vercel.app/
MIT License
248 stars 73 forks source link

Select all checkbox does not check if all checkboxes in the table row are checked #66

Closed johnlloyd-dev closed 1 year ago

johnlloyd-dev commented 1 year ago

Hello, Is there a way to make the select all checkbox in the header checked without clicking it if all checkboxes in the table rows are checked? Screenshot 2022-12-06 115712

linmasahiro commented 1 year ago

Hello, Is there a way to make the select all checkbox in the header checked without clicking it if all checkboxes in the table rows are checked? Screenshot 2022-12-06 115712

Hi, @lloyde04102000 Yes, you can reference this example to implement it.

<template>
  <button @click="doCheckedAll">Checked all</button>
  <table-lite
    ref="tableLiteRef"
    :has-checkbox="true"
    ...something...
    @return-checked-rows="updateCheckedRows"
  ></table-lite>
</template>
<script>
    // ...something

    const tableLiteRef = ref();
    const doCheckedAll = () => {
      tableLiteRef.value.setting.isCheckAll = true
    }

    return {
      // ...something
      tableLiteRef,
      doCheckedAll,
    };
</script>
johnlloyd-dev commented 1 year ago

Thank You for your response @linmasahiro. This is good. However, if the header select-all checkbox is checked, then if I am going to uncheck one of the checkboxes in the table row, it remains checked. I tried to put the tableLiteRef.value.setting.isCheckAll = false, but it unchecks all the checkboxes in the table row whenever I uncheck one of the table row checkboxes. Can we do something about it? Your response will be highly appreciated. Thank You.

linmasahiro commented 1 year ago

However, if the header select-all checkbox is checked, then if I am going to uncheck one of the checkboxes in the table row

It's easy, delete tableLiteRef.value.setting.isCheckAll = true and add

tableLiteRef.value.rowCheckbox.forEach(element => {
  element.checked = true;
});

to doCheckedAll(), it's to checked all checkboxes but header select-all checkbox not to active.

Or other method, you can check this issue https://github.com/linmasahiro/vue3-table-lite/issues/65#issuecomment-1322969696 to create a custom header select-all checkbox to control all checkboxes too. Example:

<template>
  <table-lite
    ref="tableLiteRef"
    :has-checkbox="true"
    ...something
    @is-finished="tableLoadingFinish"
    @return-checked-rows="updateCheckedRows"
  ></table-lite>
</template>
<script>
    // ...something

    const tableLiteRef = ref();
    const customHeaderCheckboxEl = ref(null);

    /**
     * Create an new header checkbox element
     */
    const putCustomHeaderCheckboxEl = () => {
      document.getElementsByClassName('vtl-checkbox-th')[0].textContent = "";
      customHeaderCheckboxEl.value = document.createElement("input");
      customHeaderCheckboxEl.value.setAttribute("type", "checkbox");
      customHeaderCheckboxEl.value.addEventListener("click", function () {
        if (customHeaderCheckboxEl.value.checked != tableLiteRef.value.setting.isCheckAll) {
          tableLiteRef.value.setting.isCheckAll = !tableLiteRef.value.setting.isCheckAll;
        } else {
          tableLiteRef.value.rowCheckbox.forEach(element => {
            element.checked = true;
          });
        }
      });
      document.getElementsByClassName('vtl-checkbox-th')[0].append(customHeaderCheckboxEl.value);
    }
    const watchCheckboxesState = () => {
      let isAllChecked = true;
      tableLiteRef.value.rowCheckbox.forEach((element) => {
        if (!element.checked) {
          isAllChecked = false;
        }
      });
      customHeaderCheckboxEl.value.checked = isAllChecked;
    }

    /**
     * Row's checkbox state changed event
     * 
     * @param {array} rowsKey 
     */
    const updateCheckedRows = (rowsKey) => {
      console.log(rowsKey);
      watchCheckboxesState();
    };

    /**
     * Loading finish event
     */
    const tableLoadingFinish = (elements) => {
      table.isLoading = false;
      putCustomHeaderCheckboxEl();
    };

    return {
      // ... something
      tableLiteRef,
      tableLoadingFinish,
      updateCheckedRows,
    };
</script>

This example is working and you hope, but not good idea I think. :(

linmasahiro commented 1 year ago

Hi, @lloyde04102000 , is this issue resolved now? :)