User Tools

Site Tools


en:web_development:forms:javascript

This is an old revision of the document!


Web Developent Lesson 8 - Forms

Javascript

Objectives

In this activity you'll learn to use Javascript to

  • temporarily display status messages
  • check form inputs before submitting

Setup

  • We'll continue using 'form.php', 'process_form.php' and 'style.css', which are reproduced below in case you need them.
  • We'll also need a file for Javascript, so create a file called 'form.js' in the same directory as 'form.php'.

form.php

<?php
    include('database.php');

    include('header.php');
    include('menu.php');

    // get list of heroes
    $query = "SELECT * FROM heroes";
    $args  = array();
    $hrslt = $pdo->prepare($query);
    $hrslt->execute($args);

    // get list of movies
    $query = "SELECT movie FROM appearances GROUP BY movie";
    $args  = array();
    $mrslt = $pdo->prepare($query);
    $mrslt->execute($args);
?>
    <main>
        <form name="add_hero" action="process_form.php" method="post">
            <fieldset>
                <legend>Add Hero</legend>
                <ul>
                    <li>
                        <label>Alias:</label>
                        <input type="text" name="alias" size="30" maxlength="50" hint="Iron Man">
                    </li>
                    <li>
                        <label>Identity:</label>
                        <input type="text" name="identity" size="30" maxlength="50" hint="Tony Stark">
                    </li>
                    <li>
                        <label>Side:</label>
                        <ul>
                            <li><input type="radio" name="side" value="Hero" checked> Hero</li>
                            <li><input type="radio" name="side" value="Villain"> Villain</li>
                        </ul>
                    </li>
                    <li>
                        <label>First Appearance:</label>
                        <input type="number" name="year">
                    </li>
                    <li>
                        <label>Source of Power:</label>
                        <select name="power">
                            <option value="Skill">Skill</option>
                            <option value="Biological">Biological</option>
                            <option value="Magic">Magic</option>
                            <option value="Technology">Technology</option>
                            <option value="Mutant">Mutant</option>
                        </select>
                    </li>
                </ul>
                <input type="submit" name="submit" value="Add / Update Hero">
            </fieldset>
        </form>

        <form name="add_appearances" action="process_form.php" method="post">
            <fieldset>
                <legend>Add Appearances</legend>
                <ul>
                    <li>
                        <label>Hero</label>
                        <select name="alias">
<?php
    // display list of heroes
    while($row = $hrslt->fetch()) {
?>
                            <option value="<?php echo $row['alias']; ?>"><?php echo $row['alias']; ?></option>
<?php
    }
?>
                        </select>
                    </li>
                    <li>
                        <label>Movie</label>
                        <ul>
<?php
    // display list of movies
    while($row = $mrslt->fetch()) {
?>
                            <li><input type="checkbox" name="movie[]" value="<?php echo $row['movie']; ?>" id=""> <?php echo $row['movie']; ?></li>
<?php
    }
?>
                            <li><input type="checkbox" name="movie[]" value="new" id=""> <input type="text" name="new_movie"></li>
                        </ul>
                    </li>
                </ul>
                <input type="submit" name="submit" value="Add Appearance">
                <input type="submit" name="submit" value="Delete Appearances">
            </fieldset>
        </form>
    </main>
<?php
    include('footer.php');
?>

process_form.php

