JavaScript check for input only works backwards - javascript

When I fill in all the input fields and choose an option in the select dropdown, for some reason the class will not be removed unless I start with the select dropdown. How come is that? I really don't get it.
var firstNameInput = document.getElementById('first_name_input');
var lastNameInput = document.getElementById('last_name_input');
var emailInput = document.getElementById('email_input');
var jobTitleInput = document.getElementById('job_title_input');
var departmentSelect = document.getElementById('department_select');
function checkForInput() {
var inputFields = firstNameInput.value && lastNameInput.value && emailInput.value && jobTitleInput.value && departmentSelect.options[departmentSelect.selectedIndex].value;
if(inputFields != '') {
copyButton.classList.remove('disabled');
} else {
copyButton.classList.add('disabled');
}
}
<form>
<input id="first_name_input" type="text" onkeyup="checkForInput();">
<input id="last_name_input" type="text" onkeyup="checkForInput();">
<input id="email_input" type="email" onkeyup="checkForInput();">
<input id="job_title_input" type="text" onkeyup="checkForInput();">
<select id="department_select" onchange="checkForInput();">
<option value="" disabled selected>Afdeling</option>
<option value="administration">Administration</option>
<option value="marketing">Marketing</option>
<option value="support">Support</option>
<option value="reklamation">Reklamation</option>
<option value="produktion">Produktion</option>
</select>
</form>
<a class="btn disabled" id="copyButton">Copy</a>

Here is a functional version:
<style>
.btn {
color: blue;
}
.disabled {
color: red;
font-size: 20px;
}
</style>
<form>
<input id="first_name_input" type="text" onkeyup="checkForInput();">
<input id="last_name_input" type="text" onkeyup="checkForInput();">
<input id="email_input" type="email" onkeyup="checkForInput();">
<input id="job_title_input" type="text" onkeyup="checkForInput();">
<select id="department_select" onchange="checkForInput();">
<option value="" disabled selected>Afdeling</option>
<option value="administration">Administration</option>
<option value="marketing">Marketing</option>
<option value="support">Support</option>
<option value="reklamation">Reklamation</option>
<option value="produktion">Produktion</option>
</select>
</form>
<a class="btn disabled" id="copyButton">Copy</a>
<script>
const checkForInput = () => {
// start a tally to see how many fields have values
let allDone = 0
// get value of each element
const firstNameInput = document.getElementById('first_name_input').value
const lastNameInput = document.getElementById('last_name_input').value
const emailInput = document.getElementById('email_input').value
const jobTitleInput = document.getElementById('job_title_input').value
const departmentSelect = document.getElementById('department_select').value
// put values into an array
const currentValues = [
firstNameInput,
lastNameInput,
emailInput,
jobTitleInput,
departmentSelect
]
// map over array and if value has any length, (1 character or greater)
// increment tally by 1
currentValues.map((value) => value.length ? allDone += 1 : false)
// if tally = 5, all fields have data in them, remove disabled class
if (allDone === 5) return copyButton.classList.remove('disabled')
// else add disabled class (just incase they wipe out a field)
return copyButton.classList.add('disabled')
}
</script>
I demonstrated several techniques that you can research further:
fat arrow syntax, http://wesbos.com/arrow-functions/
array literal, What is array literal notation in javascript and when should you use it?
Array.map, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
ternary operator, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator
inline IF statement shorthand, you can omit { and } for if statements that only have one expression, such as if (something === 'ok') console.log(something)
I used that along with explicit returns to get rid of the else { } block
const and let, http://wesbos.com/let-vs-const/
implicit return, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
This code will be easy to extend and maintain if you need to add or remove fields.
Put a console.log(currentValues) right above currentValues.map() if you want to see how it is behaving on keypress.
If you want to see even more, change the map part to this:
currentValues.map((value) => {
console.log('Examining:', value)
console.log('Character length:', value.length)
console.log('Number of completed fields:', allDone)
return value.length ? allDone += 1 : false
})

Related

Change hidden input field value according to select options

