Looping through 2 elements at a time - javascript

I'm trying to create error messages for labels on a form. Problem is that it's not working. The submitted input must be a number. Whenever it is not, clicking on the button should return a error message on the specific label.
Problem is - it only works OK if the first thing you submit is a correct set of numbers. I can't seem to get the combinations right. Do you know how I can solve this?
let coordValues = document.getElementsByClassName("input-card__input");
let submitBtn = document.getElementsByClassName("input-card__button");
let inputLabel = document.getElementsByClassName("input-card__label");
let weatherArray = [];
let labelArray = [];
for(let j=0;j<inputLabel.length;j++) {
labelArray.push(inputLabel[j].innerHTML);
}
submitBtn[0].addEventListener("click", function checkInputs() {
for(let i = 0; i<coordValues.length;i++) {
for(let k = 0; k<inputLabel.length;k++) {
if(coordValues[i].value === "" || isNaN(Number(coordValues[i].value))) {
inputLabel[k].classList.add("input-card__label--error");
inputLabel[k].innerHTML = "Oops! Write a number here."
console.log("nop");
break;
} else {
inputLabel[k].classList.remove("input-card__label--error");
inputLabel[k].innerHTML = labelArray[k];
console.log("yep");
break;
}
}
}
});
.input-card__label--error {
color: red;
}
<head>
</head>
<body>
<div class="input-card">
<h1 class="input-card__title">Where are you?</h1>
<h3 class="input-card__label">LONGITUDE</h3>
<input type="text" placeholder="Longitude" class="input-card__input">
<h3 class="input-card__label">ALTITUDE</h3>
<input type="text" placeholder="Altitude" class="input-card__input">
<button class="input-card__button">Show me weather ⛅</button>
</div>
</body>

There's a few errors in your code, here's a version I modified:
submitBtn[0].addEventListener("click", function checkInputs() {
for(let i = 0; i<coordValues.length;i++) {
if(coordValues[i].value === "" || isNaN(Number(coordValues[i].value))) {
inputLabel[i].classList.add("input-card__label--error");
inputLabel[i].innerHTML = "Oops! Write a number here."
console.log("nop");
return;
}
inputLabel[i].classList.remove("input-card__label--error");
inputLabel[i].innerHTML = labelArray[i];
}
console.log("yep");
});
One issue is the double for loop, it over complicates what you're trying to do.
Then once removed your code is left with a for loop then a test which all end up with a break so you never do more than one iteration.
The code above basically says log yes unless you find a reason to log nop.

In this case we need a flag to remember the error state:
submitBtn[0].addEventListener("click", function checkInputs() {
let allInputValid = true
for(let i = 0; i<coordValues.length;i++) {
if(coordValues[i].value === "" || isNaN(Number(coordValues[i].value))) {
inputLabel[i].classList.add("input-card__label--error");
inputLabel[i].innerHTML = "Oops! Write a number here."
console.log("nop");
allInputValid = false
}
else {
inputLabel[i].classList.remove("input-card__label--error");
inputLabel[i].innerHTML = labelArray[i];
}
}
if ( allInputValid )
console.log("yep");
});
Whenever an error is spotted, allInputValid is set to false. If there's two errors you set allInputValid to false twice.

Related

How a make a comparison values on button click?

