Why does a variable with .substring() not reflect css styling? - javascript

Using pure javascript, I am trying to create a price-validating function that when used, validates prices entered into a form. There are 4 requirements to my validation:
Input must be a number and cannot be empty
If a decimal is entered, there must at least be 1 pre- and post-decimal character
Price entered must be a number that is between $1 and $99.99 (both inclusive)
Price entered must not have whitespaces in between
and here is my code:
function formCheck() {
var success = true; //default, assumes client enters all fields correctly so "process.html" will load
var msgBox = document.getElementById('divMessage'); //feedback div
//Price Variables
var movPrice = document.getElementById('txtPrice');
var priceFdBk1 = '<ul><li> Please enter <b>numbers</b> only. </li></ul>';
var priceFdBk2 =
'<ul><li> You entered a decimal point. Please enter a <b>number</b> both before and after the decimal place. </li></ul>';
var priceFdBk3 = '<ul><li> Please enter a movie price between $1.00 to $99.99 (up to 2 decimal places). </li></ul>';
var priceFdBk4 = '<ul><li> Please do not leave a space when entering the movie price. </li></ul>';
//Price Validation
function priceCheck(price, fdBk1, fdBk2, fdBk3, fdBk4) {
//arguments = price and feedbacks if errors are made
var price_clean = price.value.trim(); //price entered by client without whitespace
var price_len = price_clean.length; //number of characters in price entered
//If there is a $ sign, remove it first
var dollarSensor = price_clean.charAt(0);
if (dollarSensor == '$') {
price_clean = price_clean.substring(1);
}
//If there is a decimal point, obtain pre- and post-decimal characters
if (price_clean.indexOf('.') > -1) {
var deciSensor = 1; //remember that input has a decimal
var intValue = price_clean.split('.')[0]; //obtain pre-decimal characters)
var decimalValue = price_clean.split('.')[1]; //obtain post-decimal characters
var postCounter = 0;
for (var j = 0; j < decimalValue.length; j++) {
//count number of decimal places
postCounter += 1;
}
}
//Filter 1: Input must be a number and cannot be empty
if (isNaN(price_clean) || price_clean == '') {
msgBox.innerHTML = fdBk1;
price.className = 'yellow';
success = false;
}
//Filter 2: If a decimal is entered, there must at least be 1 pre- and post-decimal character
else if ((deciSensor == 1 && intValue == '') || (deciSensor == 1 && decimalValue == '')) {
//if client did not enter a number before and after the decimal point
msgBox.innerHTML = fdBk2;
price.className = 'yellow';
success = false;
}
//Filter 3: Price entered must be a number that is between $1 and $99.99 (both inclusive)
else if (price_clean < 1 || price_clean > 99.99 || postCounter > 2) {
msgBox.innerHTML = fdBk3; //message in feedback div
price.className = 'yellow';
success = false; //prevent loading of "process.html" since selected movie is invalid
} else {
price.className = 'transparent';
}
//Filter 4: Price entered must not have whitespaces in between
for (var i = 0; i < price_len; i++) {
oneDigit = price_clean.charAt(i);
if (oneDigit == ' ') {
//if the price float character has a whitespace
msgBox.innerHTML = fdBk4; //message in feedback div
price.className = 'yellow'; //highlight error in client's input
success = false; //prevent loading of "process.html" since selected movie is invalid
} else if (oneDigit == '') {
//if the price float character has no whitespace
price.className = 'transparent'; //remove highlight from client's input
}
}
}
priceCheck(movPrice, priceFdBk1, priceFdBk2, priceFdBk3, priceFdBk4);
return success;
}
.yellow {
background-color: yellow;
}
.transparent {
background-color: transparent;
}
h1 {
color: #7157ff;
}
hr {
display: block;
border: 0;
border-top: 3px solid #f90;
padding: 0;
}
textarea {
width: 70%;
}
#div_main {
font-family: Sans-serif;
margin: auto;
margin-top: 30px;
width: 500px;
}
#div_left {
width: 150px;
display: inline-block;
float: left;
}
#div_left p {
margin-bottom: 19px;
}
#div_right {
width: 350px;
display: inline-block;
float: right;
}
.clear {
clear: both;
}
<div id="div_main">
<h1>
Add Movie
</h1>
<hr>
<form action="process.html" method="POST">
<div id="div_left">
<p>Price* ($):</p>
</div>
<div id="div_right">
<p><input type="text" id="txtPrice" name="txtPrice"></p>
</div>
<input type="submit" id="btnSubmit" onclick="return formCheck()">
</form>
<div id="divMessage">
*denotes compulsary fields.
</div>
</div>
The code works fine but has 1 issue, which I suspect comes from this line:
price_clean = price_clean.substring(1)
Specifically, whenever I enter a "$" sign into the form, my code will remove the "$" sign and validate the input as usual. However, when the input is invalid, it no longer highlights the input box in yellow.
May I know what is going on and how can this be fixed using vanilla javascript? Thank you

