Okay now I have been able to solve the Length problem by adding the length property to the while loop. However, when i generate the noSpecialCharacter(), it gives me NaN in front of the generated password.
this is the function:
const noSpecialCharacters = () => {
let password;
for (let i = 0; i < askUser; i++) {
let result3 = characterSet[randomCharacter()];
password += result3;
}
return password;
}
let askUser;
// create a function for prompts
const prompts = () => {
const minLength = 8;
const maxLength = 128;
askUser = null
while (askUser === null || askUser.length < minLength || askUser.length > maxLength) {
// ask the user again
askUser = prompt('Enter a password character length. Character length must be at least 8 and between 128.');
let confirmSpecialCharacter;
// if password is between length range
if (askUser >= minLength && askUser <= maxLength) {
// ask for special characters
confirmSpecialCharacter = confirm('Would you like for your password to include special characters?');
// if yes, call combine random
let pass = confirmSpecialCharacter === true ? combineRandom() : noSpecialCharacters();
alert(pass);
}
}
return askUser;
}
prompts();
When you check the length, use askUser.length
But with this logic, when the user input is correct on the first time, nothing in the wile loop will run.
A better approach is to initialize askUser = null
and set the condition in while to:
while (askUser === null || askUser.length < minLength || askUser.length > maxLength)
To check first if the askUser is null
let askUser;
// create a function for prompts
const prompts = () => {
const minLength = 8;
const maxLength = 128;
askUser = null
while (askUser === null || askUser.length < minLength || askUser.length > maxLength) {
// ask the user again
askUser = prompt('Enter a password character length. Character length must be at least 8 and between 128.');
let confirmSpecialCharacter;
// if password is between length range
if (askUser.length >= minLength && askUser.length <= maxLength) {
// ask for special characters
confirmSpecialCharacter = confirm('Would you like for your password to include special characters?');
// if yes, call combine random
if (confirmSpecialCharacter === 'yes') {
let pass = combineRandom();
alert(pass);
} else {
let pass = noSpecialCharacters();
alert(pass);
}
}
}
return askUser;
}
prompts()
Since people solved your question by adding .length to the askUser, I'm here to suggest you to reconstruct the code from while loop to recursive by keep calling the function itself until it passed the validation. (code untested)
with this method you can prevent the nested condition by return early.
// create a function for prompts
const prompts = () => {
const minLength = 8;
const maxLength = 128;
// ask the user
let askUser = prompt('Enter a password character length. Character length must be at least 8 and between 128.');
// keep asking the function itself until it passed the validation
if (askUser.length <= minLength || askUser.length >= maxLength || askUser === null) {
return prompts()
}
// ask for special characters
let confirmSpecialCharacter = confirm('Would you like for your password to include special characters?');
let pass;
// if yes, call combine random
if (confirmSpecialCharacter) {
pass = combineRandom();
} else {
pass = noSpecialCharacters();
}
alert(pass);
return askUser;
}
With ternary condition you can get much more shorter code.
// if yes, call combine random
let pass = confirmSpecialCharacter ? combineRandom() : noSpecialCharacters();
In your while condition, you are not actually checking for askUser length. Change it to this line: while (askUser.length < minLength || askUser === null || askUser.length > maxLength) { /... And it will work.
Related
I want to check if a string is a valid number without using isNaN
because I would like to accept the , character that is ignored by isNaN I don't also want to accept negative numbers and the last condition the number should be between 1 and 99.
example :
let a = '--5'; // false
let b = '95.5'; // true it can accept . also
let c = '99,8'; // false bigger than 99
let d = '99,'; // false
how can I do this. Thank you very much
const test = '55.'
var res = true;
if(test[0] === '-' || test[test.length-1] === ',' || test[test.length-1] === '.'){
res = false;
}else{
let final = test.replace(/,/g, ".");
if(isNaN(final)){
res = false;
}else{
if(Number(final)>99 ||Number(final) < 1 ) {
res = false;
}}}
console.log(res)
note that this is accepting ,56 and .76 which are valid. but you can add these condition in the first if statement if you want if(test[0] === '.' || test[0] === ','
a = '-5';
a = a.replace(/,/g, '.');
//check a is number
if (isNaN(a) || a.startsWith('-') ) {
console.log('not a number');
}else{
console.log(' not a number');
if(a > 0 && a < 100){
console.log(' a number');
}
}
There is a task: The field “First Name Last Name” can only consist of 2 words (first name and last name). Min length of each word is 3 characters, max 30. There is only 1 space between words.
The problem is that after the first word, when you put a space, it already returns true. Why? And how to check the 1 space in this input?
const validateInput = (value) => {
const lengthValue = value.split(' ').length
if (lengthValue !== 2) {
return false
} else {
return value.split(' ').filter(el => el.length > 3 && el.length <= 30) ?
value.search(/[A-Za-z]+(\s+[A-Za-z]+)?/gi) !== -1 ?
true :
false :
''
}
}
Use trim to remove spaces from around the words before testing
No need for else after a return. Makes it easier to read too
Why are you testing the words in the name for whitespace? That only works if the user pasted a newline or a tab, since you split on space
You have a nested ternary, why would you return an empty string there?
Also please read this for the future falsehoods programmers believe about names
const re = /[A-Za-z]{3,30}/;
const validateInput = (value) => {
const val = value.trim();
if (val === "") return false;
const arr = value.split(' ');
if (arr.length != 2) return false;
const [firstName, lastName] = arr;
return re.test(firstName) && re.test(lastName); // we could use .every here but you only have two
}
console.log(validateInput("Hans Anders"));
console.log(validateInput("Prince"));
console.log(validateInput("X Æ A-12"));
console.log(validateInput(" A "));
You can check if the no. of words are less than equal to two and the length of all the words fall within the specified range.
const message = document.querySelector("small");
document.querySelector("input").addEventListener("keyup", (e) => {
const isValid = validateInput(e.target.value);
if (isValid) {
message.textContent = "Valid input";
} else {
message.textContent = "Invalid input";
}
});
const validateInput = (input) => {
const words = input.split(" ");
return words.length <= 2 && words.every((w) => /^[A-Za-z]{3,30}$/.test(w));
};
<div>
<label>
Name:
<input type="text" />
</label>
</div>
<small>Invalid input</small>
For two days now, I have been trying to validate in real-time in my JavaScript calculator user inputs before passing the overall input to the operator(=) function. What I want to achieve is: I don't want the user to input more than one operator sign or dot consecutively. As the user is typing each input I want the calculator to validate each input in realtime, so that if the user input more than one operator sign or dot consecutively the calculator will warn the user and automatically delete the last input and update the validated ones on the calculator screen. For example;
1A) 22.3.2. + 4 -6 **3 ++ 2-^ <-- THIS IS WRONG(not validated)
1B) 22.3+4-6*3+2 <-- THIS IS WHAT I WANT(validated)
Below is the sample code I wrote so far.
JavaScript
let userInput = "22.2. + 3 -4^"; //as the user is inputting, i want to be validating it in realtime
function validateWrongInput() {
let p = userInput;
for (i = 0; i < p.length; i++){
if ((p.charAt(i) === "!" || p.charAt(i) === "^" ||
p.charAt(i) === "*" || p.charAt(i) === "/" || p.charAt(i) === "+" ||
p.charAt(i) === "-" || p.charAt(i) === "(" || p.charAt(i) === ")") &&
(p.charAt(i - 1) === "!" || p.charAt(i - 1) === "^" ||
p.charAt(i - 1) === "*" || p.charAt(i - 1) === "/" ||
p.charAt(i - 1) === "+" || p.charAt(i - 1) === "-" ||
p.charAt(i - 1) === "(" || p.charAt(i - 1) === ")")) {
let a = p.split("");
a.pop();
let c = a.join("");
upDisplay.textContent = c; //This shows the user input as he is typing
updisplayResult = c;
downDisplay.textContent = "ERROR-Why Two Operators?"; // this shows the final result when the = sign is pressed
return true;
} else {
return false;
}
}
}
JavaScript
let userInput = "22.2. + 3 -4^"; //as the user is inputting, i want to be validating it in realtime
function validateDecimal() {
let p = userInput;
let pointCount = 0;
for (let i = 0; i < p.length; i++) {
if (p.charAt(i) !== "!" && p.charAt(i) !== "^" && p.charAt(i) !== "*" &&
p.charAt(i) !== "/" && p.charAt(i) !== "+" && p.charAt(i) !== "-") {
if (p.charAt(i) === "." && pointCount < 1) {
pointCount += 1
downDisplay.textContent = " ";
return "ok";
} else {
pointCount = 0;
let a = p.split("");
a.pop();
let c = a.join("");
upDisplay.textContent = c; //This shows the user input as he is typing
updisplayResult = c;
downDisplay.textContent = "ERROR-Why Two Operators?"; // this shows the final result when the = sign is pressed
return "ERROR-Why Two Operators?"+c;
}
} else {
pointCount = 0;
}
}
}
I am looking for your help.
Checking input while typing
const input = document.getElementById('userInput');
input.addEventListener('keydown', () => {
const p = input.value;
// validation...
})
Sounds like you are looking for an event listener. Make sure you have the corresponding html input element, in this case: <input type="text" id="userInput">
Recommendations
I believe it is best to let the user finish whatever they are typing and check afterwards. Such behaviour can be achieved by using the event listener blur or validating just as it is submitted during the submit event (Not explained, but you may look it up or ask).
You may find a nicer way of validating your string if you craft a regular expression (regEx) together. This is somewhat complicated and should only be done if you feel confident with them.
I am sort of new to Javascript Code and I'm wondering how can I specify that x in this case can be a number in between 750 to 850.
else if(DATA == "PULSOUT 12, x") {
*Note DATA is a user input that was taken from a textarea if that info is needed.
#Ahm23, Try this:
if (DATA.substr(0,11) == "PULSOUT 12," && parseInt(DATA.substr(11).trim()) >= 750 && parseInt(DATA.substr(11).trim()) <= 850) {
You can define a function which checks if input is within range 751-849 where array contains elements [750, 850], pass or define array containing ranges at second parameter, use logic n > range[0] && n < range[1], where n is user input. You can use .match(), RegExp /\d+$ to get digits before end of string, `
let x = "750";
function checkX(n, range = [750, 850]) {
return n > range[0] && n < range[1]
}
console.log(checkX(x)); // false
console.log(checkX(x = 751)); // true
console.log(checkX(x = 850)); // false
let DATA = `PULSOUT 12, ${x = 808}`;
console.log(
checkX(x = DATA.match(/\d+$/g).pop())
&& DATA.replace(/\d+$/, "") === "PULSOUT 12, "
); // true
I'd like to validate an IPv6 address using an algorithm that emphasizes readability. The ideal solution combines a dead-simple regular expression with source-code.
Using https://blogs.msdn.microsoft.com/oldnewthing/20060522-08/?p=31113 as an example:
function isDottedIPv4(s)
{
var match = s.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
return match != null &&
match[1] <= 255 && match[2] <= 255 &&
match[3] <= 255 && match[4] <= 255;
}
Notice how Raymond moves the complexity from the regular expression into code. I'd like a solution that does the same for IPv6.
Here is a variant of Brandon's answer:
/**
* #param {String} a String
* #return {Boolean} true if the String is a valid IPv6 address; false otherwise
*/
function isIPv6(value)
{
// See https://blogs.msdn.microsoft.com/oldnewthing/20060522-08/?p=31113 and
// https://4sysops.com/archives/ipv6-tutorial-part-4-ipv6-address-syntax/
const components = value.split(":");
if (components.length < 2 || components.length > 8)
return false;
if (components[0] !== "" || components[1] !== "")
{
// Address does not begin with a zero compression ("::")
if (!components[0].match(/^[\da-f]{1,4}/i))
{
// Component must contain 1-4 hex characters
return false;
}
}
let numberOfZeroCompressions = 0;
for (let i = 1; i < components.length; ++i)
{
if (components[i] === "")
{
// We're inside a zero compression ("::")
++numberOfZeroCompressions;
if (numberOfZeroCompressions > 1)
{
// Zero compression can only occur once in an address
return false;
}
continue;
}
if (!components[i].match(/^[\da-f]{1,4}/i))
{
// Component must contain 1-4 hex characters
return false;
}
}
return true;
}
console.log('Expecting true...');
console.log(isIPv6('2001:cdba:0000:0000:0000:0000:3257:9652'));
console.log(isIPv6('2001:cdba:0:0:0:0:3257:9652'));
console.log(isIPv6('2001:cdba::3257:9652'));
console.log(isIPv6('2001:cdba::257:9652'));
console.log(isIPv6('2001:DB8:0:2F3B:2AA:FF:FE28:9C5A'));
console.log(isIPv6('::0:2F3B:2AA:FF:FE28:9C5A'));
console.log('\n');
console.log('Expecting false...');
console.log(isIPv6(':0:2F3B:2AA:FF:FE28:9C5A'));
This still may be too complex, but I think it covers most scenarios with IPv6 addresses. I went through something similar recently, it is really hard to replace a huge RegEx for something as complex as IPv6.
function isIPv6(s)
{
// Check if there are more then 2 : together (ex. :::)
if(/:{3,}/.test(s)) return false;
// Check if there are more then 2 :: (ex. ::2001::)
if(/::.+::/.test(s)) return false;
// Check if there is a single : at the end (requires :: if any)
if(/[^:]:$/.test(s)) return false;
// Check for leading colon
if(/^:(?!:)/.test(s)) return false;
// Split all the part to check each
var ipv6_parts = s.split(':');
// Make sure there are at lease 2 parts and no more then 8
if(ipv6_parts.length < 2 || ipv6_parts.length > 8) return false;
var is_valid = true;
// Loop through the parts
ipv6_parts.forEach(function(part) {
// If the part is not blank (ex. ::) it must have no more than 4 digits
if(/^[0-9a-fA-F]{0,4}$/.test(part)) return;
// Fail if none of the above match
is_valid = false;
});
return is_valid;
}
console.log(isIPv6('2001:cdba:0000:0000:0000:0000:3257:9652'));
console.log(isIPv6('2001:cdba:0:0:0:0:3257:9652'));
console.log(isIPv6('2001:cdba::3257:9652'));
console.log(isIPv6('::2001:cdba:3257:9652'));