When the user clicks on the button, you need to compare the values ​​in certain fields and display the values ​​according to the template.
I know this is a very stupid question, but I can't make it so that all values ​​are "true" and the function is considered executed and the button works out the correct values
I try like this
function serviceCheck() {
function serviceCheck1() {
var CasePageServiceSelector = document.getElementById('CasePageServicePact00d7746a-0675-49ac-8608-323407985e07ComboBoxEdit-el').value;
var ServiceDocument = 'Case';
if (CasePageServiceSelector === ServiceDocument){
console.log('1')
}
}
function serviceCheck2() {
var CasePageServiceCategSelector = document.getElementById('CasePageServiceCategoryComboBoxEdit-el').value;
var ServiceCateg = 'Talker';
if (CasePageServiceCategSelector === ServiceCateg){
console.log('2!')
}
}
function serviceCheck3() {
var CasePageServiceItemSelector = document.getElementById('CasePageServiceItemComboBoxEdit-el').value;
var ServiceItem = '4. Problem';
if (CasePageServiceItemSelector === ServiceItem){
console.log('3')
}
}
}
function ChangeSecondTA() {
let Theme = $('#CasePageSubjectTextEdit-el').val('template');
let Symptoms = $('#CasePageSymptomsHtmlEdit-el').val('template2 ');
}
function onButtonClick(event) {
try {
alert(serviceCheck)
} catch (error) {
console.error("error: ", error);
}
};
At first, you write the function serviceCheck() and you call it using: alert(serviceCheck)
Why do you use alert, if your function does not return anything?
Secondly, you write three functions serviceCheck1-3() however you newer call these functions.
you need write something like this:
function serviceCheck() {
let in1 = document.getElementById('input1').value;
let in2 = document.getElementById('input2').value;
if (in1 == in2) {
alert('true');
} else {
alert('false');
}
}
function onButtonClick() {
serviceCheck();
};
<html>
<head></head>
<body>
<button onclick="onButtonClick()">input1 == input2 ?</button>
<br><input id='input1' type="text" value="55">
<input id='input2' type="text" value="55">
</body>
</html>

Function only working after edit and refresh in Vue?

My function in Vue seems to only work after intentionally causing an error and then refreshing the page. The code works fine it's just the initialization that's isn't working.
Can anyone help?
Brief explanation:
When the user hits the button, a function is called by the name of provjeriOdgovore.
The function looks for all the elements with the class name answer (the input fields), and then iterates, checking if the value of the input is contained inside of the variable odgovori. If it is, the program appends the class green-color to the classList of answer, if it isn't, the same thing happens but instead of green-color, it's red-color
Code in question:
HTML part:
<input class="answer" type="text">
<input class="answer" type="text">
<input class="answer" type="text">
<button :onclick="provjeriOdgovore()">Provjeri</button>
Javascript part:
const odgovori = [[long array of strings], [long array of strings], [long array of strings]]
export default {
data() {
return {
provjeriOdgovore: () => {
let questionDiv = document.getElementsByClassName("answer")
for (let i = 0; i < questionDiv.length; i++) {
let userInput = questionDiv[i].value.toLowerCase();
questionDiv[i].classList.add("color-white")
if (odgovori[i].includes(userInput)) {
console.log("tocno", questionDiv[i])
questionDiv[i].classList.add("green-color");
if (questionDiv[i].classList.length > 2) {
questionDiv[i].classList.remove("red-color");
}
} else {
console.log("netocno" ,questionDiv[i])
questionDiv[i].classList.add("red-color");
if (questionDiv[i].classList.length > 2) {
questionDiv[i].classList.remove("green-color");
}
}
}
}
}
}
}
You need to put your method in,
methods: {
provjeriOdgovore() {
let questionDiv = document.getElementsByClassName("answer");
for (let i = 0; i < questionDiv.length; i++) {
let userInput = questionDiv[i].value.toLowerCase();
questionDiv[i].classList.add("color-white");
if (odgovori[i].includes(userInput)) {
console.log("tocno", questionDiv[i]);
questionDiv[i].classList.add("green-color");
if (questionDiv[i].classList.length > 2) {
questionDiv[i].classList.remove("red-color");
}
} else {
console.log("netocno", questionDiv[i]);
questionDiv[i].classList.add("red-color");
if (questionDiv[i].classList.length > 2) {
questionDiv[i].classList.remove("green-color");
}
}
}
},
},
and then call it... if you want it run on it's own while rendering or creation call it in any lifecyclehook

JavaScript validate at least one radio is checked