Your issue is that you're adding the yellow highlight, but then removing it in your final for loop, this is due to your final for loop using price_len, which is calculated before you remove the $. As a result, your for loop is doing one additional iteration, and so .charAt(i) tries to access an index not in your string giving you an empty string. To fix this, you can calculate the length after you've removed the additional $:
function formCheck() {
var success = true; //default, assumes client enters all fields correctly so "process.html" will load
var msgBox = document.getElementById('divMessage'); //feedback div
//Price Variables
var movPrice = document.getElementById('txtPrice');
var priceFdBk1 = '<ul><li> Please enter <b>numbers</b> only. </li></ul>';
var priceFdBk2 =
'<ul><li> You entered a decimal point. Please enter a <b>number</b> both before and after the decimal place. </li></ul>';
var priceFdBk3 = '<ul><li> Please enter a movie price between $1.00 to $99.99 (up to 2 decimal places). </li></ul>';
var priceFdBk4 = '<ul><li> Please do not leave a space when entering the movie price. </li></ul>';
//Price Validation
function priceCheck(price, fdBk1, fdBk2, fdBk3, fdBk4) {
//arguments = price and feedbacks if errors are made
var price_clean = price.value.trim(); //price entered by client without whitespace
//If there is a $ sign, remove it first
var dollarSensor = price_clean.charAt(0);
if (dollarSensor == '$') {
price_clean = price_clean.substring(1);
}
var price_len = price_clean.length; //number of characters in price entered
//If there is a decimal point, obtain pre- and post-decimal characters
if (price_clean.indexOf('.') > -1) {
var deciSensor = 1; //remember that input has a decimal
var intValue = price_clean.split('.')[0]; //obtain pre-decimal characters)
var decimalValue = price_clean.split('.')[1]; //obtain post-decimal characters
var postCounter = 0;
for (var j = 0; j < decimalValue.length; j++) {
//count number of decimal places
postCounter += 1;
}
}
//Filter 1: Input must be a number and cannot be empty
if (isNaN(price_clean) || price_clean == '') {
msgBox.innerHTML = fdBk1;
price.className = 'yellow';
success = false;
}
//Filter 2: If a decimal is entered, there must at least be 1 pre- and post-decimal character
else if ((deciSensor == 1 && intValue == '') || (deciSensor == 1 && decimalValue == '')) {
//if client did not enter a number before and after the decimal point
msgBox.innerHTML = fdBk2;
price.className = 'yellow';
success = false;
}
//Filter 3: Price entered must be a number that is between $1 and $99.99 (both inclusive)
else if (price_clean < 1 || price_clean > 99.99 || postCounter > 2) {
msgBox.innerHTML = fdBk3; //message in feedback div
price.className = 'yellow';
success = false; //prevent loading of "process.html" since selected movie is invalid
} else {
price.className = 'transparent';
}
//Filter 4: Price entered must not have whitespaces in between
for (var i = 0; i < price_len; i++) {
oneDigit = price_clean.charAt(i);
if (oneDigit == ' ') {
//if the price float character has a whitespace
msgBox.innerHTML = fdBk4; //message in feedback div
price.className = 'yellow'; //highlight error in client's input
success = false; //prevent loading of "process.html" since selected movie is invalid
} else if (oneDigit == '') {
//if the price float character has no whitespace
price.className = 'transparent'; //remove highlight from client's input
}
}
}
priceCheck(movPrice, priceFdBk1, priceFdBk2, priceFdBk3, priceFdBk4);
return success;
}
.yellow {
background-color: yellow;
}
.transparent {
background-color: transparent;
}
h1 {
color: #7157ff;
}
hr {
display: block;
border: 0;
border-top: 3px solid #f90;
padding: 0;
}
textarea {
width: 70%;
}
#div_main {
font-family: Sans-serif;
margin: auto;
margin-top: 30px;
width: 500px;
}
#div_left {
width: 150px;
display: inline-block;
float: left;
}
#div_left p {
margin-bottom: 19px;
}
#div_right {
width: 350px;
display: inline-block;
float: right;
}
.clear {
clear: both;
}
<div id="div_main">
<h1>
Add Movie
</h1>
<hr>
<form action="process.html" method="POST">
<div id="div_left">
<p>Price* ($):</p>
</div>
<div id="div_right">
<p><input type="text" id="txtPrice" name="txtPrice"></p>
</div>
<input type="submit" id="btnSubmit" onclick="return formCheck()">
</form>
<div id="divMessage">
*denotes compulsary fields.
</div>
</div>
There are however a few improvements you can consider making to your code though:
Use const or let instead of var (to help with minimizing scoping issues)
Update your code to use classList.toggle() to remove/add your highlight class
Consider using regular expressions or HTML5 validation with custom validation messages using setCustomValidity()
Use DOM2 event hanlders by using .addEventListener() with e.preventDefault() instead of DOM0 (onxyz) HTML attributes

