In my program, I have three text fields. In one of them, you are supposed to fill in some text, and in the other two, you fill in two numbers. The text field with the words large number has to have a greater value than the text field with the words smaller number. However, the number has to be less than the length of the user-inputted text.
Whenever I run the program, the javascript console says it cannot read property of sub-string null.
Here are the relevant bits of my code.
<p> Input text, and fill in two numbers in the boxes below. </p>
<p> The number on the left must be smaller than the one on the right</p>
<p> Press on the button to see what happens!
<script type = "text/javascript">
var t = document.getElementById("t");
var s = document.getElementById("small");
var l = document.getElementById("large");
function sub_str() {
var short_str = t.substr(s,l);
var regex_num = /^([0-9]*)$/;
if (l<s) {
window.alert("Please enter a number larger than the smaller number!");
}
if ((regex_num.test(s)) || (regex_num.test(l))){
window.alert("please enter valid numbers!");
} else {
window.alert("Your statement is: " + short_str);
}
}
</script>
<form>
<input type = "text" id = "t"></input> <br />
<input type = "text" id = "small" size = "5">small number</input> <br />
<input type = "text" id = "large" size = "5">large number</input>
<button type = "button" id = "click" onclick = "sub_str()"> Check </button>
</form>
Move DOM element selection into the function, and read its value.
Try this:
<p> Input text, and fill in two numbers in the boxes below. </p>
<p> The number on the left must be smaller than the one on the right</p>
<p> Press on the button to see what happens!
<script type = "text/javascript">
function sub_str() {
var t = document.getElementById("t").value;
var s = document.getElementById("small").value;
var l = document.getElementById("large").value;
var short_str = t.substr(s,l);
var regex_num = /^([0-9]*)$/;
if (l<s) {
window.alert("Please enter a number larger than the smaller number!");
}
if ((!regex_num.test(s)) || (!regex_num.test(l))){
window.alert("please enter valid numbers!");
} else {
window.alert("Your statement is: " + short_str);
}
}
</script>
<form>
<input type = "text" id = "t"></input> <br />
<input type = "text" id = "small" size = "5">small number</input> <br />
<input type = "text" id = "large" size = "5">large number</input>
<button type = "button" id = "click" onclick = "sub_str()"> Check </button>
</form>
There are multiple issues. You are not using .value on your elements to get value and then there is always the chance that your code gets executed before the DOM is loaded. So put your processing inside process() and then use
<body onload="process()">
to invoke this function after the document is loaded.
<script type = "text/javascript">
function process() {
function sub_str() {
var t = document.getElementById("t").value;
var s = document.getElementById("small").value;
var l = document.getElementById("large").value;
var short_str = t.substr(s,l);
var regex_num = /^([0-9]*)$/;
if (l<s) {
window.alert("Please enter a number larger than the smaller number!");
}
if ((regex_num.test(s)) || (regex_num.test(l))){
window.alert("please enter valid numbers!");
} else {
window.alert("Your statement is: " + short_str);
}
}
substr(); // Call the function here
}
</script>
Use the inputs' values, not the inputs themselves
You are interested in what the user typed in your input (that is the input's value), not the input it self. You can get the value of an input by using the input.value property.
Make sure the DOM is loaded when your script is executed
Make sure your DOM is loaded before doing any operation on it (such as getElementById). You should put your script tag at the end of the <body> or wrap your code in an onload handler.
Compare numbers, not strings
Also, when you are doing number comparison, make sure you are actually comparing number and not strings. In JavaScript, "5" > "30" is true (yep...). An input's value is a string. If you want proper number comparison, you must parse the values first (e.g. using parseInt).
console.log('"5" > "30":', "5" > "30");
console.log('5 > 30:', 5 > 30);
console.log('parseInt("5") > parseInt("30"):', parseInt("5") > parseInt("30"));
Fix your tests
The regexp test is wrong (you show an alert when the values are a number instead of when they are not). Moreover, you could just check the result of parseInt instead of regular expression.
Look after your users
Finally, you may also consider using inputs of of type type="number" instead of type="text" for the "small number" and "large number" inputs. type="number" will restrict what can be entered directly in the input itself. It will avoid user errors and the frustration of an alert.
By default, type="number" also add some controls (i.e. 2 arrows to increment or decrement the entry).
Note that even if you set the type to "number", input.value will still be a string that needs to be parsed, but this time, this string will always represent a number.
Similarly, you may programatically and automatically update the "large number" when a user enters a "small number" that is bigger and vice-versa. One less possible error, one less annoying alert.
Your code fixed (without the UI suggestions):
var t = document.getElementById("t");
var s = document.getElementById("small");
var l = document.getElementById("large");
function sub_str() {
var tVal = t.value;
var sVal = parseInt(s.value, 10); // paseInt will return NaN if the string is not a number.
var lVal = parseInt(l.value, 10);
var short_str = tVal.substr(sVal,lVal);
if (lVal<sVal) {
window.alert("Please enter a number larger than the smaller number!");
}
// Typo here, you want to test if the values are *not* a number.
else if (isNaN(sVal) || isNaN(lVal)){
window.alert("please enter valid numbers!");
} else {
window.alert("Your statement is: " + short_str);
}
}
<p> Input text, and fill in two numbers in the boxes below. </p>
<p> The number on the left must be smaller than the one on the right</p>
<p> Press on the button to see what happens!</p>
<form>
<input type = "text" id = "t"></input> <br />
<input type = "text" id = "small" size = "5">small number</input> <br />
<input type = "text" id = "large" size = "5">large number</input>
<button type = "button" id = "click" onclick = "sub_str()"> Check </button>
</form>
Related
The user has to guess a randomly generated number based on the highest value THEY input into a prompt box. Example (from 1 to ?)
I have to use a prompt and the value cannot be a decimal or string.
I'm not sure how to validate that or just not allow the user to input an invalid entry.
I am having issues reusing the number they input in the function for random number generation let num = Math.floor(Math.random() * inputMaxNumber + 1); in the game. I tried converting the value from a string to a number but that didn't work either.
This is what I have so far:
//prompt for max number the user inputs
function maxNumber() {
let inputMaxNumber = prompt ("Enter the maximum number the game can pick", " #");
if ( inputMaxNumber > 1) {
document.getElementById("maxNumber").innerHTML = "Guess a number between 1 and " + inputMaxNumber;
}
else {
alert("You must enter a positive whole number greater than 1");
}
console.log(inputMaxNumber);
}
inputMaxNumber = Number(document.getElementById("maxNumber").value); //converts this to a number from a string
// array that stores guesses
var numGuessArray = []
//validates user input for guesses (no decimals, strings, or negative numbers)
function onlyNumbers(num){
if ( /[^0-9]+/.test(num.value) ){
num.value = num.value.replace(/[^0-9]*/g,"")
}
}
//get user input to use in random number generation
// random value generated based on user input (a) new variable is num
let num = Math.floor(Math.random() * inputMaxNumber + 1);
console.log(num);
//counts the number of guesses for correct guess
var guess = 1;
//store counts and numbers guess in an array (don't count invalid guesses)
function do_guess() {
let guess = Number(document.getElementById("guess").value); //converts this to a number from a string
let message = document.getElementById("message");
//show on console
console.log(guess);
//hints about guess
if(guess == num) { //correct guess with count
message.innerHTML = "You got it and it took " + guess + " guess!";
}
else if (guess > num) { //number too high
message.innerHTML = "No, try a lower number";
}
else {//number too low
message.innerHTML = "No, try a higher number";
}
//you already guessed that number NO COUNT
}
//guess button used to guess
//use an array to keep track of the guess
<div class="container">
<h1>Higher - Lower</h1>
<p>Guess a number</p>
<div class = "row">
<div class ="col-lg-3 col-md-6">
<form>
<div class ="form-group">
<!-- This button triggers the prompt to allow the user to enter the max number-->
<input type ="button" value = "Click To Start" onclick = "maxNumber()";/>
</div>
<div class ="form-group">
<label> Your Guess:</label>
<!-- Prevents user from inputing decimals with onkeyup-->
<input type ="text" onkeyup="onlyNumbers(this)" id="guess" class ="form-control">
</div>
<p id = "maxNumber" ></p><!--Outputs maximum number range the user selected-->
<!--Button calls guess funciton when clicked-->
<button type="button" class ="btn btn-primary" onclick = "do_guess()">Guess</button>
</form>
</div>
</div>
<p id="message"></p> <!--Where message will go-->
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
Inside function maxNumber() you define inputMaxNumber locally let inputMaxNumber = prompt(...); so its value is lost when the function execution ends.
Additionally, the code where you generate the random number is executed only once, upon page load let num = Math.floor(...);. It's not executed after user enters his choice for the maximum.
Solution:
define num globally
assign the random value to it inside maxNumber()
I found this example on w3schools website -
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Can Validate Input</h2>
<p>Please input a number between 1 and 10:</p>
<input id="numb">
<button type="button" onclick="myFunction()">Submit</button>
<p id="demo"></p>
<script>
function myFunction() {
var x, text;
// Get the value of the input field with id="numb"
x = document.getElementById("numb").value;
// If x is Not a Number or less than one or greater than 10
if (isNaN(x) || x < 1 || x > 10) {
text = "Input not valid";
} else {
text = "Input OK";
}
document.getElementById("demo").innerHTML = text;
}
</script>
</body>
</html>
when I input 9 - it says 'Input OK'
when I input 11 -it says 'Input not valid'
but I have following questions -
how can I force users to type the correct type I want, but if they don't, then don't allow them to submit or re-input.
you are compareing string with number!
you should parse x to an integer like:
x = parseInt(document.getElementById("numb").value);
like this <input type="number" id="numb"/>
There are several ways to listen to changes on the input for instance. One way, just changing the code in the example above is to switch to listen to changes on the number field as trigger to validate:
<input id="numb" onChange="myFunction()">
<button type="button" >Submit</button>
Then you can add more logic into the myFunction() to make sure the button can't be pressed until numbers are valid and so on, see a working example that stops the user from pressing the button until input is valid:
https://jsfiddle.net/5fg4payk/2/
Assuming you're wanting range restriction you can achieve this with the HTML5 constraint validation API in combination with type="number", min="1" and max="10".
<input type="number" min="1" max="10" step="1" id="numb" oninput="(validity.valid)||(value='');">
To prevent re-input, you need to disable the field.
document.getElementById("numb").disabled = true;
So your code becomes :
if (isNaN(x) || x < 1 || x > 10) {
text = "Input not valid";
document.getElementById("numb").disabled = true;
} else {
text = "Input OK";
}
I am trying to create an add more button which will create a new input field. However, I would like to have an unique name set for it.
I tried to search up for an answer, but this does not answer my question.
So, basically what I tried to make my namefield unique is to use the php method rand(). The concept is that - when the add more button is clicked, it will have a name attached to the number given to me by rand().
However, what happens is that it takes the value generated by rand() and applies it to all the names of all the inputs generated.
This is my code and what I tried:
HTML:
<div class="field_wrapper">
<div>
<input type="text" name="field_name[<?php echo rand(); ?>]" value=""/>
Add More
</div>
</div>
JQUERY / JAVASCRIPT:
<script type="text/javascript">
$(document).ready(function(){
var maxField = 100; //Input fields increment limitation
var addButton = $('.add_button'); //Add button selector
var wrapper = $('.field_wrapper'); //Input field wrapper
var fieldHTML = '<div><input type="text" name="field_name[<?php echo rand(); ?>]" value=""/>Remove</div>'; //New input field html
var x = 1; //Initial field counter is 1
//Once add button is clicked
$(addButton).click(function(){
//Check maximum number of input fields
if(x < maxField){
x++; //Increment field counter
$(wrapper).append(fieldHTML); //Add field html
}
});
//Once remove button is clicked
$(wrapper).on('click', '.remove_button', function(e){
e.preventDefault();
$(this).parent('div').remove(); //Remove field html
x--; //Decrement field counter
});
});
</script>
As you can see, the first field generates the number as intended. If you click on the add more, the second field does create an unique number. However, if you click add more once again, the third field copies the same name as the 2nd field.
How do I go about achieving what I want and why is rand() not generating a new code?
Also, does rand() guarantee me that it will be an unique ID or is there a chance for it to repeat the same number?
If it does repeat, then what would be the best approach to take to make it as unique as possible?
If you generate random name with PHP it is done once on the server. Your JS code then copies the same element. What you need is to generate unique names with js.
Avoid random if you can, theoretically, you can hit the same number and run into mysterious bugs.
var generateField = function(name)
{
return '<div><input type="text" name="'+name+'" value=""/>Remove</div>'; //New input field html
}
//Once add button is clicked
$(addButton).click(function(){
//Check maximum number of input fields
if(x < maxField){
x++; //Increment field counter
$(wrapper).append(generateField('field_name['+x+']' ) ); //Add field html
}
});
Random does not necessarily mean unique, even if collisions would be extremely rare. This solution simply increments a totalFieldsCreated variable to get the next unique number (up to the maximum value JavaScript can provide.)
The new fields are created dynamically instead of using a fixed string of HTML. (This technique is more flexible.)
$(document).ready(function() {
// Defines global identifiers
let
currentFieldCount = 1,
totalFieldsCreated = 1;
const
maxFieldCount = 100,
addButton = $('.add_button'),
wrapper = $('.field_wrapper');
// Calls `addField` when addButton is clicked
$(addButton).click(addField);
// Executes anonymous function when `Remove` is clicked, which removes
// the parent div, and decrements (and logs) `currentFieldCount`
$(wrapper).on('click', '.remove_button', function(e) {
e.preventDefault();
$(this).parent('div').remove();
currentFieldCount--;
console.log(`currentFieldCount: ${currentFieldCount}`);
});
// Defines the `addField` function
function addField(){
// Makes sure that `currentFieldCount` and `totalFieldsCreated`
// are not at maximum before proceeding
if(
currentFieldCount < maxFieldCount &&
totalFieldsCreated < Number.MAX_VALUE
){
// Creates an input element, increments `totalFieldsCreated`,
// and uses the incremented value in the input's `name` attribute
const input = document.createElement("input");
input.type = "text";
input.name = "field" + ++totalFieldsCreated;
input.value = "";
// Creates an anchor element with the `remove_button` class
const a = document.createElement("a");
a.href = "javascript:void(0);";
a.classList.add("remove_button");
a.title = "remove";
a.innerHTML = "Remove";
// Adds the new elements to the DOM, and increments `currentFieldCount`
const div = document.createElement("div");
div.appendChild(input);
div.appendChild(a);
$(wrapper).append(div);
currentFieldCount++;
// Logs the new values of both variables
console.log(
`currentFieldCount: ${currentFieldCount},`,
`totalFieldsCreated ${totalFieldsCreated}`
);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="field_wrapper">
<div>
<input type="text" name="field1" value="" />
Add More
</div>
</div>
Try Math.random() in js rather than rand() in php ,Math.floor(Math.random()*90000) + 10000 will generate a five digit random number , Hope this helps
$('.rand').attr('name',"fields["+Math.floor(Math.random()*90000) + 10000+"]")
$('.add_button').click(function(e){
$('.field_wrapper').append('<div><input type="text" name=fields['+Math.floor(Math.random()*90000) + 10000+'] value=""/>Remove</div>')
})
$(document).on('click','.remove_button',function(e){
$(this).parent().remove()
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div class="field_wrapper">
<div>
<input type="text" class="rand" value=""/>
Add More
</div>
</div>
I am trying to create a form which will store values in an empty array but the values must be between 0 to 5 and comma separated. the problem is it alerts if values is more than 5 but still stores the value in the array. I want it to alert and then restore the form value.
Here is my code:
<form name ="form1" onsubmit="return validateForm()">
<input type="number" name="text" id="inputText" name="inputText" />
<button onclick="pushData();">Insert</button>
<p id="pText"></p>
</form>
And javascript:
function validateForm () {
var form = document.forms["form1"]["inputText"].value;
if(form <0 && form >= 6) {
alert('value should must be between 0 to 5');
return false;
}
}
// create an empty array
var myArr = [];
function pushData() {
// get value from the input text
var inputText = document.getElementById('inputText').value;
// append data to the array
myArr.push(inputText);
var pval = "";
for(i = 0; i < myArr.length; i++) {
pval = pval + myArr[i];
}
// display array data
document.getElementById('pText').innerHTML = "Grades: " + pval ;
}
Try
if (form <0 || form >= 6)
I think it may work better if you reorganize where the functions are being bound.
Event propagation order:
The button is clicked, and the value is pushed into the array.
The form's submit event triggers, and validates the values, but it's too late.
There are many ways to approach this one, but the simplest would be to call pushData at the end of your validateForm.
Adjusted the condition, because there's no way for a number to
be less than 0 AND greater than or equal to 6 at the same time.
Also added event.preventDefault to stop form submission.
JavaScript
function validateForm (event) {
event.preventDefault();
var form = document.forms["form1"]["inputText"].value;
if (form < 0 || form > 5) {
alert('value should must be between 0 to 5');
return false;
}
pushData();
}
HTML
<form name="form1" onsubmit="validateForm(event)">
<input type="number" id="inputText" />
<button type="submit">Insert</button>
<p id="pText"></p>
</form>
JSFiddle
Note that per the MDN:
A number input is considered valid when empty and when a single number
is entered, but is otherwise invalid.
With this particular form element you may add min and max attributes so that the user must enter a value within a specified range. Therefore, the current contents of the OP's validateForm() function are superfluous. Additionally, that function has a problematic line of code:
if(form <0 && form >= 6) {
You cannot have a value that is both less than zero and greater than or equal to six. Use instead a logical OR, i.e. "||" operator for the logic to work.
The following code allows for a user to select numeric values in the range that the OP specifies and then it displays them in a comma-separated format, as follows:
var d = document;
d.g = d.getElementById;
var pText = d.g('pText');
pText.innerHTML = "Grades: ";
var inputText = d.g("inputText");
var myArr = [];
function pushData() {
var notrailingcomma = "";
myArr.push(inputText.value);
if (myArr.length > 1) {
notrailingcomma = myArr.join(", ").trim().replace(/,$/g,"");
pText.innerHTML = "Grades: " + notrailingcomma;
}
else
{
pText.innerHTML += inputText.value;
}
}
d.forms["form1"].onsubmit = function(event) {
event.preventDefault();
pushData();
};
p {
padding: 1em;
margin:1em;
background:#eeeeff;
color: #009;
}
<form name="form1">
<input type="number" id="inputText" name="inputText" min=0 max=5 value=0>
<button type="submit">Insert</button>
</form>
<p id="pText"></p>
A couple of points with respect to the form:
The OP's HTML has an error in the input field: it has two names. I dropped the one with a name of "text".
I like what #thgaskell recommends with respect to changing "Insert" into a submit button, preventing the default action of submitting the form, and associating pushData with the form's onsubmit event. So, I've modified the code accordingly.
I have an HTML Input field and I need javascript to check if the input entered into this box is a certain string. Specifically, it has to be a specific Zip code, there are a total of 9 different zip codes, all which are different and in no numerical order. Once the code checks if it is that specific zip code, it returns "Yes", if not, simply no.
I know how to do this with ints, as shown in the code below, but not sure to how to do this with strings. This is my current code, which works with validating an integer between 1-10:
<input id="numb">
<button type="button" onclick="myFunction()">Submit</button>
<p id="demo"></p>
<script>
function myFunction() {
var x, text;
// Get the value of the input field with id="numb"
x = document.getElementById("numb").value;
// If x is Not a Number or less than one or greater than 10
if (isNaN(x) || x < 1 || x > 10) {
text = "Input not valid";
} else {
text = "Input OK";
}
document.getElementById("demo").innerHTML = text;
}
</script>
I think you are over-thinking this. You can just use the indexOf function to test your zip code array.
var btn= document.getElementById("btn");
var input = document.getElementById("numb");
var output = document.getElementById("demo");
var formArea = document.getElementById("formArea");
var zips = ["11111","22222","33333","44444","55555", "e1", "e2"];
btn.addEventListener("click", function() {
var result = null;
// indexOf() returns -1 when the supplied value isn't present
if(zips.indexOf(numb.value.toLowerCase()) > -1){
result = "yes";
// Show the form by removing the hidden class
formArea.classList.remove("hidden");
} else {
result = "no";
// Hide the form by adding the hidden class
formArea.classList.add("hidden");
}
output.textContent = result;
});
#formArea{
border:2px double grey;
width:50%;
box-shadow:2px 2px 0 #303030;
height:100px;
padding:5px;
}
.hidden {
display:none;
}
<input id="numb">
<button type="button" id="btn">Submit</button>
<p id="demo"></p>
<div id="formArea" class="hidden ">
Your form goes here
</div>
Can you use a regular expression for postal codes? Note this accounts for a set of zip codes that are in string format, but you are welcome to create a zip-code regex that can satisfy the set of zip codes you are interested in. And furthermore, if the set is small enough you can probably just enumerate them in a list/set and check if the set contains the input.
<input id="numb">
<button type="button" onclick="myFunction()">Submit</button>
<p id="demo"></p>
<script>
function myFunction() {
var x, text;
var isValidZip = /(^\d{5}$)|(^\d{5}-\d{4}$)/;
// Get the value of the input field with id="numb"
x = document.getElementById("numb").value;
// If x is Not a Number or less than one or greater than 10
if (!isValidZip.test(x)) {
text = "Input not valid";
} else {
text = "Input OK";
}
document.getElementById("demo").innerHTML = text;
}
</script>
convert it to a number
x = Number(document.getElementById("numb").value);