I am trying to write a script for changing the hidden input value according to selected options.
I have hindi data stored on a variable and I need to pick this hindi data according to english data selected in select feild. The select options are working fine so far, but I am unable to fectch the related hindi data.
var stateObject = {
"Bihar": {
"Begusarai": ["Bachhwara", "Bakhari", "Balia", "Barauni", "Begusarai", "Bhagwanpur", "Birpur", "Cheriya Bariyarpur", "Chhorahi", "Dandari", "Garhpura", "Khudabandpur", "Mansoorchak", "Matihani", "Nawkothi", "Sahebpur Kamal", "Samho Akha Kurha", "Teghra"],
},
}
var stateObjectHindi = {
"बिहार": {
"बेगूसराय": ["बछवारा", "बखरी", "बलिया", "बरौनी", "बेगुसराय", "भगवानपुर", "बीरपुर", "चेरिया बरियारपुर", "छौराही", "डंडारी", "गढ़पुरा", "खोदाबंदपुर", "मंसूरचक", "मटिहानी", "नावकोठी", "साहेबपुर कमाल", "साम्हो अखा कुरहा", "तेघरा"],
},
}
window.onload = function() {
var stateList = document.getElementById("stateList"),
stateListHindi = document.getElementById("stateListHindi"),
districtList = document.getElementById("districtList"),
districtListHindi = document.getElementById("districtListHindi"),
blockList = document.getElementById("blockList"),
blockListHindi = document.getElementById("blockListHindi");
for (var country in stateObject) {
stateList.options[stateList.options.length] = new Option(country, country);
}
stateList.onchange = function() {
districtList.length = 1; // remove all options bar first
blockList.length = 1; // remove all options bar first
if (this.selectedIndex < 1) return; // done
for (var state in stateObject[this.value]) {
districtList.options[districtList.options.length] = new Option(state, state);
}
}
stateList.onchange(); // reset in case page is reloaded
districtList.onchange = function() {
blockList.length = 1; // remove all options bar first
if (this.selectedIndex < 1) return; // done
var district = stateObject[stateList.value][this.value];
for (var i = 0; i < district.length; i++) {
blockList.options[blockList.options.length] = new Option(district[i], district[i]);
stateListHindi.value = this.value;
}
}
}
<select name="state" id="stateList">
<option value="" selected="selected">Select State</option>
</select>
<select name="district" id="districtList">
<option value="" selected="selected">Select District</option>
</select>
<select name="block" id="blockList">
<option value="" selected="selected">Select Block</option>
</select>
<br/> State in Hindi: <input type="hidden" class="stateListHindi" id="stateListHindi" name="stateListHindi" value="" /><br/> District in Hindi: <input type="hidden" class="districtListHindi" id="districtListHindi" name="districtListHindi" value="" /><br/>Block in Hindi: <input type="hidden" class="blockListHindi" id="blockListHindi" name="blockListHindi" value="" /><br/>
JSFiddle Demo
Your data structure is perhaps not too well-suited for what you want here. You need to find the corresponding property in both objects, for the first two levels, by their position - so you will have to extract the keys first, and use indexOf to locate them.
So for the state first of all, that would be
var selectedKeyIndex = Object.keys(stateObject).indexOf(this.value);
stateListHindi.value = Object.keys(stateObjectHindi)[selectedKeyIndex];
Extract the keys from the English object, and find the index of the property matching the current selection in there. Then use that index, to extract the corresponding property name from the Hindi object.
Now, for the district, you'll have to do the same thing, but for one more level:
var selectedKeyIndex = Object.keys(stateObject[stateList.value]).indexOf(this.value);
districtListHindi.value = Object.keys(stateObjectHindi[stateListHindi.value])[selectedKeyIndex];
And then for the Blocks, which are in an array, you can select directly by index,
var selectedKeyIndex = stateObject[stateList.value][districtList.value].indexOf(this.value);
blockListHindi.value = stateObjectHindi[stateListHindi.value][districtListHindi.value][selectedKeyIndex];
All of it put together here: https://jsfiddle.net/6g5ad4cz/.
(I made the hidden fields into normal text fields, so that the result can be visually checked straight away.)

How to change a placeholder by a select tag?