A small fix to your code, you've set price_len before removing leading $
const price_len = price_clean.length;
for(var i=0; i<price_len; i++){
...
}
<html>
<head>
<style>
.yellow{
background-color:yellow
}
.transparent{
background-color: transparent;
}
h1 {
color: #7157ff;
}
hr {
display: block;
border: 0;
border-top: 3px solid #f90;
padding: 0;
}
textarea {
width: 70%;
}
#div_main {
font-family: Sans-serif;
margin: auto;
margin-top: 30px;
width: 500px;
}
#div_left {
width: 150px;
display: inline-block;
float: left;
}
#div_left p {
margin-bottom: 19px;
}
#div_right {
width: 350px;
display: inline-block;
float: right;
}
.clear {
clear: both;
}
</style>
<script language="javascript">
function formCheck(){
var success=true; //default, assumes client enters all fields correctly so "process.html" will load
var msgBox = document.getElementById("divMessage"); //feedback div
//Price Variables
var movPrice = document.getElementById("txtPrice");
var priceFdBk1 = "<ul><li> Please enter <b>numbers</b> only. </li></ul>"
var priceFdBk2 = "<ul><li> You entered a decimal point. Please enter a <b>number</b> both before and after the decimal place. </li></ul>"
var priceFdBk3 = "<ul><li> Please enter a movie price between $1.00 to $99.99 (up to 2 decimal places). </li></ul>"
var priceFdBk4 = "<ul><li> Please do not leave a space when entering the movie price. </li></ul>"
//Price Validation
function priceCheck(price,fdBk1,fdBk2,fdBk3,fdBk4){ //arguments = price and feedbacks if errors are made
var price_clean = price.value.trim(); //price entered by client without whitespace
//var price_len = price_clean.length; //number of characters in price entered
//If there is a $ sign, remove it first
var dollarSensor = price_clean.charAt(0);
if (dollarSensor=="$"){
price_clean = price_clean.substring(1);
}
//If there is a decimal point, obtain pre- and post-decimal characters
if (price_clean.indexOf('.')>-1){
var deciSensor=1 //remember that input has a decimal
var intValue = price_clean.split(".")[0]; //obtain pre-decimal characters)
var decimalValue = price_clean.split(".")[1]; //obtain post-decimal characters
var postCounter=0
for (var j=0;j<decimalValue.length;j++){ //count number of decimal places
postCounter+=1;
}
}
//Filter 1: Input must be a number and cannot be empty
if (isNaN(price_clean)||price_clean==""){
msgBox.innerHTML = fdBk1;
price.className="yellow";
success=false;
}
//Filter 2: If a decimal is entered, there must at least be 1 pre- and post-decimal character
else if (deciSensor==1 && intValue==""||deciSensor==1 && decimalValue==""){ //if client did not enter a number before and after the decimal point
msgBox.innerHTML = fdBk2;
price.className="yellow";
success=false;
}
//Filter 3: Price entered must be a number that is between $1 and $99.99 (both inclusive)
else if (price_clean<1||price_clean>99.99||postCounter>2){
msgBox.innerHTML = fdBk3; //message in feedback div
price.className="yellow";
success=false; //prevent loading of "process.html" since selected movie is invalid
}
else{
price.className="transparent";
}
//Filter 4: Price entered must not have whitespaces in between
const price_len = price_clean.length;
for(var i=0; i<price_len; i++){
oneDigit = price_clean.charAt(i);
if (oneDigit==" "){ //if the price float character has a whitespace
msgBox.innerHTML= fdBk4; //message in feedback div
price.className="yellow"; //highlight error in client's input
success=false; //prevent loading of "process.html" since selected movie is invalid
}
else if (oneDigit==""){ //if the price float character has no whitespace
price.className="transparent"; //remove highlight from client's input
}
}
}
priceCheck(movPrice,priceFdBk1,priceFdBk2,priceFdBk3,priceFdBk4)
return success;
}
</script>
</head>
<body>
<div id="div_main">
<h1>
Add Movie
</h1>
<hr>
<form action="process.html" method="POST">
<div id="div_left">
<p>Price* ($):</p>
</div>
<div id="div_right">
<p><input type="text" id="txtPrice" name="txtPrice"></p>
</div>
<input type="submit" id="btnSubmit" onclick="return formCheck()">
</form>
<div id="divMessage">
*denotes compulsary fields.
</div>
</div>
</body>
</html>

Related

Is there a way to exclude already used characters from an array?