<?php
    include('header.php');
    include('menu.php');
    include('database.php');
    
    // check which form
    switch ($_POST['submit']) {
        case 'Add / Update Hero':
            // check whether hero already exists
            $hquery = "SELECT * FROM heroes WHERE alias=?";
            $hargs  = array($_POST['alias']);
            $hrslt  = $pdo->prepare($hquery);
            $hrslt->execute($hargs);
            if($row = $hrslt->fetch()) { // the hero exists
                $query = "UPDATE heroes SET identity=?, hero_villain=?, first_appeared=?, power=? WHERE alias=?";
                $args  = array($_POST['identity'], $_POST['side'], $_POST['year'], $_POST['power'], $_POST['alias']);
                $rslt  = $pdo->prepare($query);
                if($rslt->execute($args)) {
                    $message = "{$_POST['alias']} was updated successfully.";
                } else {
                    $message = "There was a problem updating {$_POST['alias']}.";
                }
            } else {
                $query = "INSERT INTO `heroes` (`alias`, `identity`, `hero_villain`, `first_appeared`, `power`) VALUES (?,?,?,?,?)";
                $args  = array($_POST['alias'], $_POST['identity'], $_POST['side'], $_POST['year'], $_POST['power']);
                $rslt  = $pdo->prepare($query);
                if ($rslt->execute($args)) {
                    $message = "{$_POST['alias']} was inserted successfully.";
                } else {
                    $message = "There was a problem inserting {$_POST['alias']}.";
                }
            }
            break;
        case 'Add Appearance':
            $args = array();
            foreach($_POST['movie'] as $movie) {
                if ($movie == 'new') {
                    array_push($args, $_POST['alias'], $_POST['new_movie']);
                } else {
                    error_log($movie);
                    // check if it exists already
                    $mquery = "SELECT * FROM appearances WHERE alias=? AND movie=?";
                    $margs  = array($_POST['alias'], $movie);
                    $rslt   = $pdo->prepare($mquery);
                    $rslt->execute($margs);
                    if (!$row = $rslt->fetch()) {
                        array_push($args, $_POST['alias'], $movie);
                    }
                }
            }
            error_log(print_r($args, 1));
            $movies = count($args)/2;
            if ($movies > 0) {
                $values = str_repeat('(?,?), ', $movies-1) . '(?,?)';
                $query = "INSERT INTO appearances (alias, movie) VALUES $values";
                error_log("MURRAY: $query    " . print_r($args, 1));
                $rslt  = $pdo->prepare($query);
                if ($rslt->execute($args)) {
                    $message = "$movies appearances were inserted successfully.";
                } else {
                    $message = "There was a problem inserting $movies appearances.";
                }
            } else {
                $checked = count($_POST['movie']);
                $message = "All $checked appearances are already in the database.";
            }
            
            break;
        case 'Delete Appearances':
            $movies = count($_POST['movie']);
            $values = str_repeat('?,', $movies-1) . '?';
            $query = "DELETE FROM appearances WHERE alias=? AND movie IN ($values)";
            $args  = array($_POST['alias']);
            foreach($_POST['movie'] as $movie) {
                array_push($args, $movie);
            }
            error_log($query . print_r($args, 1));
            $rslt = $pdo->prepare($query);
            if ($rslt->execute($args)) {
                $message = "$movies appearances were deleted successfully.";
            } else {
                $message = "There was a problem deleting $movies appearances";
            }
            break;
        default:
            break;
    }
?>
    <main>
        <p><?php echo $message; ?></p>
    </main>
<?php
    include('footer.php');
?>

style.css

ol {
    color: blue;
  }
  
  ol ol {
    font-weight: 700;
  }

ul {
  list-style-type: none;
}

td, th {
  border-width: 1px;
  border-style: solid;
}

td {
  padding: 10px;
}

table {
  border-collapse: collapse;
}

header {
  background-color:indianred;
  border:darkred solid 2px;
  height: 100px;
  position: absolute;
  left: 16%;
  right: 0px;
  top: 0px;
}

nav {
  background-color: burlywood;
  border:yellow solid 2px;
  position: fixed;
  top: 0px;
  bottom: 0px;
  width: 16%;
  left: 0px;
}

main {
  background-color: lightgree;
  border: darkgreen solid 2px;
  position: absolute;
  top: 100px;
  left: 16%;
  right: 0px;
  bottom: 80px;
  overflow: scroll;
  padding: 20px;
}

footer {
  background-color: lightskyblue;
  border: darkblue solid 2px;
  position: absolute;
  bottom: 0px;
  height: 80px;
  left: 16%;
  right: 0px;
}

.content {
  background-color:coral;
  border:orangered solid 2px;
  height: 400px;
  padding: 40px;
  margin: 20px;
  display: inline-block;
  width: 300px;
}

img {
  float: left;
  max-height: 250px;
  border: solid 2px green;
  margin: 20px 20px 20px 0px;
  padding: 10px;
  border-radius: 30px;
}

#album {
  display: flex;
  justify-content:space-between;
  flex-wrap: wrap;
}

video {
  max-height: 250px;
  float: right;
  clear: left;
  margin: 20px 0px 20px 20px;
  padding: 10px;
}

