False value being passed in ajax call

I have an Ajax call that loops through a json file with the following code:

<input class='num' type='text' name='quantity_" + element.id + "' id='numb' value='0'>

It calls a function in the form tag as follows:

<form method='POST' action='cart.php' id='cartForm' onsubmit='return myFunction();'>

When I try to validate the quantity to make sure that it’s a positive number less than ten, I use the following javascript:

function myFunction() {
var x;
x = document.getElementById('numb').value;
alert(x);//this prints 0 every time
if ( isNaN(x) || (x < 0) || (x > 10)) {
alert("Quantity must be a positive number less than 10.");
event.preventDefault(); 
return false;
} else {
alert("Input OK");
}
}

The problem is that it doesn’t get the $_POST value of the textbox, it gets the value of zero like how the textbox is initialized every time.

That’s because the text box has a value of zero, isn’t it?

<input ... value='0'>

When you type a different number into the input field, the function alerts that other number.
You can see a simple test of this at https://jsfiddle.net/Lo5jh3ws/1/

#1: This is what input type = number was designed for.
#2: Danger senses tingling…

name='quantity_" + element.id + "' id='numb'

… you seem to be dynamically creating multiple inputs there… multiple inputs with the same ID… if there’s more than one thing with the id ‘numb’, you’ve broken your form. ID must be unique across the page.

1 Like

A programming friend of mine pointed out that it’s iterating through a loop of ids and the id is the same for every text input so I changed it to:

and I changed my function to:

function myFunction() {
  var x, i, y;
  
  for (i = 1; i < 7; i++) {
    y = 'numb_' + i;
    x = document.getElementById(y).value;
	//alert(y);

	if ( isNaN(x) || (x < 0) || (x > 10)) {
  
    alert("Quantity must be a positive number less than 10.");
	event.preventDefault(); 
	return false;
  } else {
    alert("Input OK");
  }
}
}

alert(y); prints out numb_1 every time so it’s not looping properly. How can I improve my loop?

Hi @makamo661, the loop looks fine but the script is probably throwing after the first iteration if there are no more elements matching the current ID – you might want to check the console of your browser dev tools for errors (which BTW also provides convenient logging methods that are more informative and less obstrusive than using alerts for debugging).

Anyway better would be not to hard-code the number of the expected elements into the loop at all but get a list of the desired elements from the start, e.g.

var elements = document.querySelectorAll('[id^="numb_"]')

for (var i = 0; i < elements.length; i++) {
  console.log(elements[i].id)
}

// Or:
elements.forEach(function (element) {
  console.log(element.id)
})

Thank you. This is my working code:

function myFunction() {
var x, y;
var elements = document.querySelectorAll('[id^="numb_"]');

for (var i = 1; i < elements.length; i++) {
	
	y = elements[i].id;
	
    x = document.getElementById(y).value;  

	if ( isNaN(x) || (x < 1) || (x > 10)) {
  
    alert("Quantity must be a positive number less than 10.");
	event.preventDefault(); 
	return false;
  } else {
	return true;
}
}
}

No need to get the same element again by ID though, you already have that very reference in the list:

for (var i = 0; i < elements.length; i++) {
  x = elements[i].value
  // ...
}

BTW you’d also have to cast the value to a number before doing arithmetic operations:

x = Number(elements[i].value)

if (isNaN(x) || (x < 0) || (x > 10)) {
  // ...
}

woooah there cowboy.
You don’t want to return true until you’ve checked ALL the results. You’ve gone from false negative to false positive errors.

Finish the for loop, and then return true. That way you know ALL the tests passed (cause if any had failed, you’d have returned false and never gotten to the end)