New to programming here, and I am just about to finish my first project-a password generator. I am trying to keep it as simple as possible, nothing fancy, yet I have come to a standstill. I want to implement an option that allows the user to only get one character to appear only once in the generated password. As of now, it is just a random jumble of characters, repeating and whatnot, so I was wondering if there is any way to implement such a feature-and if so, how? If statements? loops? I am up for all suggestions!
Here is the code.
var keys = {
upperCase : ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"],
lowerCase: ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","z"],
number: ["0","1","2","3","5","6","7","8","9"],
symbol: ["!","#","#","$","%","^","&","*","(",")","_","+","~","|","}","{","[","]",":",";","?",">","<",",",".","/","-","="]
}
var getKey = [
function upperCase() {
return keys.upperCase[Math.floor(Math.random() * keys.upperCase.length)];
},
function lowerCase() {
return keys.lowerCase[Math.floor(Math.random() * keys.lowerCase.length)];
},
function number() {
return keys.number[Math.floor(Math.random() * keys.number.length)];
},
function symbol() {
return keys.symbol[Math.floor(Math.random() * keys.symbol.length)];
}
];
function createPassword() {
var upper = document.getElementById("upperCase").checked;
var lower = document.getElementById("lowerCase").checked;
var number = document.getElementById("number").checked;
var symbol = document.getElementById("symbol").checked;
if (upper + lower + number + symbol === 0) {
alert("Please check a box!");
return;
}
var passwordBox = document.getElementById("passwordBox");
var length = document.getElementById("length");
var password = "";
while (length.value > password.length) {
var keyToAdd = getKey[Math.floor(Math.random() * getKey.length)];
var isChecked = document.getElementById(keyToAdd.name).checked;
if (isChecked) {
password += keyToAdd();
}
}
passwordBox.innerHTML = password;
}
Link to codepen (with all HTML, JavaScript and CSS) is available here.
#Embla I think this is what you are trying to achieve, let me know if smthg is missing in this solution. You didnt provide HTML, I just assumed what it might look like
let passwordBox = document.getElementById("passwordBox");
let length = document.getElementById("length");
const keys = {
upperCase : ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"],
lowerCase: ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","z"],
number: ["0","1","2","3","5","6","7","8","9"],
symbol: ["!","#","#","$","%","^","&","*","(",")","_","+","~","|","}","{","[","]",":",";","?",">","<",",",".","/","-","="]
}
function random( max, min=0){
return ~~(Math.random() * (max - min) + min)
}
function getKey(objArr){
const values = Object.values(objArr);
const randValue = values[random(values.length)];
return randValue[random(randValue.length)];
}
function createPassWord(passwordLength){
const pwdStorage = new Set();
while( pwdStorage.size < passwordLength ){
pwdStorage.add(getKey(keys))
}
return [...pwdStorage].join('');
}
length.addEventListener('change', (event)=>{
passwordBox.textContent = createPassWord(+length.value)
})
input[type="number"]{
width: 150px;
height: 30px;
border: 2px solid grey;
border-radius: 5px;
padding-left:10px;
font-size: 18px;
}
<div class="password-Container">
<h2 id="passwordBox">Password</h2>
</div>
<input type="number" name="" id="length" min="1" max="100" step="1" placeholder="Enter number">
I writed a function for your request, i hope that works for you.
Array.prototype.getAndRemove = function (index) {
const item = this[index];
if (this.indexOf(item) > -1) {
this = this.splice(this.indexOf(item), 1);
if (this.indexOf(item) > -1) {
this = this.splice(this.indexOf(item), 1);
}
}
return item;
}

Value is uploading in firebase even when the condition is not fulfilled

In this code, I want the value not to be uploaded in the firebase database when the condition of
at least 1 number, at least one lowercase value and minimum 4 characters to be included
even when the condition is not full filled the values are uploaded into the database
var myInput = document.getElementById("user_name2");
var letter = document.getElementById("letter");
var number = document.getElementById("number");
var length = document.getElementById("length");
// When the user clicks on the password field, show the message box
myInput.onfocus = function() {
document.getElementById("message").style.display = "block";
}
// When the user clicks outside of the password field, hide the message box
myInput.onblur = function() {
document.getElementById("message").style.display = "none";
}
// When the user starts to type something inside the password field
myInput.onkeyup = function() {
// Validate lowercase letters
var lowerCaseLetters = /[a-z]/g;
if(myInput.value.match(lowerCaseLetters)) {
letter.classList.remove("invalid");
letter.classList.add("valid");
} else {
letter.classList.remove("valid");
letter.classList.add("invalid");
}
// Validate numbers
var numbers = /[0-9]/g;
if(myInput.value.match(numbers)) {
number.classList.remove("invalid");
number.classList.add("valid");
} else {
number.classList.remove("valid");
number.classList.add("invalid");
}
// Validate length
if(myInput.value.length >= 4) {
length.classList.remove("invalid");
length.classList.add("valid");
} else {
length.classList.remove("valid");
length.classList.add("invalid");
}
}
var tblUsers = document.getElementById('tbl_users_list');
var databaseRef = firebase.database().ref('users/');
var rowIndex = 1;
var uid;
var childKey;
var childData;
databaseRef.once('value', function(snapshot) {
snapshot.forEach(function(childSnapshot) {
childSnapshot.key;
childSnapshot.val();
var row = tblUsers.insertRow(rowIndex);
var cellId = row.insertCell(0);
var cellName = row.insertCell(1);
cellId.appendChild(document.createTextNode(childKey));
cellName.appendChild(document.createTextNode(childData.user_name));
cellName.appendChild(document.createTextNode(childData.user_name2));
rowIndex = rowIndex + 1;
});
});
function save_user(){
var user_name = document.getElementById('user_name').value;
var user_name2 = document.getElementById('user_name2').value;
uid = firebase.database().ref().child('users').push().key;
var data = {
user_id: uid,
user_name: user_name,
password: user_name2
}
var updates = {};
updates['/users/' + uid] = data;
firebase.database().ref().update(updates);
alert('The user is created successfully!');
reload_page();
document.writeln(uid);
}
function update_user(){
var user_name = document.getElementById('user_name').value;
var user_id = document.getElementById('user_id').value;
var data = {
user_id: user_id,
user_name: user_name
}
var updates = {};
updates['/users/' + user_id] = data;
firebase.database().ref().update(updates);
alert('The user is updated successfully!');
reload_page();
}
function delete_user(){
var password = ""; // hard-coded value, but this could also be read from the HTML
var ref = firebase.database().ref("users");
var query = ref.orderByChild("password").equalTo(password);
query.once("value").then(function(results) {
results.forEach(function(snapshot) {
snapshot.ref.remove();
alert('record removed');
})
})
}
function reload_page(){
window.location.reload();
}
ref.on("child_added", function(snapshot, prevChildKey) {
var newPost = snapshot.val();
console.log("Author: " + newPost.author);
console.log("Title: " + newPost.title);
console.log("Previous Post ID: " + prevChildKey);
});
.valid {
color: green;
}
/* Add a red text color and an "x" when the requirements are wrong */
.invalid {
color: red;
}
.button {
display: inline-block;
padding: 15px 25px;
font-size: 24px;
cursor: pointer;
text-align: center;
text-decoration: none;
outline: none;
color: #fff;
background-color: #4CAF50;
border: none;
border-radius: 15px;
box-shadow: 0 9px #999;
}
.button:hover {background-color: #3e8e41}
.button:active {
background-color: #3e8e41;
box-shadow: 0 5px #666;
transform: translateY(4px);
}
#grad {
background-image: linear-gradient(to top right, #33ccff 10%, #ff99cc 100%);
}
<input type="text" id="user_name2" style="height:75px;font-size:14pt;" name="psw" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}" title="Must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters" required>
<div id="message">
<h3>Unique ID must contain the following:</h3>
<p id="letter" class="invalid">A <b>lowercase</b> letter</p>
<p id="number" class="invalid">A <b>number</b></p>
<p id="length" class="invalid">Minimum <b>4 characters</b></p>
<input type="button" class="button" value="Save" onclick="save_user();" autocomplete="on" />
I have used CSS to change the conditions on each and every time the condition is satisfied
Your code, as written, will always save the user to the database. When a user clicks the "Save" button, the save_user() function is called. And there is no logical path through save_user() that doesn't result in a new user being stored - you're not validating the user input before storing it.
You seem to be doing a lot of useful input validation while the user types (your keyup handler code), but nothing keeps the user from clicking "Save", and clicking "Save" invariably saves a new user.
Hope this helps.