I want the placeholder of the text input to change depending on the option selected on the select tag. Also, I wanted to change the text input to disabled on the "DOC" option.
I gathered some code examples, but none of them were showing exactly what I was looking for, so I ended up with this code below.
function changeDOC() {
var x = document.getElementById("document").value;
if (x == "doc") {
document.getElementById('docu').disabled = true;
} else if (x == "cpf") {
document.getElementsById("doc")[0].placeholder = 'CPF';
} else if (x == "cnpj") {
document.getElementsById("doc")[0].placeholder = 'CPF';
}
}
<select onchange="changeDOC" id="document">
<option value="doc" selected>DOC</option>
<option value="cpf">CPF</option>
<option value="cnpj">CNPJ</option>
</select>
<input type="text" class="form-control" id="docu" placeholder="Select a document.">
But it does nothing.
There are a few things wrong in your code, first off, there is no getElementsById() function in document, it's getElementById() since there can only ever be one element with a given ID in valid HTML (meaning you don't have to access the 0th element of the return value ([0])):
document.getElementsById("doc")[0].placeholder = 'CPF';
should be
document.getElementById("doc").placeholder = 'CPF';
Also you have to add parentheses to your markup to actually execute the function.
<select onchange="changeDOC" id="document">
Has to be
<select onchange="changeDOC()" id="document">
Also if you have DOC as selected by default, you should deactivate the element by default too, and activate it again if you choose the other options.
Here's the full code:
function changeDOC() {
var x = document.getElementById("document").value;
if (x == "doc") {
document.getElementById('docu').disabled = true;
} else if (x == "cpf") {
document.getElementById("docu").placeholder = 'CPF';
document.getElementById('docu').disabled = false;
} else if (x == "cnpj") {
document.getElementById("docu").placeholder = 'CPF';
document.getElementById('docu').disabled = false;
}
}
<select onchange="changeDOC()" id="document">
<option value="doc" selected>DOC</option>
<option value="cpf">CPF</option>
<option value="cnpj">CNPJ</option>
</select>
<input type="text" class="form-control" id="docu" placeholder="Select a document." disabled="true">
First, there is no such method as getElementsById(), it's getElementById(), which returns one element (if found). So there is no array returned from it, so passing an index isn't going to get you anything.
Next, your inline event attribute has to provide executable code that would invoke your function, but you didn't put parenthesis after the function name, so your code doesn't do this. But, you should not be using inline HTML event attributes in the first place. Instead, do all your event binding in JavaScript with the standard addEventListener() method, which actually does take a callback method reference (no parenthesis).
Now, it appears that you just want the input to have a placeholder that matches the selected item from the list, in which case, you don't need an if statement for that, just set the placeholder to the selected value directly. You only need the if to detect if the first item was selected and in that case, use the setAttribute method to set up the disabled functionality.
Also, since the select's first option is DOC and that choice should make the input disabled, you should add the disabled attribute to the input HTML statically from the start.
See the comments below for more adjustments.
// Get references to elements you'll work with just once, not upon
// each invocation of the event handler. Also, don't name or give things
// id's that are also the name of an object (ie. document)
let select = document.getElementById("list");
let input = document.getElementById("docu");
// Set up the event handler in JavaScript, not with HTML attributes like onchange
select.addEventListener("change", changeDOC);
function changeDOC() {
input.placeholder = this.value; // `this` is a reference to the select itself
if (this.value == "doc") {
input.setAttribute("disabled", "disabled");
} else {
input.removeAttribute("disabled");
}
}
<select id="list">
<option value="doc" selected>DOC</option>
<option value="cpf">CPF</option>
<option value="cnpj">CNPJ</option>
</select>
<input type="text" class="form-control" id="docu" placeholder="Select a document." disabled>
There is a lot of syntax error in your code, just figure out errors but you should also go through over it.
Number 1:
You need to call the function not just place the name.
<select onchange="changeDOC" id="document"> // Wrong
<select onchange="changeDOC()" id="document"> // Correct
Number 2:
document.getElementsById("doc") // Wrong
document.getElementById("doc") // Correct
Number 3:
In the input tag you are using id="docu" and get with ('doc')
function changeDOC() {
var x = document.getElementById("document").value;
if (x == "doc") {
document.getElementById('docu').disabled = true;
document.getElementById("docu").placeholder = 'DOC';
} else if (x === "cpf") {
document.getElementById('docu').disabled = false;
document.getElementById("docu").placeholder = 'CPF';
} else if (x === "cnpj") {
document.getElementById('docu').disabled = false;
document.getElementById("docu").placeholder = 'CNPJ';
}
}
<select onchange="changeDOC()" id="document">
<option value="doc" selected>DOC</option>
<option value="cpf">CPF</option>
<option value="cnpj">CNPJ</option>
</select>
<input type="text" class="form-control" disabled id="docu" placeholder="Select a document.">
I have removed the extra id from the select option in HTML.
In JavaScript the select variable returns the whole select node with it's children.
So I've added an event listener that on a change fires off a function with a parameter e that target's children (the one that's been selected) and add set's it's value as an attribute to the input tag.
const select = document.querySelector('select');
const input = document.querySelector('input');
select.addEventListener('change', e => {
input.setAttribute('placeholder', `Select a ${e.target.value.toUpperCase()}`);
})
<select>
<option value="doc" selected>DOC</option>
<option value="cpf">CPF</option>
<option value="cnpj">CNPJ</option>
</select>
<input type="text" class="form-control" id="docu" placeholder="Select a document." />

How to find average of innerHTMLs?

I have input fields and selects. For different select options there are different equations. After calculating equations, I used .innerHTML to show results. I got first part of the code worked, but I am stuck at the last part. When I try to calculate average of outputs, It shows Nan. Can anyone help with this problem? Thanks in advance.
var container = document.getElementById('container');
var span1 = document.getElementById('span1');
var span2 = document.getElementById('span2');
var output = document.getElementById('output');
function average() {
var a = parseFloat(document.getElementById('a').value);
var b = parseFloat(document.getElementById('b').value);
var c = parseFloat(document.getElementById('c').value);
var d = parseFloat(document.getElementById('d').value);
if (document.getElementById('select1').value == '1') {
span1.innerHTML = ((a+b)/(a*b)).toFixed(2);
} else if (document.getElementById('select1').value == '2') {
span1.innerHTML = ((a*b)/(a+b)).toFixed(2)
} else {
span1.innerHTML = '';
}
if (isNaN(span1.innerHTML)) {
span1.innerHTML = '';
}
if (document.getElementById('select1').value == 'none1') {
span1.innerHTML = 'None'
}
if (document.getElementById('select2').value == '3') {
span2.innerHTML = ((c+d)*100/(c*d)).toFixed(2);
} else if (document.getElementById('select2').value == '4') {
span2.innerHTML = ((c*d)*100/(c+d)).toFixed(2)
} else {
span2.innerHTML = '';
}
if (isNaN(span2.innerHTML)) {
span2.innerHTML = '';
}
if (document.getElementById('select2').value == 'none2') {
span2.innerHTML = 'None'
}
var percent = document.getElementsByClassName('percent');
for (var i = 0; percent.length > i; i++) {
if (percent.length > 0) {
output.innerHTML = percent[i]/(percent.length);
}
}
}
container.addEventListener('change', average);
container.addEventListener('input', average);
<div id="container">
<input id="a" type="number">
<input id="b" type="number">
<select name="abc" id="select1">
<option value="Choose">Choose...</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="none1">None</option>
</select>
<br>
<input id="c" type="number">
<input id="d" type="number">
<select name="abcd" id="select2">
<option value="Choose">Choose...</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="none2">None</option>
</select>
<span id="span1" class="percent"></span>
<span id="span2" class="percent"></span><br>
<span id="output"></span>
</div>
.innerHTML gets or sets the content of an element by invoking the HTML parser on the string passed as the value or extracted from the element. When the content is, or is to become just text (no HTML to be parsed), you should use .textContent as this will not invoke the HTML parser on the content, which saves processing power. In your case, you should be using .textContent.
Now, either way, data sent to or gotten from either .innerHTML or .textContent is a string, so if you want to do math with the value, you need to first convert it to a number. This can be done in several ways:
parseInt(stringToBeConverted, radix)
parseFloat(stringToBeConverted)
Number(stringToBeConverted)
+stringToBeConverted
Now, you have two issues, first when some of the text fields are still empty, their value is an empty string and parseFloat() on an empty string returns NaN. This can be solved by giving each field a default value of 0 in the HTML (i.e. <input id="a" type="number" value="0">).
Second, even with a, b, c, and d all having numeric values, your math:
((a + b) / (a * b)).toFixed(2);
Will result in NaN when a * b results in 0 because that will result in a division by zero situation.
You need to change your algorithm to test for this situation before doing the math.
I have no idea what you're trying to do, but I think this might be the correct solution it's a working way of getting the value of the percent[i] HTML element:
Change
output.innerHTML = percent[i]/(percent.length);
to
output.innerHTML = percent.item(i).innerHTML/(percent.length);
or
output.innerHTML = percent[i].innerHTML/(percent.length);

Javascript If statement with boolean value

I have two dropdown select boxes and I want a textbox to update with a value based on the selected texts from the two boxes.
If the first box selected is 'dollars' and the second is 'naira', I want the rate to be 100 and this value inputted in the textbox with the id of rate.
Unfortunately when my function executes I keep getting a value of undefined. Something is obviously wrong with my if statement but I can't figure it out.I need to do this with pure javascript, not jquery.
Here is my code:
<p>Select currency to send</p>
<select id="fromCurrency">
<option value = "Dollars">Dollars</option>
<option value = "Pounds">Pounds</option>
<option value = "Naira">Naira</option>
</select>
<p>Select currency to receive</p>
<select id="toCurrency">
<option value = "Naira">Naira</option>
<option value = "Dollars">Dollars</option>
<option value = "Pounds">Pounds</option>
</select><br />
<label>Enter amount to send</label>
<input type="text" id="amount" name="amount"><br />
<button onclick ="getRate()">Get Rate</button><br />
<label>Rate:</label>
<input type="text" id="rate" name="rate"><br />
<label>Total:</label>
<input type="text" id="total" name="total"><br />
<script>
function getRate() {
var e = document.getElementById("fromCurrency");
var eSend = e.options[e.selectedIndex].value;
var i = document.getElementById('toCurrency');
var eReceive = i.options[i.selectedIndex].value;
var rate = document.getElementById('rate');
var dollars = {
'pounds':20,
'naira':15
};
if (eSend =='dollars' && eReceive =='naira') {
var rValue= (dollars['pounds']);
};
rate.value = rValue;
};
</script>
Please advice.
Thanks
EDIT:
I tried to use a switch statement as I have about 6 different conditions, and this is what I tried but it didn't work.
var rValue = 0;
switch (rValue) {
case (eSend =='Dollars' && eReceive =='Naira'):
rValue= (dollars['naira']);
break;
case (eSend =='Dollars' && eReceive =='Pounds'):
rValue= (dollars['pounds']);
break;
}
rate.value = rValue;
JavaScript is case-sensitive, your if statement:
if (eSend =='dollars' && eReceive =='naira') {
is looking for dollars, not Dollars, capitalize to match your select values:
if (eSend =='Dollars' && eReceive =='Naira') {

drop down list with more then one dilimiter. can get JS to work

Ok so i am trying to get a textarea where a user can type in text. select a delimiter from a dropdown list. Hit count and it will count how many times it splits.
I cant seem to get my code to split at all. here is my code.
JavaScript
window.onload = function() {
document.getElementById("change").onclick = function() {
var paragraph = document.getElementById('box').value;
var x = document.getElementById("changeCase");
var getInfo = document.getElementById('ParaWrite');
var LowerCase = " ";
var splitAT = " ";
alert("above the for loop");
if (x.checked === true)
{
LowerCase = paragraph.toLowerCase();
}
else
{
LowerCase = paragraph;
}
for (var i = 0; i <document.form1.split.options.length; i++)
{
if (document.form1.split.options[i].selected === true)
{
splitAT = paragraph.split(options[i]);
}
}
document.write(splitAT);
doc write is just so i can see if it even makes it that far in the code and it does not.
here is my HTML
<form name="form1" id="form1">
<textarea type="text" id="box" value=""/></textarea>
<input type='checkbox' name='write' id='changeCase' value='Check'/><br>
<input type='button' value="Count" id="change"/>
<select name="split" id="split">
<option value="like">like</option>
<option value="monkey">monkey</option>
<option value="I">I</option>
<option value=".">.</option>
<option value=",">,</option>
<option value="?">?</option>
<option value=" ">[Space]</option>
</select>
</form>
<div id="ParaWrite">
</div>
options is not defined.
splitAT = paragraph.split(document.form1.split.options[i]);
http://jsfiddle.net/ExplosionPIlls/KeZEd/

Categories