show Save-Button when items added

Viewed 191

I would like the save button to appear only when an item is added and when all items are deleted or saved, the button is set to hide.....

Could you tell me how should I implement?

The second question would be how should I programming the save button

enter image description here

Shopping-List Component:

export default function ShoppingList () {
    // Enthält alle values die aus dem Input Element hinzugefügt wurden
    const [items, setItems] = useState([]);
    // Enthält value aus dem Element Input
    const [inputValue, setInputValue] = useState('');

    const AddButtonClick = () => {
        if (inputValue === ""){
            alert("Eingabefeld ist Leer");
        } else {
            // Wird das neue Array zurück in den status gepusht
            setItems(prevState => [...prevState, inputValue]);
            // Setzt den inputValue auf eine leere Zeichenkette zurück
            setInputValue('');
        }
    }


    const deleteButtonClick = (index) => {
        const newItems = items && items.filter((element , i) => i !== index);
        setItems(newItems);
    }

    return(
        <>
            <div className="error">
                <Alert
                    message="Error"
                    description="Eingabefeld ist Leer!"
                    type="error"
                    showIcon
                />
            </div>
            <div className="eingabe">
                <Input value={inputValue} onChange={(event) => setInputValue(event.target.value)}
                       name='input'
                       className='addItemInput'
                       placeholder="Artikel hinzufügen"
                />
                <Button
                    type="primary"
                    onClick={() => AddButtonClick()}
                >Add</Button>
            </div>
            <div className='itemList'>
                {items.map((item, index) => (
                    <ul className='itemContainer'>
                        <li className='item-name'>
                            {item}
                        </li>
                        <div className='delete-btn'>
                            <Button type="primary" danger onClick={() => deleteButtonClick(index)}>
                                Delete
                            </Button>
                        </div>
                    </ul>
                ))}
                <div className="speichernBtn">
                    <Button
                        type="primary"
                    >Save
                    </Button>
                </div>
            </div>
        </>
    )
}
3 Answers

You could just use conditional rendering to make this work. This for example will only render the button if there are items in the list.

Please see the edit below for an improved version

{items.length !== 0 && (
    <div className="speichernBtn">
      <Button type="primary">Save</Button>
    </div>
)}

The condition could of course be more complex if needed. Another way would be to hide the button using some CSS to set the display property.

Many component libraries also have props to do this kind of thing i.e. applying CSS to a component. You have not mentioned which component library you are using but if you were to use Material UI you could use the sx prop to do this.

<div className="speichernBtn">
  <Button 
    type="primary" 
    sx={{ display: items.length !== 0 ? "inline-block": "none" }}>
    Save
  </Button>
</div>;

When using Chakra UI you could just use the display prop directly. But you would need to check out the documentation of your component library to see how this can be done.

Edit

As mrpbennett pointed out you should use a ternary operator instead of && to make sure nothing is rendered otherwise 0 could be rendered. Here a link to a blog article explaining this in more depth as provided by mrpbennett.

So this would be the code following this advise.

{items.length !== 0 ? (
    <div className="speichernBtn">
      <Button type="primary">Save</Button>
    </div>
  ) : null}

This is how I would do it, because personally I am not a big fan of the inline ternary.

add the following method:

const isItemsEmpty() => {
  return items.length > 0
}

Then for the button element use the following:

<Button
  type="primary"
  danger
  onClick={() => deleteButtonClick(index)}
  hidden={isItemsEmpty()}
  disabled={isItemsEmpty()}
>
Delete
</Button>

How I would approach this is first I would create a constant that tells you if you should show your button or not:

const [showButton, setShowButton] = useState(false);

After this, you should check if showButton is true in all places where you only want to show your button if that variable is true. For example, you would do something like this:

{showButton && 
<Button type="primary" onClick={() => AddButtonClick()}>
    Add
</Button>}

Then you would need to modify the state in all functions that are called when you need to show the button:

const deleteButtonClick = (index) => {
        const newItems = items && items.filter((element , i) => i !== index);
        setItems(newItems);
        showButton(true);
    }

And do the opposite when you don't want it to be shown, for example:

function handleSave(){
    showButton(false);
}
Related