Using <label> <input> <br> in for loop

I'd like to ask on how to add label, input, and br in for loop please. I'm trying to create an application to calculate score/GPA with for loop. Basically, if I enter 4 then 4 boxes of test scores will show up for me to enter (the default value is 150) - and the maximum I can go is 5.
I'm having problem putting label, input, and br in the for loop - the code is fine and it ran, but you obviously see that I'm not using label, input, and br tags.
How may I add these in please?
For example, if I enter 3 in the number of exams, then setupInputBox() will generate three label, three input and three br elements.
I attached my codes below.
Thank you so much!
// define a function so that in js code, $ can be used to replace document.getElementById
var $ = function(id) {
return document.getElementById(id);
};
var numInputs = 1; //default setting, showing one test score input box
//define setupInputBox function to add more test score inputs boxes
var setupInputBox = function() {
$('testInputs').innerHTML = "";
$('scoreTotal').value = "";
$('scoreAvg').value = "";
$('scoreFinal').value = "";
numInputs = $('numscores').value;
numInputs = parseInt(numInputs);
// convert inputs into integer numerical value
//step-1.1: Add a condition in if() statement
//if user input for number of test scores is valid and in the range 1 to 5
if (Number.isInteger(numInputs) && numInputs >= 1 && numInputs <= 5) {
var mainDiv = document.getElementById("testInputs");
for (var i = 0; i < numInputs; i++) {
//Step-1.2.1: create new <label>, <input>, and <br> elements (use createElement() method)
var lbl = document.createElement('label');
var inp = document.createElement("input");
var br = document.createElement("br");
//Step-1.2.2: create text content node for each new <label> element ( use createTextNode() method )
lbl.append(document.createTextNode("Test-" + (i + 1)));
//Step-1.3.1: add for attribute to each new <label> element ( use setAttribute() method)
lbl.setAttribute("for", "score" + (i + 1));
//Step-1.3.2: add id, type, and value attributes to new <input> elements ( use setAttribute() method)
inp.setAttribute("id", "score" + (i + 1));
inp.setAttribute("value", "150");
inp.setAttribute("type", "number");
//Step-1.4: append each new <label>, <input>, and <br> elements to the <div> element with id=”testInputs”.
mainDiv.append(lbl, inp, br);
}
}
};
//whenever user changes selection on number of test scores to consider, setupInputBox function will be executed again
$('numscores').oninput = setupInputBox;
//define processEntries function to get user inputted test scores, do input validation, and caculate total and average points and
//determine the final letter grade. Display all results on web page.
var processEntries = function() {
$('scoreTotal').value = "";
$('scoreAvg').value = "";
$('scoreFinal').value = "";
var score = []; //define an array to hold test scores
var message = ""; //define a variable for containing and displaying error message
var totalscore = 0,
avgScore, finalScore;
var isValid = true;
for (var i = 0; i < numInputs; i++) //
{
$("score" + (i + 1)).className = "";
//step 2.1: add js code to read in each user inputted test score(s) from input test score boxes on the web page.
var test = document.getElementById("score" + (i + 1));
var testScore = parseFloat(test.value);
//step 2.2: add js code to validate each test score to make sure all inputted test scores are numerical values
//between 0 and 150 (i.e., no less than 0 and no greater than 150 points).
if (!Number.isNaN(testScore) && testScore >= 0 && testScore <= 150) {
//if a test score is valid, add that test score to the score array.
score.push(testScore);
} else {
isValid = false;
//if a test score is invalid, generate error message, and add that error messge to message string.
message += "Test-" + (i + 1) + " score input is invalid. Should be a number between 0 and 150.\n"
test.setAttribute("class", "error");
}
}
console.log(score); //print out score array in console
console.log(message); //print out message string in console
if (isValid) {
//step2.3: add js so that when all inputted test scores are valid, compute total points, average points (with zero decimal place), and
//final letter grade, and display them in the input boxes in the <div> element with id=’result’ on the web page.
for (var j = 0; j < numInputs; j++) {
totalscore += score[j];
}
totalscore = totalscore.toFixed(1);
avgScore = totalscore / numInputs;
avgScore = avgScore.toFixed(1);
var scoreTotal = document.getElementById('scoreTotal');
scoreTotal.value = totalscore.toString();
var scoreAvg = document.getElementById('scoreAvg');
scoreAvg.value = avgScore.toString();
avgScore = parseFloat(avgScore);
if (avgScore <= 150 && avgScore >= 120)
finalScore = "A";
else if (avgScore < 120 && avgScore >= 100)
finalScore = "B";
else if (avgScore < 100 && avgScore >= 80)
finalScore = "C";
else if (avgScore < 80 && avgScore >= 60)
finalScore = "D";
else if (avgScore < 60)
finalScore = "F";
var scoreFinal = document.getElementById("scoreFinal")
scoreFinal.value = finalScore
} else {
//If not all inputted test scores are valid, then create an alert box to display an error message
alert(message);
}
}; //end of processEntries function
//each time when calculate button is clicked, inputted test scores will be evaluated and
$("calculate").onclick = function() {
if (numInputs > 0 && numInputs < 6)
processEntries();
};
$("numscores").focus();
#import url(http://fonts.googleapis.com/css?family=Wellfleet);
body {
font-family: 'Wellfleet', Arial, Helvetica, sans-serif;
background-color: white;
margin: 0 auto;
width: 60%;
min-width: 600px;
border: 3px solid blue;
padding: 0 1em .5em;
}
h1 {
color: blue;
margin: .5em 0;
}
#teacher {
float: right;
margin: 0px 30px 0px 0px;
}
label {
float: left;
width: 10em;
text-align: right;
margin-bottom: .5em;
}
input {
width: 5em;
margin-left: 1em;
margin-bottom: .5em;
}
input.error {
background-color: yellow;
}
#s1 {
display: inline-block;
}
#s1 input {
vertical-align: center;
float: left;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test Score App</title>
<link rel="stylesheet" href="score.css">
</head>
<body>
<main>
<h2>The Test Scores App</h2>
<img src="teacher.png" id="teacher" alt="teacher" width="177" height="277">
<div id="s1">
<label for="numscores">How many tests you want to consider?</label>
<input type='number' id='numscores' min='1' max='10' value='1'>
</div>
<div id="testInputs">
<label for="score1">Test-1:</label>
<input type='number' id='score1' value='150' /><br>
</div>
<div id='result'>
<label for="scoreTotal">Total Points:</label>
<input type="number" id="scoreTotal" disabled><br>
<label for="scoreAvg">Avg Grade:</label>
<input type="number" id="scoreAvg" disabled><br>
<label for="scoreFinal">Final Letter Grade:</label>
<input type="text" id="scoreFinal" disabled><br>
<label> </label>
<input type="button" id="calculate" value="Calculate">
</div>
</main>
<script src="testScoreV2.js">
</script>
</body>
</html>
Use a template literal and you can make this a lot simpler
// define a function so that in js code, $ can be used to replace document.getElementById
var $ = function(id) {
return document.getElementById(id);
};
var numInputs = 1; //default setting, showing one test score input box
//define setupInputBox function to add more test score inputs boxes
var setupInputBox = function() {
$('testInputs').innerHTML = "";
$('scoreTotal').value = "";
$('scoreAvg').value = "";
$('scoreFinal').value = "";
//string to hold our new html
let newHTML = "";
numInputs = $('numscores').value;
numInputs = parseInt(numInputs);
// convert inputs into integer numerical value
//step-1.1: Add a condition in if() statement
//if user input for number of test scores is valid and in the range 1 to 5
if (Number.isInteger(numInputs) && numInputs >= 1 && numInputs <= 5) {
var mainDiv = document.getElementById("testInputs");
for (var i = 0; i < numInputs; i++) {
//Create new html using template literal
newHTML += `<label for='score${i+1}'>Test - ${i+1}</label><input type='number' value='150' id='score${i+1}'><br>`;
}
//Update the div
mainDiv.innerHTML += newHTML;
}
};
//whenever user changes selection on number of test scores to consider, setupInputBox function will be executed again
$('numscores').oninput = setupInputBox;
//define processEntries function to get user inputted test scores, do input validation, and caculate total and average points and
//determine the final letter grade. Display all results on web page.
var processEntries = function() {
$('scoreTotal').value = "";
$('scoreAvg').value = "";
$('scoreFinal').value = "";
var score = []; //define an array to hold test scores
var message = ""; //define a variable for containing and displaying error message
var totalscore = 0,
avgScore, finalScore;
var isValid = true;
for (var i = 0; i < numInputs; i++) //
{
$("score" + (i + 1)).className = "";
//step 2.1: add js code to read in each user inputted test score(s) from input test score boxes on the web page.
var test = document.getElementById("score" + (i + 1));
var testScore = parseFloat(test.value);
//step 2.2: add js code to validate each test score to make sure all inputted test scores are numerical values
//between 0 and 150 (i.e., no less than 0 and no greater than 150 points).
if (!Number.isNaN(testScore) && testScore >= 0 && testScore <= 150) {
//if a test score is valid, add that test score to the score array.
score.push(testScore);
} else {
isValid = false;
//if a test score is invalid, generate error message, and add that error messge to message string.
message += "Test-" + (i + 1) + " score input is invalid. Should be a number between 0 and 150.\n"
test.setAttribute("class", "error");
}
}
console.log(score); //print out score array in console
console.log(message); //print out message string in console
if (isValid) {
//step2.3: add js so that when all inputted test scores are valid, compute total points, average points (with zero decimal place), and
//final letter grade, and display them in the input boxes in the <div> element with id=’result’ on the web page.
for (var j = 0; j < numInputs; j++) {
totalscore += score[j];
}
totalscore = totalscore.toFixed(1);
avgScore = totalscore / numInputs;
avgScore = avgScore.toFixed(1);
var scoreTotal = document.getElementById('scoreTotal');
scoreTotal.value = totalscore.toString();
var scoreAvg = document.getElementById('scoreAvg');
scoreAvg.value = avgScore.toString();
avgScore = parseFloat(avgScore);
if (avgScore <= 150 && avgScore >= 120)
finalScore = "A";
else if (avgScore < 120 && avgScore >= 100)
finalScore = "B";
else if (avgScore < 100 && avgScore >= 80)
finalScore = "C";
else if (avgScore < 80 && avgScore >= 60)
finalScore = "D";
else if (avgScore < 60)
finalScore = "F";
var scoreFinal = document.getElementById("scoreFinal")
scoreFinal.value = finalScore
} else {
//If not all inputted test scores are valid, then create an alert box to display an error message
alert(message);
}
}; //end of processEntries function
//each time when calculate button is clicked, inputted test scores will be evaluated and
$("calculate").onclick = function() {
if (numInputs > 0 && numInputs < 6)
processEntries();
};
$("numscores").focus();
#import url(http://fonts.googleapis.com/css?family=Wellfleet);
body {
font-family: 'Wellfleet', Arial, Helvetica, sans-serif;
background-color: white;
margin: 0 auto;
width: 60%;
min-width: 600px;
border: 3px solid blue;
padding: 0 1em .5em;
}
h1 {
color: blue;
margin: .5em 0;
}
#teacher {
float: right;
margin: 0px 30px 0px 0px;
}
label {
float: left;
width: 10em;
text-align: right;
margin-bottom: .5em;
}
input {
width: 5em;
margin-left: 1em;
margin-bottom: .5em;
}
input.error {
background-color: yellow;
}
#s1 {
display: inline-block;
}
#s1 input {
vertical-align: center;
float: left;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test Score App</title>
<link rel="stylesheet" href="score.css">
</head>
<body>
<main>
<h2>The Test Scores App</h2>
<img src="teacher.png" id="teacher" alt="teacher" width="177" height="277">
<div id="s1">
<label for="numscores">How many tests you want to consider?</label>
<input type='number' id='numscores' min='1' max='10' value='1'>
</div>
<div id="testInputs">
<label for="score1">Test-1:</label>
<input type='number' id='score1' value='150' /><br>
</div>
<div id='result'>
<label for="scoreTotal">Total Points:</label>
<input type="number" id="scoreTotal" disabled><br>
<label for="scoreAvg">Avg Grade:</label>
<input type="number" id="scoreAvg" disabled><br>
<label for="scoreFinal">Final Letter Grade:</label>
<input type="text" id="scoreFinal" disabled><br>
<label> </label>
<input type="button" id="calculate" value="Calculate">
</div>
</main>
<script src="testScoreV2.js">
</script>
</body>
</html>