audio {
  margin: 20px 20px 20px 0px;
  padding: 10px 10px 10px 0px;
}

input[type=button] {
  display: block;
}

figcaption {
  display: block;
  text-align: center;
  font-family: 'Arial', sans-serif;
  color: green;
}

label {
  display: inline-block;
  width: 10em;
  text-align: right;
}

input[type=checkbox], input[type=radio] {
  margin-left: 11em;
}

input[type=text], input[type=number], select {
  margin-left: 1em;
}

input[name=new_movie] {
  margin-left: 0em;
}

Single Page Form and Processing

  • Sometimes separating the form from the processing as we've done makes sense because the form is only required once and then you'll show them something different.
  • More often, in my experience, a form adds to existing content that you'll show after submission, so it makes more sense to include the processing code on the same page as the form.
  • We'll do this now. Copy everything in 'process_form.php' excluding the include lines and html code to the top of 'form.php'.
  • 'form.php' should now look like this.
<?php
    include('database.php');
    // check which form
    switch ($_POST['submit']) {
        case 'Add / Update Hero':
            // check whether hero already exists
            $hquery = "SELECT * FROM heroes WHERE alias=?";
            $hargs  = array($_POST['alias']);
            $hrslt  = $pdo->prepare($hquery);
            $hrslt->execute($hargs);
            if($row = $hrslt->fetch()) { // the hero exists
                $query = "UPDATE heroes SET identity=?, hero_villain=?, first_appeared=?, power=? WHERE alias=?";
                $args  = array($_POST['identity'], $_POST['side'], $_POST['year'], $_POST['power'], $_POST['alias']);
                $rslt  = $pdo->prepare($query);
                if($rslt->execute($args)) {
                    $message = "{$_POST['alias']} was updated successfully.";
                } else {
                    $message = "There was a problem updating {$_POST['alias']}.";
                }
            } else {
                $query = "INSERT INTO `heroes` (`alias`, `identity`, `hero_villain`, `first_appeared`, `power`) VALUES (?,?,?,?,?)";
                $args  = array($_POST['alias'], $_POST['identity'], $_POST['side'], $_POST['year'], $_POST['power']);
                $rslt  = $pdo->prepare($query);
                if ($rslt->execute($args)) {
                    $message = "{$_POST['alias']} was inserted successfully.";
                } else {
                    $message = "There was a problem inserting {$_POST['alias']}.";
                }
            }
            break;
        case 'Add Appearance':
            $args = array();
            foreach($_POST['movie'] as $movie) {
                if ($movie == 'new') {
                    array_push($args, $_POST['alias'], $_POST['new_movie']);
                } else {
                    error_log($movie);
                    // check if it exists already
                    $mquery = "SELECT * FROM appearances WHERE alias=? AND movie=?";
                    $margs  = array($_POST['alias'], $movie);
                    $rslt   = $pdo->prepare($mquery);
                    $rslt->execute($margs);
                    if (!$row = $rslt->fetch()) {
                        array_push($args, $_POST['alias'], $movie);
                    }
                }
            }
            error_log(print_r($args, 1));
            $movies = count($args)/2;
            if ($movies > 0) {
                $values = str_repeat('(?,?), ', $movies-1) . '(?,?)';
                $query = "INSERT INTO appearances (alias, movie) VALUES $values";
                error_log("MURRAY: $query    " . print_r($args, 1));
                $rslt  = $pdo->prepare($query);
                if ($rslt->execute($args)) {
                    $message = "$movies appearances were inserted successfully.";
                } else {
                    $message = "There was a problem inserting $movies appearances.";
                }
            } else {
                $checked = count($_POST['movie']);
                $message = "All $checked appearances are already in the database.";
            }
            
            break;
        case 'Delete Appearances':
            $movies = count($_POST['movie']);
            $values = str_repeat('?,', $movies-1) . '?';
            $query = "DELETE FROM appearances WHERE alias=? AND movie IN ($values)";
            $args  = array($_POST['alias']);
            foreach($_POST['movie'] as $movie) {
                array_push($args, $movie);
            }
            error_log($query . print_r($args, 1));
            $rslt = $pdo->prepare($query);
            if ($rslt->execute($args)) {
                $message = "$movies appearances were deleted successfully.";
            } else {
                $message = "There was a problem deleting $movies appearances";
            }
            break;
        default:
            break;
    }

    include('header.php');
    include('menu.php');

    // get list of heroes
    $query = "SELECT * FROM heroes";
    $args  = array();
    $hrslt = $pdo->prepare($query);
    $hrslt->execute($args);

    // get list of movies
    $query = "SELECT movie FROM appearances GROUP BY movie";
    $args  = array();
    $mrslt = $pdo->prepare($query);
    $mrslt->execute($args);
