Search code examples
phpformsform-control

How can I get the array index of a button I clicked out of multiple buttons


I have a form for a shopping cart that lists the details of each stored item by iteration using $_SESSION. This form consists of same multiple form controls including <button> elements for cancellation.

The problem I'm faced with is I cannot get PHP to identify which cancellation <button> was clicked, so I'm unable to specify the item to delete from the form.

The code of the form controls goes:

......

if(isset($_SESSION[$i]['stocks']) && $_SESSION[$i]['stocks'] !== ''):
echo '<dl><dt>Quantity</dt><dd><input name="stock[]" type="text" value="'.$_SESSION[$i]['stocks'].'"></dd></dl>';
endif;
echo '<button name="cancel[]">Cancel</button>';
......

The cancel button has an name attribute in array format and also running var_dump returns all of the content of $_SESSION[].

Please help me find any ways to identify which cancel button was clicked.

Thanks for reading this.


Solution

  • Every HTML button element can have a value attribute. Just fill it with the identifier you need to identify your cancel button.

    <button name="cancel" value="<?= htmlspecialchars($i) ?>" type="submit">
        Cancel
    </button>
    

    When submitting the form you can access the identifier with $_POST['cancel'] in your php script.

    The button and its value is only submitted if the button was used to submit the form. You have to use the type attribute to submit the form.

    When using AJAX (for god 's sake don 't use jQuery!) you don 't have to use the type attribute when setting an event listener on the button. Just read out the value and use it as query argument for your request.

    <button name="cancel" value="<?= htmlspecialchars($i) ?>">
        Cancel
    </button>
    <script>
    let buttons = document.querySelectorAll('button[name="cancel"]');
    buttons.forEach(button => {
        button.addEventListener('click', async (event) => {
            event.preventDefault();
            let value = event.currentTarget.value;
            let response = await fetch('cancel.php?item=' + value);
            ...
        });
    });
    </script>
    

    The example sets an event listener that listens on a click event and fires an async request to cancel.php with the query argument, e.g. ìtem=1. The value is determined dynamically from the value attribute of the button with each click and is available to you in the PHP script with $_GET['item'].

    The example shown is not good because it sets an event listener for each button. This can lead to performance problems of the HTML page depending on the number of buttons. It would be better if a single event listener is set on the parent form element, which is then used to determine the respective buttons. The example shown is only intended as an illustration.

    For details using the JavaScript fetch API: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch