0

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!

4
  • 1
    Programmatically submitting the form will not include the button pressed. You'll have to store the button's name / value pair somewhere else like an hidden input Commented Feb 6, 2024 at 3:46
  • 1
    Does this answer your question? Javascript Submit does not include Submit Button Value Commented Feb 6, 2024 at 3:48
  • 1
    There's other fancy options like styling checkboxes to look like buttons Commented Feb 6, 2024 at 3:53
  • @Phil Thanks for your comments. That question you linked was helpful, as was your comment about styling checkboxes. I think inputs (checkboxes or radios) are the best solution to my question. Such a solution wasn't provided in the question you have linked. Accordingly, I provide a complete working solution below. Commented Feb 7, 2024 at 6:15

2 Answers 2

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.

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

1 Comment

Thanks. This is good, but a better method is to simply use two radio inputs. This is cleaner and actually shortens the code overall.
1

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>

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.