Number with thousand decimal and two digit after comma [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I need thousand decimal and two digit after comma like following picture.
https://brutmaas.net/maas-hesaplama/brutten-nete/tablo
Following code need to be improved.
<input type="number" id="myInput" value="3512.12"
onfocus="focusFunction()"
onblur="blurFunction()" style="text-align: right" />
Here is a little snippet that does basically the same thing as the example page you gave:
// Factory to produce a new number container based on the input value
function createNumericDisplay(input){
var display = document.createElement("div"), decimal = document.createElement("sup"), number = new Number(input.value).toLocaleString('de-DE').split(",");
if(number.length == 1){
number[1] = "0";
}
display.setAttribute("class", "numeric");
display.innerText = number[0];
decimal.innerText = ","+number[1].lpad("0",2).substr(0,2);
display.appendChild(decimal);
return display;
}
// Creates or removes the number
function toggleNumericDisplay(input, show){
var display = input.parentNode.querySelector(".numeric");
if(display && !show){
display.parentNode.removeChild(display);
}else if(!display && show){
display = createNumericDisplay(input);
input.parentNode.appendChild(display);
}
}
// When we focus, remove the formatted number container
function focusFunction(ev) {
toggleNumericDisplay(ev.target, false);
}
// When we blur, create the formatted number container
function blurFunction(ev) {
toggleNumericDisplay(ev.target, true);
}
// Pad a string with zeroes
String.prototype.lpad = function(padString, length) {
var str = this;
while (str.length < length)
str = padString + str;
return str;
}
// Initialize values
var numerics = document.body.querySelectorAll(".numeric-wrapper input");
for(var i=0; i<numerics.length; ++i){
toggleNumericDisplay(numerics[i], true);
}
.numeric-wrapper {
display: inline-block;
position: relative;
border: 1px solid #000;
font: 13.3333px "Arial" !important;
}
.numeric-wrapper .numeric {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
pointer-events: none;
background-color: #fff;
text-align: right;
}
.numeric-wrapper .numeric sup {
opacity: 0.75;
}
<div class="numeric-wrapper">
<input type="number" id="myInput" value="1450.91" onfocus="focusFunction(event)" onblur="blurFunction(event)" style="text-align: right" step="1" />
</div>
You can use a pattern attribute to restrict which characters can be entered (the following restricts to digits, dots and commas):
<input type="text" id="num" name="number"
pattern="[0-9.,]+"
onkeypress="return window.validate && validate(event);"
title="Enter german localized number" />
Then some JavaScript to validate the format upon the keypress event either manually or using globalize.numberParser( [options] ).
function validate(e) {
var valid = true;
var text = document.getElementById("num").value;
// either manually check if format is valid e.g.
var firstLetter = text.charAt(0);
if(firstLetter === ".") {
valid = false;
}
// etc.
// or parse/validate with globalize
var num = Globalize.numberParser(/*german locale*/)("10.000,00")
valid = !isNaN(parseFloat(num)) && isFinite(num);
return valid;
}
Another option could be to let someone enter 1234.56 (or whatever their local equivalent is) then format that into 1.234,56?

Min length of input (searchbox)

I need to add a popup window event to my search system - when a customer hit only 2 characters it should popup a small table with alert e. g. "You must enter at least 3 characters when searching..." and the background should be greyed out.
Is this possible for me? Here is my javascript code for searching (in table):
/*** SEARCHBOX ***/
//define the table search object, which can implement both functions and properties
window.tableSearch = {};
//initialize the search, setup the current object
tableSearch.init = function() {
//define the properties I want on the tableSearch object
this.Rows = document.getElementById('data').getElementsByTagName('TR');
this.RowsLength = tableSearch.Rows.length;
this.RowsText = [];
//loop through the table and add the data to the table search object
for (var i = 0; i < tableSearch.RowsLength; i++) {
this.RowsText[i] = (tableSearch.Rows[i].innerText) ? tableSearch.Rows[i].innerText.toUpperCase() : tableSearch.Rows[i].textContent.toUpperCase();
}
}
//onlys shows the relevant rows as determined by the search string
tableSearch.runSearch = function() {
//get the search term
this.Term = document.getElementById('searchbox').value.toUpperCase();
//loop through the rows and hide rows that do not match the search query
for (var i = 0, row; row = this.Rows[i], rowText = this.RowsText[i]; i++) {
row.style.display = ((rowText.indexOf(this.Term) != -1) || this.Term === '') ? '' : 'none';
}
}
//handles the enter key being pressed
tableSearch.search = function(e) {
//checks if the user pressed the enter key, and if they did then run the search
var keycode;
if (window.event) { keycode = window.event.keyCode; }
else if (e) { keycode = e.which; }
else { return false; }
if (keycode == 13) {
tableSearch.runSearch();
}
else { return false; }
}
And here is my html code (search box):
<table border="0" cellpadding="0" cellspacing="0">
<tbody><tr><td>
<input id="searchbox" size="25" maxlength="100" value="search..." style="color: gray;" name="Search" onkeyup="tableSearch.search(event)" onfocus="if(this.value == 'search...') {this.value=''}" onblur="if(this.value == ''){this.value ='search...'}" type="text" />
<input class="button_searchbox" value="Search" onclick="tableSearch.runSearch();" type="button" />
</td></tr></tbody>
</table><br />
Any ideas? Thx
This is a little example using part of your code, and a simple div as a popup:
function doSearch(event)
{
var keycode;
if (window.event) { keycode = window.event.keyCode; }
else if (e) { keycode = e.which; }
else { return false; }
if (keycode == 13)
{
if (this.searchbox.value.length > 2)
{
console.log("Searching...");
}
else
{
document.getElementById("divPopup").style.display = "block";
}
}
else
{
document.getElementById("divPopup").style.display = "none";
return false;
}
}
Div:
<div id="divPopup">You must enter at least 3 characters when searching...</div>
CSS:
#divPopup
{
color: grey;
font-family: Verdana;
font-size: 10px;
border: 1px solid black;
width: 200px;
display: none;
}
JSFiddle: http://jsfiddle.net/hescano/9NFqL/
In your runSearch function, after the statement
this.Term = document.getElementById('searchbox').value.toUpperCase();
check the length of the search term
if (this.Term.length() < 3){
alert('You must enter at least 3 characters when searching...');
return;
}
Thats all.

Categories

Resources