skip to Main Content

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.

2

Answers


  1. 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

    Login or Signup to reply.
  2. First you have to identify each row with some unique ID/value. Below shown example may help you.

    What I have done here is, I have just added a new custom attribute to button tag called data-target. Along with this, I have added a custom class actionBtn to identify all such buttons in JS.

    ......
    
    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;
    
    // you can change the array element with unique ID or unique value for each row instead of `$_SESSION[$i]['stocks']`
    echo '<button class="actionBtn" name="cancel[]" data-target="'.$_SESSION[$i]['stocks'].'">Cancel</button>';
    ......
    

    After this, I have created a JS event which triggers a JS function when these buttons clicked. I am assuming you are using jQuery in your project.

    <script>
    $(function(){
         $('.actionBtn').on('click',function(event){
              // cancel all default actions when button clicked.
              event.preventDefault();
             
              // to make you understand, we are creating a variable which stores the values that needs to be removed from `$_SESSION`
              var target_to_remove = $(this).attr('data-target');
    
              // Now I am sending the value to server via AJAX call.
              $.post('<some_destination_url>.php',{target : target_to_remove},function(response){
                 /* ... Do necessary action here after you receive response from server ... */
                 if($.trim(response) == 'success')
                 {
                     alert('success');
                 } else {
                     alert('failed');
                 }
              });
         });
    });
    </script>
    

    Now as the JS part is done, We have to capture the $_POST data in PHP script.

    File: <some_destination_url>.php

      if(isset($_POST['target']))
      {
          for($i=0;$i<count($_SESSION);$i++)
          {
              if($_SESSION[$i]['stocks'] == $_POST['target'])
              {
                   /* if you want to remove whole parent array then use below */
                   //unset($_SESSION[$i]);
    
                   /* if you want to remove 3rd level array element only, then use below */
                   //unset($_SESSION[$i]['stocks']);
    
                   // finally echo something back to JS so that it knows task was successfull or not.
                   echo 'success';
              }
    
          }
          // echo failure if no elements found.
          echo 'item not found';
      }
      else 
      {
         // echo something if `$_POST` is not set.
         echo 'Invalid attempt to remove array element.';
      }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search