?>
    <main>
        <form name="add_hero" action="process_form.php" method="post">
            <fieldset>
                <legend>Add Hero</legend>
                <ul>
                    <li>
                        <label>Alias:</label>
                        <input type="text" name="alias" size="30" maxlength="50" hint="Iron Man">
                    </li>
                    <li>
                        <label>Identity:</label>
                        <input type="text" name="identity" size="30" maxlength="50" hint="Tony Stark">
                    </li>
                    <li>
                        <label>Side:</label>
                        <ul>
                            <li><input type="radio" name="side" value="Hero" checked> Hero</li>
                            <li><input type="radio" name="side" value="Villain"> Villain</li>
                        </ul>
                    </li>
                    <li>
                        <label>First Appearance:</label>
                        <input type="number" name="year">
                    </li>
                    <li>
                        <label>Source of Power:</label>
                        <select name="power">
                            <option value="Skill">Skill</option>
                            <option value="Biological">Biological</option>
                            <option value="Magic">Magic</option>
                            <option value="Technology">Technology</option>
                            <option value="Mutant">Mutant</option>
                        </select>
                    </li>
                </ul>
                <input type="submit" name="submit" value="Add / Update Hero">
            </fieldset>
        </form>

        <form name="add_appearances" action="process_form.php" method="post">
            <fieldset>
                <legend>Add Appearances</legend>
                <ul>
                    <li>
                        <label>Hero</label>
                        <select name="alias">
<?php
    // display list of heroes
    while($row = $hrslt->fetch()) {
?>
                            <option value="<?php echo $row['alias']; ?>"><?php echo $row['alias']; ?></option>
<?php
    }
?>
                        </select>
                    </li>
                    <li>
                        <label>Movie</label>
                        <ul>
<?php
    // display list of movies
    while($row = $mrslt->fetch()) {
?>
                            <li><input type="checkbox" name="movie[]" value="<?php echo $row['movie']; ?>" id=""> <?php echo $row['movie']; ?></li>
<?php
    }
?>
                            <li><input type="checkbox" name="movie[]" value="new" id=""> <input type="text" name="new_movie"></li>
                        </ul>
                    </li>
                </ul>
                <input type="submit" name="submit" value="Add Appearance">
                <input type="submit" name="submit" value="Delete Appearances">
            </fieldset>
        </form>
    </main>
<?php
    include('footer.php');
?>
  • For this to work, we need to direct the forms to this page when submitted.
  • Update the action in each form to 'form.php'.
        <form name="add_hero" action="form.php" method="post">
        <form name="add_appearances" action="form.php" method="post">
  • We're missing a place to display the status message. Add a tag at the top of <main>.
        <div id="status">
            <p><?php echo $message; ?></p>
        </div>
  • Save, upload and check that you can see the message.
  • Then let's add some CSS to make it clear it's a status message.
#status {
  background-color: rgb(238, 157, 157);
  border: darkred 1px solid;
  color: darkred;
  margin-bottom: 20px;
  padding-left: 20px;
}
  • The colours make it stand out, and the margin and padding give it some space to make it readable.
  • Save and upload the files and submit something to ensure you're happy with the way it looks. Feel free to change it until you are.

Timer

  • We need to link Javascript, which we can do simply by naming the page because we've added a link in 'header.php' already to link Javascript for each page.
    $page = "form";
    include('header.php');
  • Open 'form.js'.
  • We'll want the message to show (if there is one) for a short time, then make it disappear.
  • There's no point doing this until the page is ready, so we'll set our code to run on window.onload.
window.onload = function () {
    
}
  • Let's name the tag so we don't have to keep typing out the full code.
