简体   繁体   中英

How to delay form submission

I'm working on a basic webform for my beginning Javascript class. I pretty much have all my expected results (assignment covers input validation and storing elements in an array by name), except for the fact that when I submit the form, I'd like to give a 5 second delay from the time I hit submit to when the page redirects. This delay is so that user will be able to cancel the order.

From what we have learned in class so far, I would expect I perform this action with a setTimeout block of code- though I haven't been able to work that yet. My form submission is dependent on a true/false return value from the called function, and I'd like to delay that true value from hitting so quickly. I've attached my full HTML file but the block of code that I'm wondering why it isn't working in particular is this:

    setTimeout(function() {
                   return true;
               }, 5000);

The first problem I observe when debugging in Chrome is that this doesn't return the True value back to the surrounding code.

I think that something could be done with jQuery to circumvent this but we haven't covered any of that so I'd like to avoid going that route.

```
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta name="description" content="Costello Improved">
    <meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
    <title>Costellos Pasta and Pizza</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <link rel="stylesheet" href="costello.css">
</head>

<body>

    <form name="myForm" action="https://costello-pasta.glitch.me/order" id="myForm" method="POST" onsubmit="return calculateOrder(this)">
        <div class="container">

            <div class="row">
                <div class="col-md-12" id="debug">Costello's Online Orders</div>
            </div>

            <div class="row">
                <div class="col-md-4  label">Pasta Bowl</div>
                <div class="col-md-4"> (basic price: $7.50)</div>
                <div class="col-md-4"></div>
            </div>

            <div class="row">
                <div class="col-md-4  label">Pasta</div>
                <div class="col-md-4">
                    <div><input type="radio" name="pastatype" value="0" />Spaghetti (no extra cost)</div>
                    <div><input type="radio" name="pastatype" value="50" />Fettucine (add 50 cents)</div>
                    <div><input type="radio" name="pastatype" value="75" />Fusilli (add 75 cents)</div>
                </div>
                <div class="col-md-4 msg" id="radioLabel"></div>
            </div>

            <div class="row">
                <div class="col-md-4  label">Sauce</div>
                <div class="col-md-4">
                    <select name="sauce">
                        <option value="0">Pomodoro (no extra cost)</option>
                        <option value="50">Bolognese (add 50 cents)</option>
                        <option value="100">Alfredo (add $1.00)</option>
                    </select>
                </div>
                <div class="col-md-4"></div>
            </div>

            <div class="row">
                <div class="col-md-4  label">Extras</div>
                <div class="col-md-4">
                    <div><input type="checkbox" name="extras" value="200" />Side salad (add $2.00)</div>
                    <div><input type="checkbox" name="extras" value="100" />Bread sticks (add $1.00)</div>
                </div>
                <div class="col-md-4"></div>
            </div>

            <div class="row">
                <div class="col-md-4  label">Name</div>
                <div class="col-md-4"><input type="text" id="name" name="client_name" /></div>
                <div class="col-md-4 msg" id="nameLabel"></div>
            </div>

            <div class="row">
                <div class="col-md-4  label">Phone</div>
                <div class="col-md-4"><input type="text" id="phone" value="" /></div>
                <div class="col-md-4 msg" id="phoneLabel"></div>
            </div>

            <div class="row">
                <div class="col-md-4  label"><input type="submit" value="Order" /></div>
                <div class="col-md-4" id="totalcost"></div>
                <div class="col-md-4 msg" id="submitMessage"></div>
            </div>
        </div>

    </form>

</body>

<script>
    function calculateOrder() {
        var totalCost = 750;

        //Storing Pasta radio buttons into array.  Iterating through array and adding checked selection's value to the total cost. 
        var submitBool = true;
        var pastaArray = document.getElementsByName('pastatype');
        for (var i = 0; i < pastaArray.length; i++) {
            if (pastaArray[i].checked == true) {
                totalCost = totalCost + parseInt(pastaArray[i].value);
            }
            //Validating Pasta input
        }
        if (pastaArray[0].checked == false && pastaArray[1].checked == false && pastaArray[2].checked == false) {
            document.getElementById('radioLabel').innerHTML = "Required field! (You must choose a pasta)";
            submitBool = false;
        } else {
            document.getElementById('radioLabel').innerHTML = "";
        }

        //Storing sauce selection into an array.  Adding price for selected option.
        var sauceArray = document.getElementsByName('sauce');
        totalCost = totalCost + parseInt(sauceArray[0].value);

        //Storing extras selection(s) into an array.  Adding prices for selected options.   
        var extraArray = document.getElementsByName('extras');

        for (var x = 0; x < extraArray.length; x++) {
            if (extraArray[x].checked == true) {
                totalCost = totalCost + parseInt(extraArray[x].value);
            }
        }


        //Validating Name input
        if (document.getElementById('name').value == "") {
            document.getElementById('nameLabel').innerHTML = "Required field!  Enter your name.";
            submitBool = false;
        } else {
            document.getElementById('nameLabel').innerHTML = "";
        }

        //Validating Phone Number Input
        var phone = document.getElementById('phone').value;
        phone = phone.toString();

        if (document.getElementById('phone').value == null) {
            document.getElementById('phoneLabel').innerHTML = "Required field!  Enter your phone number.";
            submitBool = false;
        } else if (phone[3] != "-") {
            document.getElementById('phoneLabel').innerHTML = "Enter in 888-888-8888 format!";
            submitBool = false;
        } else if (phone[7] != "-") {
            document.getElementById('phoneLabel').innerHTML = "Enter in 888-888-8888 format!";
            submitBool = false;
        } else if (phone.length > 12 || phone.length < 12) {
            document.getElementById('phoneLabel').innerHTML = "Enter in 888-888-8888 format!";
            submitBool = false;
        } else {
            document.getElementById('phoneLabel').innerHTML = "";
        }


        //Form runs if input has been valid in all input options
        if (submitBool == false) {

            return false;
        } else if (submitBool == true){
            var preFixed = totalCost / 100;
            var postFixed = preFixed.toFixed(2);


            document.getElementById('totalcost').innerHTML = "Total Bill: $" + postFixed;

            document.getElementById('submitMessage').innerHTML = "Order is being processed, <a>cancel?</a>"

           setTimeout(function() {
               return true;
           }, 5000);
        }

    }

</script>

</html>
```

You can use the onSubmit event and delay the usual functionality. I've created a simple demo thus you can understand it easily. Here after form submission it'll submit the form after 5 seconds, or be canceled if you hit Cancel.

 const myForm = document.getElementById('myForm'); myForm.addEventListener('submit', handleSubmit); var submitTimer; function handleSubmit(event) { console.log('submitTimer set'); event.preventDefault(); submitTimer = setTimeout(() => { this.submit(); console.log('Submitted after 5 seconds'); }, 5000) }; function cancel(){ clearTimeout(submitTimer); console.log('Submit Canceled'); }
 <form id="myForm"> <input type="text" name="name"/> <button type="submit">Submit</button> <button type="button" onclick="cancel()" >Cancel</button> </form>

The setTimeout function calls a function or evaluates an expression after a specified number of milliseconds (in your case 5000). What you did in your code was just to return a boolean without creating a channel to get the value after the time has lapsed. Since this code is sort of "asynchronous" (it takes time), you can use the inbuilt Promise function to get the value. In order words, your code could be restructured to something like this:

getTheBoolValue = () => new Promise((resolve, reject) => {
  setTimeout(function(){
    resolve(true)
  },5000)
})

getTheBoolValue().then(data => console.log(data))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM