nextui icon indicating copy to clipboard operation
nextui copied to clipboard

[BUG] - When click select all in table, it returns 'ALL' instead of keys

Open AlejandroSanchez90 opened this issue 1 year ago • 7 comments

NextUI Version

2.0.28

Describe the bug

Im using the table component, and when i select one row at a time, i get the actual row key, but if i select all using the checkbox at the top, then ill get all, this is bad, because, if im using pagination, and there are 2 items, then it will select all items in the state, i know i can separate the state to have 1 for all my keys, and other per pagination, but this is double work, is there a way to always return keys on select all?

Your Example Website or App

No response

Steps to Reproduce the Bug or Issue

Select all in a table returns "all"

Expected behavior

return array of keys

Screenshots or Videos

No response

Operating System Version

windows

Browser

Chrome

AlejandroSanchez90 avatar Nov 15 '23 22:11 AlejandroSanchez90

+1, having a issue when i need to send the table data to a external api and all i can send is that 'all' string, only works if i select all of them one by one, also can't remove the select all box, making user error very likely.

cassiothacosta avatar Nov 16 '23 13:11 cassiothacosta

I had that issue and a dumb workaround when I was creating a file browser, I used NextUI's Table as a list view for files and I wanted all views to use the same state variable so I did this:

useEffect(() => {
    if(selectedRows === 'all') {
        let allRows;
        allFiles.forEach(file => allRows.push(file.fileID,toString()));
        setSelectedRows(new Set(allRows));
    }
}, [selectedRows])

NOTE: I did add a toString() since NextUI's selectedKeys only reads from strings. I know this isn't a solution but maybe you could implement this until there's a fix.

Oolix avatar Nov 30 '23 20:11 Oolix

I had that issue and a dumb workaround when I was creating a file browser, I used NextUI's Table as a list view for files and I wanted all views to use the same state variable so I did this:

useEffect(() => {
    if(selectedRows === 'all') {
        let allRows;
        allFiles.forEach(file => allRows.push(file.fileID,toString()));
        setSelectedRows(new Set(allRows));
    }
}, [selectedRows])

NOTE: I did add a toString() since NextUI's selectedKeys only reads from strings. I know this isn't a solution but maybe you could implement this until there's a fix.

yeah this is the normal aproach, the problem is when you have pagination or async loading, in this case you need more logic

AlejandroSanchez90 avatar Dec 06 '23 03:12 AlejandroSanchez90

Is there any progress or update related to this?

Adrian2jr avatar Feb 07 '24 20:02 Adrian2jr

I had that issue and a dumb workaround when I was creating a file browser, I used NextUI's Table as a list view for files and I wanted all views to use the same state variable so I did this:

useEffect(() => {
    if(selectedRows === 'all') {
        let allRows;
        allFiles.forEach(file => allRows.push(file.fileID,toString()));
        setSelectedRows(new Set(allRows));
    }
}, [selectedRows])

NOTE: I did add a toString() since NextUI's selectedKeys only reads from strings. I know this isn't a solution but maybe you could implement this until there's a fix.

yeah this is the normal aproach, the problem is when you have pagination or async loading, in this case you need more logic

This wouldn't filter the disabled ones. How to exclude the disabled rows?

jim-king-2000 avatar Feb 22 '24 10:02 jim-king-2000

My implimentation for this:

        onSelectionChange={(keys) => {
          if (typeof keys === "string" && keys === "all") {
            setSelectedKeys(
              new Set(paginatedCompanies.map((company) => company.orgNumber))
            );
          } else {
            setSelectedKeys(new Set(keys));
          }
        }}

checking if selected rows = "all"

jenslys avatar Apr 25 '24 12:04 jenslys

Any updates on this?

I've tried both suggested solutions and it does update the selection states of the individual products, but then I'm still encountering some issues:

  • The checkboxes from each row in the table aren't getting updated when selecting all, which makes it seem like you haven't got anything selected, even though the state has all id's in them.
  • You can then reselect them which would result in them being added again in the state and a total selection that's a higher number then the total items you have in the table.
  • When you have a selected a row and then press the toggle select all, it will update the state to select all, while it should deselect them all if you have something selected

For the deselecting all when all rows are already selected I've tweaked the code a bit, but it's still really buggy:

OnSelectionChange={(keys) => {
    if (keys === "all" || keys.size === filteredItems.length) {
        // Toggle selection: if all currently filtered items are selected, deselect all
        if (selectedKeys.size === filteredItems.length) {
            setSelectedKeys(new Set());
        } else {
            // Select all filtered items
            setSelectedKeys(new Set(filteredItems.map(item => item.id)));
        }
    } else {
        // Handle individual selection changes
        setSelectedKeys(new Set(keys));
    }
    console.log("Selected Keys: ", keys);
}}

lldiegon avatar May 10 '24 05:05 lldiegon

Hello from Venezuela This is my solution to get item ID's from the selected items

The object selectedKeys contains the information

`useEffect(() => {
	if (Array(selectedKeys) && (selectedKeys as any) !== 'all') {
		selectedKeys.forEach((e) => {
			console.log(e) // Get selected IDs from the table
		})
	}

	if ((selectedKeys as any) === 'all') {
		console.log(filteredItems) // Get all filtered items from the table
	}
}, [selectedKeys, filteredItems])`

Now you can write a function for handle those selected keys

async function handleDelete(){
         const response = await DeleteItems(selectedKeys)
}

or

async function handleDelete(){
         const items = []
         if (Array(selectedKeys) && (selectedKeys as any) !== 'all') {
            selectedKeys.forEach((e) => {
		console.log(e) // Get selected IDs from the table
                items.push(e)
	    })
         }
         const response = await DeleteItems(items)
}

miguelxmarquez avatar Jun 15 '24 21:06 miguelxmarquez