I'm building a tabbed for using a mixture of JavaScript and CSS. So far I have validation on my text inputs that ensure a user can't progress unless data has been input.
I have got it working so that my script detected unchecked radios, but the problem is that I want the user to only select one. At the moment even when one gets selected the script won't let you progress because it's seeing the other three as unchecked. How could I add a rule to look at the radios and set valid = true if one is selected - if more or less than 1 then fail?
my function:
function validateForm() {
// This function deals with validation of the form fields
var x, y, i, valid = true;
x = document.getElementsByClassName("tab");
y = x[currentTab].getElementsByTagName("input");
// A loop that checks every input field in the current tab:
for (i = 0; i < y.length; i++) {
// If a field is empty...
if (y[i].type === "text") {
if (y[i].value == "") {
// add an "invalid" class to the field:
y[i].classList.add('invalid');
// and set the current valid status to false:
valid = false;
} else if (!y[i].value == "") {
y[i].classList.remove('invalid');
valid = true;
}
}
if (y[i].type === 'radio') {
//y[i].classList.remove('invalid');
//valid = true;
if (!y[i].checked) {
y[i].classList.add('invalid');
valid = false;
} else {
y[i].classList.remove('invalid');
valid = true;
}
}
}
// If the valid status is true, mark the step as finished and valid:
if (valid) {
document.getElementsByClassName("step")[currentTab].className += " finish";
}
return valid; // return the valid status
}
Do I need to split the validation down into further functions to separate validating different field types?
I think that radio buttons are the way to go. Especially from a UI point of view. Why would you let the user pick more than one item only to tell them later they can't?
Having said that, you can do what you're trying to do with something like this:
function validateForm() {
var checkBoxHolders = document.querySelectorAll(".checkboxholder");
var valid = true;
for (var i = 0; i < checkBoxHolders.length; i++) {
var numChecked = checkBoxHolders[i].querySelectorAll("input[type='checkbox']:checked").length;
if (numChecked === 1) {
checkBoxHolders[i].classList.remove('invalid');
} else {
checkBoxHolders[i].classList.add('invalid');
}
valid = valid && numChecked === 1;
}
document.getElementById('valid').innerHTML = 'I am valid: ' + valid;
}
.invalid {
background-color: orange;
}
<input type="text" id='foo'>
<input type="text" id='bar'>
<div class='checkboxholder'>
First group
<input type="checkbox" id='check1'>
<input type="checkbox" id='check2'>
</div>
<div class='checkboxholder'>
Second group
<input type="checkbox" id='check3'>
<input type="checkbox" id='check4'>
</div>
<button type='button' onclick='validateForm()'>Validate me</button>
<div id='valid'>
</div>
With jQuery, it'd be something like:
if (jQuery('input[name=RadiosGroupName]:checked').length === 0) {
valid = false;
}

How to put IF CONDITION with an AND CONDITION and the NOT OPERATOR in javascript?