window.onload = function () {
    var status = document.getElementById('status');
}
  • Now we want to set a timer for 10 seconds (or choose a time that suits you).
  • Unlike PHP and most other languages, Javascript doesn't wait for each line of code to execute before moving on. It sets a line of code to run and then goes immediately on to the next. This means that code saying 'wait for 10 seconds' won't have any effect.
  • Instead, we put the code we want to delay inside a function and use setTimeout to wait 10s before running the function.
  • Javascript counts in milliseconds, so 10s is 10000.
  • Add this code after setting 'status'.
    setTimeout(function () {

    }, 10000);
  • This says to wait 10000ms then run the function inside {} .
  • In our case, our function is simply to remove the 'status' div from the page.
  • Add this inside the {} .
        status.style.display = 'none';
  • Save and upload the code, then run to see the effect.
  • The code disappears after 10s as we want, but if there's no message, it shows an ugly red block for 10s, which isn't a great user experience.
  • Let's hide the status using CSS.
#status {
  background-color: rgb(238, 157, 157);
  border: darkred 1px solid;
  color: darkred;
  margin-bottom: 20px;
  padding-left: 20px;
  display: none;
}
  • Then we can use Javascript to display the status if it actually has content.
window.onload = function () {
    var status = document.getElementById('status');
    if (status.firstElementChild.innerHTML != '') {
        status.style.display = 'block';
    }
    setTimeout(function () {
        status.style.display = 'none';
    }, 10000);
}
  • The new lines (3-5) check whether there is any code inside the <p> element (the firstChildElement of 'status'), and if so, sets the display to 'block'.
  • Save and upload the code to make sure it works to your satisfaction.

Form Verification

  • Remember that we added some code in the 'Add Appearances' form to check whether there were any movies to add?
  • We did that to avoid sending a bad query to the database.
  • In a large system, many bad queries will slow down the site for everyone, which makes for a bad experience.
  • We therefore want to check everything before sending it on. We should also have done this for the 'Add Hero' form, but I usually do this step last because if it's better not to send a bad query to the database, it's also better not to send bad data to the server.
  • We can use Javascript on the user's PC to check that data is good before sending the data to the server.
  • To do this, we can catch the 'submit' requests and hold it until we're ready, but it's simpler to change the 'submit' input to a 'button' input. Do this for all our 'submit' inputs.
                <input type="button" name="submit" value="Add / Update Hero">
                <input type="button" name="submit" value="Add Appearance">
                <input type="button" name="submit" value="Delete Appearances">
  • Then we can call functions for each to verify the data and submit when we're ready.
                <input type="button" name="submit" value="Add / Update Hero" onclick="verifyAddHero()">
                <input type="button" name="submit" value="Add Appearance" onclick="verifyAddAppearance()">
                <input type="button" name="submit" value="Delete Appearances" onclick="verifyDeleteAppearance()">

Required Fields

  • Our 'heroes' table in the database requires that all fields contain content.
  • Required fields are generally denoted by a red asterisk, which we can add with a combination of HTML and CSS.
                        <label>Alias:<span class="required">*</span></label>
                        <label>Identity:<span class="required">*</span></label>
                        <label>Side:<span class="required">*</span></label>
                        <label>First Appearance:<span class="required">*</span></label>
                        <label>Source of Power:<span class="required">*</span></label>
.required {
  color: red;
  vertical-align: super;
}
  • vertical-align: super is the CSS equivalent of the <sup> tag to make the asterisk superscript.
  • We can use Javascript to check that all required fields are completed before submitting the form.
  • In 'form.js', add a function called 'verifyAddHero'.
function verifyAddHero() {

}

Text Input

  • Let's start with the check for the alias.
    message = "";
    if (document.getElementsByName('alias')[0].value == "") {
        message += "The alias is required. ";
    }
    console.log(message);
  • document.getElementsByName('alias') is a list of all elements named 'alias'.
  • We want the first, so we use [0].
  • Then if the content is empty, we want to create a message reminding the user that 'alias' is required.
  • Except, we don't want to create it here because we want a message for each of the missing inputs.
  • Instead, we create the message variable first, then add a message to it if necessary.
  • console.log(message); will display the message in the console so you can see the result now. We'll add the message to the 'status' block later.
  • Save, upload and submit the form without an alias to check that it works.
  • Let's do the same for 'identity'.
    if (document.getElementsByName('alias')[0].innerHTML == "") {
        message += "The alias is required. ";
    }
    if (document.getElementsByName('identity')[0].innerHTML == "") {
        message += "The identity is required. ";
    }
    console.log(message);
  • We don't need to add a check for 'side' or 'power' because we automatically select an option and there is no way to select nothing.

