I'm creating a web front for a database using HTML, CSS, JavaScript and PHP for my uni coursework. I've only got so far as HTML and JavaScript form validation before I've run into this weird problem.
In my HTML, I link the JavaScript as follows:
<script type="text/javascript" src="dbicw2.js"></script>
Correct file name, I've checked.
Next, I have a form which takes a user's search. It upon submitting runs my JavaScript function, and its action is a PHP file. The code is as follows:
<form action="dbicw2.php" onSubmit="return validate(this)">
<input type="text" name="title">
<input type="submit" value="submit">
</form>
Again, correct PHP filename and JS function name.
Now, my JavaScript function seems to always return True, regardless of what happens. Currently, my JS looks like:
function validate(form)
{
alert("Hi")
for (var field in form.elements) { //For elements in form
field+="" //Incase it is undefined
alert("This element: '" + field.value + "'")
if (field.value.trim() == "") { //If the string is empty
alert(field.name + " is empty.") //Alert message
return false //Failed validation
}
}
return true //Otherwise, successful validation
}
Not even the alert message at the top runs. The form just goes through and PHP is loaded, regardless of the JS. The script neither works in Edge.
This is baffling because my code is a near clone of my professor's example, which works.
What is causing the Javascript to not be run and the PHP action done?
Edit: my professor's example code, which works:
HTML:
<!DOCTYPE html>
<html>
<head>
<title>(prof name)</title>
<LINK REL='stylesheet' TYPE='text/css' HREF='dbicw.css'>
<script type="text/javascript" src="dbicw.js"></script>
</head>
<body>
<h1>Search for a Movie by Title</h1>
<form action="search_movie_example.php" onSubmit="return validate(this)">
Movie title:<br>
<input type="text" name="title">
<br>
<br>
<input type="submit" value="Search">
</form>
</body>
</html>
JavaScript:
function validate(form)
{
var ok=1
var msg=""
for (var i = 0; i < form.length; i++) {
if (form.elements[i].value.trim() == "") {
msg += "'" + form.elements[i].name + "' is void. "
ok=0
}
}
if (ok == 0) {
alert(msg)
return false
}
else {
return true
}
}
I think I found a mistake (hopefully THE mistake) in your code. It's really simple, but very common.
You iterate over your form elements using for (var field in form.elements), but this will iterate over the index values of the form elements, rather than over the actual elements. Change in to of to iterate over the actual values instead.
Example:
let arr = ['foo', 'bar', 'cat'];
for (let word in arr) {
console.log(word); // prints 0, 1, 2
}
for (let word of arr) {
console.log(word); // prints foo, bar, cat
}
Try this:
function validate(form) {
event.preventDefault();
alert("Hi")
for (var field of [...form.querySelectorAll('input:not([type="submit"])')]) { //For elements in form
alert("This element: '" + field.value + "'")
if (field.value.trim() == "") { //If the string is empty
alert(field.name + " is empty.") //Alert message
}
}
}
<form action="dbicw2.php" onsubmit="validate(this)">
<input type="text" name="title">
<input type="submit" value="submit">
</form>
I added an event.preventDefault() so the page wouldn't be redirected in the live example, and changed the in to of while also altering the statement that "fetches" the input elements. The of simply allows you to iterate through the array, and the actual selector just gets all the input elements that are not of the type submit.
If you only want to alter your code to make it work, then try this:
function validate(form) {
alert("Hi")
for (var field of [...form.elements]) { //For elements in form
alert("This element: '" + field.value + "'")
if (field.value.trim() == "") { //If the string is empty
alert(field.name + " is empty.") //Alert message
return false //Failed validation
}
}
return true //Otherwise, successful validation
}
<form action="dbicw2.php" onSubmit="return validate(this)">
<input type="text" name="title">
<input type="submit" value="submit">
</form>
I again changed the in to of, and added a spread operator to convert the HTMLFormControlsCollection to an array.
Related
I'm attempting a simple form validation where if the input field is empty, the user will see a message asking to fill out any fields that are empty.
I'm able to loop and find which fields are empty and display a message, but the message will only display the last input field that was looped. How do I get the message to display all input fields that are empty?
HTML:
<label>Name</label>
<input class=formInput" name="name" />
<label>Email</label>
<input class=formInput" name="email" />
<label>Message</label>
<textarea class=formInput" name="message" />
<span id="fail-message"></span>
JS:
let inputFields = document.getElementsByClassName('formInput');
for (var i = 0; i < inputFields.length; i++) {
if (inputFields[i].value === '') {
document.querySelector('#fail-message').innerHTML =
'Please fill out ' +
inputFields[i].getAttribute('name') +
' field(s)';
}
}
This currently outputs "Please fill out message field(s)"
Assuming all is empty, I'd like it to output "Please fill out name, email and message field(s)"
The code you have overwrites the innerHTML completely every time it finds an empty field. What you should do instead is keep an array of all the empty fields, then only write the innerHTML once after the loop, with the list of fields it found.
let inputFields = document.getElementsByClassName('formInput');
const emptyFieldNames = [];
for (var i = 0; i < inputFields.length; i++) {
if (inputFields[i].value === '') {
emptyFieldNames.push(inputFields[i].getAttribute('name'));
}
}
if (emptyFieldNames.length > 0) {
document.querySelector('#fail-message').innerHTML = 'Please fill out the following fields: ' + emptyFieldNames.join(', ');
}
You overwrite the innerHTML of the message span in every iteration. You should concatenate the new error to it or use separate spans.
You would have to build an array containing the fields name that are not valid ... right now, you "overwrite" the innerHTML of the #fail-message element with the latest field (aka, it is INSIDE your loop to be rewritten each time the condition is met in the loop).
Add the names of the field in array (do not rewrite the whole array) and then use "yourArray.join()" to output all the names in the innerHTML of the correct element, like you do inside your loop.
You are replacing the value in the span element everytime you go through the loop. So only the last empty form element will be shown as fail message. Instead, you have to concatenate each string and then show it together.
Here is the complete code that will work for you:
<html>
<head>
<script>
function myFunction() {
let inputFields = document.getElementsByClassName('formInput');
let message ='';
for (var i = 0; i < inputFields.length; i++) {
console.log(inputFields[i].value);
if (inputFields[i].value === '') {
message = message + inputFields[i].getAttribute('name') + ', ';
}
}
let n = message.lastIndexOf(",");
message = message.substring(0,n);
document.querySelector('#fail-message').innerHTML =
'Please fill out ' +
message +
' field(s)';
}
</script>
</head>
<body>
<label>Name</label>
<input class="formInput" name="name" />
<label>Email</label>
<input class="formInput" name="email" />
<label>Message</label>
<textarea class="formInput" name="message"> </textarea>
<button onclick="myFunction()">Submit</button>
<span id="fail-message"></span>
</body>
</html>
I am trying to use JavaScript in an online examination assignment in HTML. As a requirement of the project, we have to use text input forms as well as radio buttons and the like. I have dealt with the part of radio buttons but for some reason my text input forms do not work. My problem will be clearly stated using this code snippet from the main project:
<html>
<head>
<title></title>
<script type="text/javascript">
var test, name, matr, myname, count = 0;
function form(){
test = document.getElementById("test");
test.innerHTML = "Count = "+count;
test.innerHTML += "<form> \
First name:<br> \
<input type='text' name='name'><br>\
<button onclick='check()'>Submit Answer</button>";
}
function check(){
myname = document.getElementsByName("name");
if (myname[1].value == "myname")
{
count++;
}
form();
}
window.addEventListener("load", form, false);
</script>
</head>
<body>
<div id = "test"></div>
</body>
</html>
What this code aims to do is that when the user inputs "myname" into the form called 'First name' and clicks 'Submit', the counter on the top should increment.
Can someone please shed some light on what I am doing wrong and how it may be resolved.
As Pluto mentioned, arrays in javascript start at 0. You can also look at tinkering with the form element. It is not closed nor is the type, get or post specified. I got it working in the example below by removing the form completely. This is because the button press was trying to submit the form and therefore load a new page.
https://jsfiddle.net/jpm68eub/
var test, name, matr, myname, count = 0;
function form() {
test = document.getElementById("test");
test.innerHTML = "Count = " + count;
test.innerHTML += "</br> First name:<br> \
<input type='text' name='name'><br>\
<button onclick='check()'>Submit Answer</button>";
}
function check() {
myname = document.getElementsByName("name");
if (myname[0].value == "myname") {
count++;
}
form();
}
form();
you need to prevent the default action of the onclick event. To do this, try something like this:
function check(e){
e.preventDefault();
myname = document.getElementsByName("name");
if (myname[0].value == "myname")
{
count++;
}
form();
}
the above user was also correct about where javascript arrays start (they start at 0)
I have the following code in a SharePoint aspx page ( I got an error that said I cannot use form controls... that is why the form tags are not there):
<div id="formBox">
Here is a link : <a href="" id=lnk>nothing here yet</a> <br>
<input type='text' id='userInput' />
<input name="codename" type="radio" value="codeA" /> <label for="x">X</label> <input name="codename" type="radio" value="codeB" /><label for="y">Y</label>
<input type='button' onclick='javascript:changeText2()' value='Change Text'/>
</div>
Here is the function which is supposed to concatenate the information: It works... kind of.. parts of it.
It will add the selected button to the url, and also the input text. However, it is firing before the input is filled out, and then works once you type in the box again.
I tired to add in if statement, to stop the code if the box was not filled out but it didn't work. Here is what I have...
function changeText2(){
var userInput = document.getElementById('userInput').value;
$('#formBox input[type="text"]').on('change', function() {
var linktest = 'site/info.aspx?' + $('input[name="codename"]:checked', '#formBox').val() + '=' + userInput;
alert(linktest);
});
var lnk = document.getElementById('lnk');
lnk.href = "http://www.google.com?q=" + userInput;
lnk.innerHTML = lnk.href;
}
I tried to check the input box like this, but it didn't work:
if( $('#formBox input[type="text"]').val== "") {
alert('no info');
}
It should be val() in jquery, not val. However, it will be value in javascript, not val. Simply just use unique id, try something like this,
For Jquery:
if( $('#userInput').val() === "") {
alert('no info');
}
For javascript:
if(document.getElementById("userInput").value === "") {
alert('no info');
}
I am trying to make a form that automatically sums input fields on blur and displays the sum in an inactive "Total:" field. I don't want to run anything if a user puts focus in an input then moves focus away without inputting anything and if a user does input something I want to restrict the field to only numbers. If there is a better way of doing this, please let me know. Here is an example of my current approach:
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test Calc</title>
<script src="javascript.js"></script>
</head>
<body>
<h1>Sales By Month</h1>
<form method="get">
<label for="january">January:</label>
<input type="text" id="january" class="amount" onblur="isNum(); calculateSum();">
<label for="february">February:</label>
<input type="text" id="february" class="amount" onblur="isNum(); calculateSum();">
<label for="total">Total:</label>
<input type="text" id="total" disabled>
</form>
</body>
</html>
JavaScript
function calculateSum() {
var elems = document.getElementsByClassName('amount');
var myLength = elems.length;
sum = 0;
for (var i = 0; i < myLength; ++i) {
sum += elems[i].value *1;
}
document.getElementById('total').value = sum;
}
function isNum() {
var amounts = parseInt(document.getElementsByClassName('amount').value);
if (isNaN(amounts) == true && amounts != '') {
alert("Please enter a numeric value");
}
}
The calculation function currently works but the "Please enter a numeric value" alert pops up every time I tab away from a field regardless of the contents.
First you need to test the value of the element that losts focus, which means you should pass it in the argument like this
onblur="isNum(this); calculateSum();"
then in your isNum function in javascript remove document.getElementsByClassName and use the argument instead ... and don't test if amounts != '' because it will never be equal to empty string while you do this amounts = parseInt(elem.value); you have to test on the elem.value
function isNum(elem)
{
var amounts = parseInt(elem.value);
if (isNaN(amounts) == true && elem.value != '') {
alert("Please enter a numeric value");
}
Here is a jsFiddle
I am looking for a javascript function. which will disable the entered (filled) text field on submit. So when the user logs in back the filled text box has to remain disabled. I have tried a code, but here what happens is on clicking the sumbit the contents in the text field gets deleted.
<html>
<head>
<script>
function enableDisable(){
var disable = true;
var arglen = arguments.length;
var startIndex = 0;
var frm = document.example1;//change appropriate form name
if (arglen>0){
if (typeof arguments[0]=="boolean") {
disable=arguments[0];
if (arglen>1) startIndex=1;
}
for (var i=startIndex;i<arglen;i++){
obj = eval("frm."+arguments[i]);
if (typeof obj=="object"){
if (document.layers) {
if (disable){
obj.onfocus=new Function("this.blur()");
if (obj.type=="text") obj.onchange=new Function("this.value=this.defaultValue");
}
else {
obj.onfocus=new Function("return");
if (obj.type=="text") obj.onchange=new Function("return");
}
}
else obj.disabled=disable;
}
}
}
}
</script>
</head>
<body>
<form name="example1">
Text Field: <input type="text" name="text1">
<br>
<input type="submit" name="control1" onclick="enableDisable(this.submit,'text1','submit','select1')">
</form>
</body>
</html>
please do guide.
Make sure your submit function returns false if you don't want the page to refresh. The code you're looking for is document.getElementById('insertIdOfTextFieldHere').style.readonly = "readonly";