<body>
<input type="radio" name="other_charges" value="To Pay" >To Pay
<input type="radio" name="other_charges" value="COD" >COD
<input type="submit" onclick="sum_cash()"/>
</body>
here is my html ...in this i am having two radio buttons with different values and i have called a function using onclick event....here is the code...
<script type="text/javascript">
function sum_cash() {
var elements_ocharges = document.getElementsByName('other_charges');
for (var i = 0; i < elements_ocharges.length; i++) {
if (elements_ocharges[i].checked)
value_ocharges = elements_ocharges[i].value;
}
var val_ocharges=value_ocharges;
if (val_ocharges=="To Pay") {
alert("pay");
}
if (val_ocharges=="COD") {
alert("cod");
}
if ((val_ocharges!="COD") && (val_ocharges!="To Pay") ) {
alert("hi");
}
}
</script>
Now in the function, I am checking the value of the radio button selected. If the user chooses the Pay radio button then on clicking the submit button it alerts the user for payment. When the user chooses the COD radio button then on submitting it alerts COD.
What I want is that when the user has selected nothing and clicked on the submit button then it should alert the user. Unfortunately, it is not checking the condition. Can anyone please help me?
You may try like this:
<script type="text/javascript">
function sum_cash()
{
var elements_ocharges = document.getElementsByName('other_charges');
var value_ocharges = null;
for (var i = 0; i < elements_ocharges.length; i++)
{
if (elements_ocharges[i].checked)
value_ocharges = elements_ocharges[i].value;
}
var val_ocharges=value_ocharges;
if(val_ocharges=="To Pay")
{
alert("pay");
}
else if(val_ocharges=="COD")
{
alert("cod");
}
else
{
alert("hi");
} }
</script>
your problem is this conditional near the top:
if (elements_ocharges[i].checked)
value_ocharges = elements_ocharges[i].value;
since neither radio button is checked, value_ocharges is never set. this will cause an error when you attempt to access the value with var val_ocharges=value_ocharges; you should set the value of value_ocharges to something (null is fine) before entering your loop, then everything will work:
<script type="text/javascript">
function sum_cash()
{
var elements_ocharges = document.getElementsByName('other_charges');
var value_ocharges = null;
for (var i = 0; i < elements_ocharges.length; i++)
{
if (elements_ocharges[i].checked)
value_ocharges = elements_ocharges[i].value;
}
var val_ocharges=value_ocharges;
if(val_ocharges=="To Pay")
{
alert("pay");
}
if(val_ocharges=="COD")
{
alert("cod");
}
if ((val_ocharges!="COD") && (val_ocharges!="To Pay") )
{
alert("hi");
}
}
</script>
Try this ,
else if ((val_ocharges =="")
{
alert("hi");
}
Hope this helps!!
First, set your value_ocharges above the for loop:
var value_ocharges = false;
Then, instead of:
if ((val_ocharges!="COD") && (val_ocharges!="To Pay") ) {
alert("hi");
}
use this outside of the loop:
if (!val_ocharges){
alert("hi");
}
Basically, this checks if val_ocharges is defined somewhere in the loop, and if it's not, it triggers the alert.

How do I compare the value of an element returned by getElementsByName to a string?

I'm making a quiz with a text input. This is what I have so far:
<html>
<head>
<script type="text/javascript">
function check() {
var s1 = document.getElementsByName('s1');
if(s1 == 'ō') {
document.getElementById("as1").innerHTML = 'Correct';
} else {
document.getElementById("as1").innerHTML = 'Incorrect';
}
var s2 = document.getElementsByName('s2');
if(s2 == 's') {
document.getElementById("as2").innerHTML = 'Correct';
} else {
document.getElementById("as2").innerHTML = 'Incorrect';
}
//(...etc...)
var p3 = document.getElementsByName('p3');
if(p3 == 'nt') {
document.getElementById("ap3").innerHTML = 'Correct';
} else {
document.getElementById("ap3").innerHTML = 'Incorrect';
}
}
</script>
</head>
<body>
1st sing<input type="text" name="s1"> <div id="as1"><br>
2nd sing<input type="text" name="s2"> <div id="as2"><br>
<!-- ...etc... -->
3rd pl<input type="text" name="p3"> <div id="ap3"><br>
<button onclick='check()'>Check Answers</button>
</body>
</html>
Every time I check answers it always says Incorrect and only shows the first question. I also need a way to clear the text fields after I check the answers. One of the answers has a macro. Thanks in advance.
The method getElementsByName returns a NodeList, you can't really compare that against a string. If you have only one element with such name, you need to grab the first element from that list using such code instead:
var s1 = document.getElementsByName('s1')[0].value;
To make it more flexible and elegant plus avoid error when you have typo in a name, first add such function:
function SetStatus(sName, sCorrect, sPlaceholder) {
var elements = document.getElementsByName(sName);
if (elements.length == 1) {
var placeholder = document.getElementById(sPlaceholder);
if (placeholder) {
var value = elements[0].value;
placeholder.innerHTML = (value === sCorrect) ? "Correct" : "Incorrect";
} else {
//uncomment below line to show debug info
//alert("placeholder " + sPlaceholder+ " does not exist");
}
} else {
//uncomment below line to show debug info
//alert("element named " + sName + " does not exist or exists more than once");
}
}
Then your code will become:
SetStatus('s1', 'ō', 'as1');
SetStatus('s2', 's', 'as2');
//...
document.getElementsByName('s1') is an array you should use document.getElementsByName('s1')[0] to get certain element(first in this case)

Categories