Console Commands

  • We do need to check for a 4-digit number in the 'year' input.
  • This is quite tricky, so open your console and type the following.
document.getElementsByName('year')[0]
  • You'll see some grey text underneath showing you details of the 'year' input.
  • Press 'Enter' and you'll get the whole object with all its information and functions.
  • Press the up arrow to restore the text you just entered.
  • You can now add to this text in any way you like.
  • Add '.value' at the end to see the value of the input field.
  • Type a number into the field and press 'Enter' in the console to see the number returned there.
  • Before we go further, let's give the console a command to assign the value to a variable.
  • Press the up arrow to get the value again, and add 'year = ' at the front and ';' at the back as follows.
year = document.getElementsByName('year')[0].value;
  • You'll see the value you've entered.
  • Type 'year' and see that value again. Your console now knows that 'year' is the value in the 'year' field.

Comparisons

  • Now change the number to text and see that it shows "" for the same command ('year'), so we have a problem.
  • We need first to check whether there is any recognisable input at all.
  • Try the following in the console.
document.getElementsByName('year')[0].value == ""
  • You should see 'True'.
  • == is a comparison test, which returns 'True' if the expressions on either side are the same and 'False' otherwise. So this statement means 'the year is empty.'

Check Number Length

  • Change the year to a number.
  • Type the following into the console and check that it shows the number of digits in your number.
year.length
  • You should recognise this from earlier lessons. Here, .length doesn't count the number of elements in an array. It counts the number of characters in text or digits in a string.
  • We want a message to appear if the number is anything other than 4 digits. Try
year.length == 4
  • You should see the opposite of what we want. It will show 'True' if 'year' is a 4-digit number and 'False' otherwise. We need to use '!' to turn it around. Try
!year.length == 4
  • You should see that this doesn't work. Rather than taking the opposite of the whole statement year.length == 4, this takes the opposite of year.length and compares it to 4.
  • To make '!' apply to the whole expression we need to enclose it in ()
!(year.length == 4)
  • Try a few numbers to ensure that works to your satisfaction.

Combining Expressions

  • Now, since we want to write a message in both cases 'if the entered value is empty (not a number) OR if the number is NOT 4 digits' we need to combine them.
  • We can replace the 'OR' in the above expression with || in Javascript. The final expression will look like this.
if ((year == "") || !(year.length == 4))
  • Although we don't need () around the first expression, keeping the two parts consistent helps reduce confusion.
  • For comparison, a logical 'AND' is written as && . We could say the above as 'if the entered value is NOT BOTH a number AND 4 digits long', which we would write as if (!(year == "") && (year.length == 4)).
  • Try this and use the expression you're most comfortable with.
  • We can now add this code into our verifyAddHero function.
    var year = document.getElementsByName('year')[0].value;
    if ((year == "") || !(year.length == 4)) {
        message += "The first appearance is required and must be a 4-digit year. ";
    }
  • Test this to make sure it works as you expect.

Display Message

  • Finally, we need to display the message.
    var status = document.getElementById('status');
    if (message == "") {
        console.log('ready to submit');
    } else {
        status.firstElementChild.innerHTML = message;
        status.style.display = 'block';
    }
  • I've identified the 'status' element first because I'll use it a couple of times.
  • If the message is blank (ie all fields have an entry) then we are ready to submit the form (or do further checks) but for the moment, we just display a message in the console.
  • If there is a message, then we need to display that for the user. This time we're not removing the message after 10 seconds.
  • Save, upload and submit the form with various fields complete. Check that the response is as expected.

Deferred Submission

  • Try this code in your console.
