0

I am generating an array of objects and then Outputting these into a list, each objects has a checkbox that then adds it to the changeableElements array if it is checked

I am having trouble getting it to show only objects that are added to the array to appear as checked, and also disabled all of the other checkboxes once 3 are selected, how can I do this?

             const [items, setItems] = useState(
               [...Array(301)].map(
                    (_, i) => ({ name: `element ${i}`, selected: false, id: `element_uid_${i}}` }),
                 ),
                   )
             const [changeableElements, setchangeableElements] = useState([])
             const updatechangeableElements = (item) => {
              setchangeableElements(changeableElements.concat(item))
             }

                    <ElementsListWrap>
          {items.slice(0, itemsLimit !== null ? itemsLimit : Infinity)
          .filter((item) => new RegExp(`^${searchValue.toLowerCase()}`).test(item.name))
          .map((item) => (
            <div
              key={item.name}
            >
              {console.log('bkakask',changeableElements.filter((i) => item.id === i.id))}
              <ElementWrap>
                <Checkbox
                  key={item.name}
                  onChange={() => updatechangeableElements({ ...item, selected: true })}
                  type="checkbox"
                  checked={changeableElements.filter(i => item.id === i.selected === true).length > 0}
                  disabled={items.filter((i) => i.selected).length > 2 && item.selected !== true}
                />
                {console.log(changeableElements.map(bla => item.id === bla.id))}
                {item.name}
              </ElementWrap>
            </div>
            ),
          )}
        </ElementsListWrap>

2 Answers 2

1

You are setting checked to the result of filter which will always be an array (sometimes empty), so always truthy.

You likely need to use something like this

    <Checkbox
       key={item.name}
       onChange={() => updatechangeableElements({ ...item, selected: true })}
       type="checkbox"
       checked={changeableElements.find(i => item.id === i && item.selected === true)}
       disabled={items.filter((i) => i.selected).length > 2 && item.selected !== true}
    />

update

This should handle both checked and disabled states.

.map((item) => {
    const isChecked = item.selected && changeableElements.some(i => item.id === i);
    const isDisabled = !isChecked && (items.filter((i) => i.selected).length > 2);
    return (
      <div
        key={item.name}
      >
        <ElementWrap>
          <Checkbox
            key={item.name}
            onChange={() => updatechangeableElements({ ...item, selected: true })}
            type="checkbox"
            checked={isChecked}
            disabled={isDisabled}
          />
          {item.name}
        </ElementWrap>
      </div>
      )},

Sign up to request clarification or add additional context in comments.

4 Comments

I suggest using array::find instead as it does return a truthy value if found, undefined if not. Also, selected is already a boolean, so checking it against true is redundant, but at this point I think the OP could simply check just the selected value. Not really sure what's going on with the array as mapping isn't overt.
@DrewReese even better (this way it will stop traversing the array once it finds an item, so better performance as well). Updated answer.
I have updated the code to include how im mapping my array, thanks for the answer, the checking works now however the checkboxes are not disabled when over 3 are selected
@tomharrison updated answer with what i believe should handle both cases
0

filter() does not return boolean, and checkbox is checked if checked property is true.

So you might want change the checked section to:

checked={changeableElements.filter(item => item.id === item.selected === true).length > 0}

Instead of:

checked={changeableElements.filter(item => item.id === item.selected === true)}

For disable issue, have you map the items? Or you only render each object in the array? If you only render one item in the array, the condition will never be met.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.