skip to Main Content

A button has a name/value pair. When I click it, after a two-second delay, I want the form to submit with the button’s name/value pair as part of the form data.

Without any Javascript, the form would submit without delay with the button’s name/value pair as part of the form data.

Please see my MWE below.

<!doctype html>
<html lang="en">
    <head>
        <script src="import/jquery-3.6.4.min.js"></script>
        <script>
            $(document).ready(function(){

                var waittime=2;
                var blocksubmit=true;

                $('form').submit(function (evt) {
                    if (blocksubmit) evt.preventDefault();
                });

                $('button').click(function(me){
                    theval = this.value;
                    $('#msg').html('Submitting "'+theval+'" in '+waittime+' seconds.');
                
                    setTimeout(
                        function () {
                            blocksubmit=false;
                            $('form').first().trigger('submit');
                            $('#msg').html('The URL should now display ?'+theval+' at its end.');
                        },
                        1000*waittime
                    );

                });
            });
        </script>
    </head>
    <body>
        <form action="?" method="get">
            <p id="msg">Choose one:</p>
            <button name="choice" value="True">True</button>
            <button name="choice" value="False">False</button>
        </form>
        <p>Expected behavior: Two seconds after clicking a button, the browser loads `?choice=True` or `?choice=False`.</p> 
        <p>Actual behavior: Two seconds after clicking a button, the browser loads `?`. The input value is not included.</p> 
    </body>
</html>

Why is it ignoring the form data set when I click a button? choice is not set when the form submits.

Thanks!

2

Answers


  1. Chosen as BEST ANSWER

    The submit button name/value pair will only be included in the form data if the form is submitted via clicking that submit button.

    Accordingly you need to store that form data elsewhere. Simply convert the two buttons to radio inputs. Now your code is shorter, because you don't need to preventDefault of the form submission!

    <!doctype html>
    <html lang="en">
        <head>
            <script src="import/jquery-3.6.1.min.js"></script>
            <script>
                $(document).ready(function(){
    
                    var waittime=2;
    
                    $("input[name='choice']").click(function(me){
                        theval = this.value;
                        $('#msg').html('Submitting "'+theval+'" in '+waittime+' seconds.');
                    
                        setTimeout(
                            function () {
                                $('form').first().trigger('submit');
                                $('#msg').html('The URL should now display ?'+theval+' at its end.');
                            },
                            1000*waittime
                        );
    
                    });
                });
            </script>
        </head>
        <body>
            <form action="?" method="get">
                <p id="msg">Choose one:</p>
                <input type="radio" name="choice" value="True" id="inputTrue">
                <label for="inputTrue">True</label>
                <input type="radio" name="choice" value="False" id="inputFalse">
                <label for="inputFalse">False</label>
            </form>
            <p>Expected behavior: Two seconds after clicking a button, the browser loads `?choice=True` or `?choice=False`.</p> 
            <p>Actual behavior: Two seconds after clicking a button, the browser loads `?`. The input value is not included.</p> 
        </body>
    </html>
    

    You can use Bootstrap to easily make those radio inputs look like buttons:

    <!doctype html>
    <html lang="en">
        <head>
            <link rel="stylesheet" href="import/bootstrap.min.css" type="text/css" />
            <script src="import/jquery-3.6.1.min.js"></script>
            <script>
                $(document).ready(function(){
    
                    var waittime=2;
    
                    $("input[name='choice']").click(function(me){
                        theval = this.value;
                        $('#msg').html('Submitting "'+theval+'" in '+waittime+' seconds.');
                    
                        setTimeout(
                            function () {
                                $('form').first().trigger('submit');
                                $('#msg').html('The URL should now display ?'+theval+' at its end.');
                            },
                            1000*waittime
                        );
    
    
                    });
                });
            </script>
        </head>
        <body>
            <form action="?" method="get">
                <p id="msg">Choose one:</p>
                <input type="radio" class="btn-check" name="choice" value="True" id="inputTrue" autocomplete="off">
                <label class="btn btn-secondary" for="inputTrue">True</label>
                <input type="radio" class="btn-check" name="choice" value="False" id="inputFalse" autocomplete="off">
                <label class="btn btn-secondary" for="inputFalse">False</label>
            </form>
            <p>Expected behavior: Two seconds after clicking a button, the browser loads `?choice=True` or `?choice=False`.</p> 
            <p>Actual behavior: Two seconds after clicking a button, the browser loads `?`. The input value is not included.</p> 
        </body>
    </html>
    

  2. The issue here is that the form is being submitted before the button’s value can be included in the form data. When the $('form').first().trigger('submit'); line is executed, it submits the form as it is at that moment, which does not include the button’s value because the button click event has not completed yet.

    To fix this, you can create a hidden input field in the form and set its value to the button’s value when the button is clicked. Then, when the form is submitted, the hidden input field’s value will be included in the form data. Like so:

    <!doctype html>
    <html lang="en">
        <head>
            <script src="import/jquery-3.6.4.min.js"></script>
            <script>
                $(document).ready(function(){
                    var waittime=2;
                    var blocksubmit=true;
                    $('form').submit(function (evt) {
                        if (blocksubmit) evt.preventDefault();
                    });
                    $('button').click(function(me){
                        theval = this.value;
                        $('#msg').html('Submitting "'+theval+'" in '+waittime+' seconds.');
                        $('#hiddenInput').val(theval); // Set the hidden input field's value
                    
                        setTimeout(
                            function () {
                                blocksubmit=false;
                                $('form').first().trigger('submit');
                                $('#msg').html('The URL should now display ?choice='+theval+' at its end.');
                            },
                            1000*waittime
                        );
                    });
                });
            </script>
        </head>
        <body>
            <form action="?" method="get">
                <p id="msg">Choose one:</p>
                <button name="choice" value="True">True</button>
                <button name="choice" value="False">False</button>
                <input type="hidden" id="hiddenInput" name="choice"> <!-- hidden input -->
            </form>
            <p>Expected behavior: Two seconds after clicking a button, the browser loads `?choice=True` or `?choice=False`.</p> 
            <p>Actual behavior: Two seconds after clicking a button, the browser loads `?`. The input value is not included.</p> 
        </body>
    </html>
    

    Now the form data will include the choice parameter with the value of the button that was clicked. The URL should now display ?choice=True or ?choice=False at its end, as expected.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search