document.getElementsByName'add_hero')[0].submit()
  • You should see a message that says this 'is not a function'.
  • This is because we've named our form buttons 'submit'.
  • By naming them 'submit' we've overwritten the function 'submit()'.
  • We can easily fix this by renaming our buttons 'formSubmit' in 'form.php'.
                <input type="button" name="formSubmit" value="Add / Update Hero" onclick="verifyAddHero()">
                <input type="button" name="formSubmit" value="Add Appearance" onclick="verifyAddAppearance()">
                <input type="button" name="formSubmit" value="Delete Appearances" onclick="verifyDeleteAppearance()">
  • Our processing code will no longer recognise the data, though, so we need to reflect this change in the processing code in the 4th line from the top.
    switch ($_POST['formSubmit']) {
  • Now replace console.log('ready to submit'); in 'form.js' with the submit command you tested in the console.
    var status = document.getElementById('status');
    if (message == "") {
        document.getElementsByName('add_hero').submit();
    } else {
        status.firstElementChild.innerHTML = message;
        status.style.display = 'block';
    }
  • Save, upload and test that it works as you expect.

Selected Value

  • Let's set up the second form to submit new appearances.
function verifyAddAppearance() {
    message = "";
}
  • To show how we can check the value of a Select Box, let's first add an empty option to the box in 'form.php'.
                        <label>Hero</label>
                        <select name="alias">
                            <option value=""></option>
<?php
    // display list of heroes
    while($row = $hrslt->fetch()) {
?>
                            <option value="<?php echo $row['alias']; ?>"><?php echo $row['alias']; ?></option>
<?php
    }
?>
                        </select>
  • See the new empty option in the 3rd line?
  • In the console, create a variable called 'alias' for the Select Box value.
alias = document.getElementsByName('alias')[1].value;
  • Remember that this is the second field we've named 'alias' in the page, so we need to use the index of [1].

Not Equal

  • We can check if the value is empty by typing alias == "".
  • So we can add code to show a message as follows.
function verifyAddAppearance() {
    var message = "";
    var alias = document.getElementsByName('alias')[1].value;
    if (alias == "") {
        message += "The Hero is required. ";
    }
}

Checkbox Status

  • Checking a checkbox is more complex in standard Javascript. You need to check each of the values to see which are checked.
  • First we need to set a variable 'movie' for all the checkboxes.
  • If you try var movie = document.getElementsByName('movie[]')[0]; in the console you'll see that it is 'undefined', so we need to find another way.
  • Try this in your console.
document.getElementById('movieList').getElementsByTagName('input')[1]
  • You should see the second movie highlighted and <input id="" type="checkbox" name="movie[]" value="Iron Man"> element shown in the console.
  • We can check whether this movie is selected by doing this.
document.getElementById('movieList').getElementsByTagName('input')[1].checked
  • Try that yourself.

While Loop

  • Now, to loop through all the list items, we can do this.
    for (n = 0; n < movieList.length; n++) {
        
    }
  • There's not always need to check every checkbox, though, and for a long list this could take time. As soon as we know one of them is checked, we can stop.
  • For this, we can use a 'while statement'.
  • A 'while statement' says to do something while a condition is true.
  • In this case, we need to check that the checkbox actually exists (n < movieList.length will do this) AND that the movie isn't checked, which we can test with <html>!movieList[n].checked).
  • Our loop is then as follows.
    while((n < movieList.length) && (!movieList[n].checked)) {
        n++;
    }
  • Copy this into your 'verifyAddAppearance' function.
  • Now, if we actually get all the way through the list and have found nothing checked, we want to add a message, but if we do find something, we want to stop it.
  • Our 'message' variable isn't very useful for this, so we need another.
  • Create a variable called 'NoAppearance' to track the number of unchecked movies.
    var message  = "";
    var noAppearance = 0;
  • We can then increment the number every time we find an unchecked box.
    while((n < movieList.length) && (!movieList[n].checked)) {
        noAppearance++;
        n++;
    }
  • At the end, we can compare the number of unchecked boxes with the total number of movies. If it's less, then at least one is checked. Otherwise, if noAppearance is equal to the number of movies, we need to show a message.
    if (noAppearance == movieList.length) {
        message += "You need to add at least one movie. ";
    }
  • Finally, we can determine whether to submit the form or show a message in the same way as for the previous form.
    var status = document.getElementById('status');
    if (message == "") {
        document.getElementsByName('add_hero').submit();
    } else {
        status.firstElementChild.innerHTML = message;
        status.style.display = 'block';
    }
en/web_development/forms/javascript.1643245440.txt.gz · Last modified: 2023/08/16 09:33 (external edit)