I have a problem with the script.
I am trying to count two input fields, and insert the result into the third field.
But it doesn't work, and unfortunately I can't figure out what's wrong.
function sum() {
var txtFirstNumberValue = document.querySelectorAll('#firstID > div > div > div > input').value;
var txtSecondNumberValue = document.querySelectorAll('#second > div > div > div > input').value;
if (txtFirstNumberValue == "")
txtFirstNumberValue = 0;
if (txtSecondNumberValue == "")
txtSecondNumberValue = 0;
var result = parseInt(txtFirstNumberValue) / parseInt(txtSecondNumberValue);
if (!isNaN(result)) {
document.querySelectorAll('#third > div > div > div > input').value = result;
}
}
<div id="firstID"><div>
<label>first</label>
<div>
<div>
<input name="drts[field_first][0]" type="number" value="" maxlength="255">
</div>
</div>
</div></div>
<div id="second"><div>
<label>second</label>
<div>
<div>
<input name="drts[field_second][0]" type="number" maxlength="255">
</div>
</div>
</div></div>
<div id="third"><div>
<label>third</label>
<div>
<div>
<input name="drts[field_third][0]" type="number" value="" maxlength="255">
<div></div>
</div>
</div>
</div></div>
There are a few problems here.
Are you actually calling sum? I've added a call in the example code so you can run it.
Your query selectors are not right. There isn't actually anything in the divs with the IDs you query. I've moved the input boxes into the correct places. When debugging, you should check that you are actually finding elements in your querySelectorAll call before proceeding.
querySelectorAll doesn't have a value property. You would need to iterate over each element before getting the items. Given you specifically want one item, it would be better to use something more specific like getElementById. I've kept the original querySelectorAll but changed the IDs on the divs to classes so we can have more than one result for this example. Then, I iterate over them pulling out the value to add to result. I've moved the parseInt to the running calculation otherwise it would perform a string concatenation.
Even better than the above would be to access the input directly. There's probably no point accessing a div and drilling down to the input. I've included this example to output the result.
I've removed redundant html. It's not related to the answer but try to keep your markup clean.
function sum() {
var inputElements = document.querySelectorAll('.user-input > div > div > input');
var result = 0;
inputElements.forEach(element => {
result += element.value ? parseInt(element.value) : 0
})
document.getElementById('third').value = result
}
document.getElementById('run-button').addEventListener('click', sum)
<div class="user-input">
<label>first</label>
<div>
<div>
<input name="drts[field_first][0]" type="number" maxlength="255">
</div>
</div>
<div>
<div class="user-input">
<label>second</label>
<div>
<div>
<input name="drts[field_second][0]" type="number" maxlength="255">
</div>
</div>
<div>
<label>third</label>
<div>
<div>
<input id="third" name="drts[field_third][0]" type="number" value="" maxlength="255">
<div></div>
</div>
</div>
<div>
<button type="button" id="run-button">Run</button>
Try like this
function sum() {
let txtFirstNumberValue = document.querySelector('#firstID input').value;
let txtSecondNumberValue = document.querySelector('#second input').value;
let result = parseInt(txtFirstNumberValue) / parseInt(txtSecondNumberValue);
if (!isNaN(result)) {
document.querySelector('#third input').value = result;
} else {
document.querySelector('#third input').value = '';
}
}
<div id="firstID"><div>
<label>first</label>
<div>
<div>
<input name="drts[field_first][0]" type="number" value="" maxlength="255">
</div>
</div>
</div></div>
<div id="second"><div>
<label>second</label>
<div>
<div>
<input name="drts[field_second][0]" type="number" maxlength="255">
</div>
</div>
</div></div>
<div id="third"><div>
<label>third</label>
<div>
<div>
<input name="drts[field_third][0]" type="number" value="" maxlength="255" disabled>
<div></div>
</div>
</div>
<div>
<button id="button" onclick="sum()">Calculate</button>
</div>
</div>
</div>
const input1 = document.querySelector('#input1');
const input2 = document.querySelector('#input2');
const input3 = document.querySelector('#input3');
const storeInputs = [input1, input2];
for(let i = 0; i < storeInputs.length; i++) {
storeInputs[i].addEventListener('input', function() {
// multiply input1 and input2 with 1 for converting there values from string to number
input3.value = input1.value * 1 + input2.value * 1;
});
};
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<label for="input1">First Input</label>
<input id="input1" type="number" value="0"></input>
<label for="input2">Second Input</label>
<input id="input2" type="number" value="0"></input>
<label for="input3">Third Input</label>
<input id="input3" type="number" value="0"></input>
</body>
</html>
Related
I'm new in JS and I have trouble to finish a converter only with inputs, I explain the problem !
We have two input, Meters and Feet. when I transmit a number to Feet I have the result in Meters. And I Want to do the same think with Meters . and vice versa
let metresEl = document.getElementById('inputMetres');
function LengthConverter(valNum) {
metresEl.value = valNum/3.2808;
}
<div class="container">
<div class="form-group">
<label>Feet</label>
<input type="number" id="inputFeet" placeholder="Feet" oninput="LengthConverter(this.value)" onchange="LengthConverter(this.value)" >
</div>
<div class="form-group">
<label>Metres</label>
<input type="number" id="inputMetres" placeholder="Metres">
</div>
</div>
You can add another parameter in the LengthConvertor function which will say the input unit (meter or feet) and convert it accordingly inside the function using if.
function LengthConverter(valNum, inputUnit) {
if(inputUnit === 'feet')
metresEl.value = valNum/3.2808;
if(inputUnit === 'meter')
feetsEL.value = valNum * 3.2808;
}
<div class="container">
<div class="form-group">
<label>Feet</label>
<input type="number" id="inputFeet" placeholder="Feet" oninput="LengthConverter(this.value,"feet")" onchange="LengthConverter(this.value,"feet")" >
</div>
<div class="form-group">
<label>Metres</label>
<input type="number" id="inputMetres" placeholder="Metres" oninput="LengthConverter(this.value,"meter")" onchange="LengthConverter(this.value,"meter")" >
</div>
</div>
Added inverse conversion:
let metresEl = document.getElementById('inputMetres');
let feetEl = document.getElementById('inputFeet');
function FeetToMetres(valNum) {
metresEl.value = valNum/3.2808;
}
function MetresToFeet(valNum) {
feetEl.value = 3.2808*valNum;
}
<div class="container">
<div class="form-group">
<label>Feet</label>
<input type="number" id="inputFeet" placeholder="Feet" oninput="FeetToMetres(this.value)" onchange="FeetToMetres(this.value)" >
</div>
<div class="form-group">
<label>Metres</label>
<input type="number" id="inputMetres" placeholder="Metres" oninput="MetresToFeet(this.value)" onchange="MetresToFeet(this.value)">
</div>
</div>
You can add a element.addEvenetListener to each input, and when it chances you get it's value, convert, and put in on the right input.
let metresEl = document.getElementById('inputMetres');
let feetsEl = document.getElementById('inputFeets');
metresEl.addEventListener('change', yourCode);
feetsEl.addEventListener('change', yourCode);
For exemple, if metres input changes, you convert to feets and add to feets input.
I'm trying to create an interactive resume template using javascript and html and have managed to use cloneNode to duplicate work history blocks (see attached screenshot)
The problem(s) I am having is that clicking on the add list item button in the cloned/duplicated work history block at the bottom, creates a <li> item in the 1st/cloned element.
The objective is to be able to add or delete ````` list elements within a specific work history block and to also be able to add/remove entire work history sections. Currently it deletes from the top down, which is also an issue.
Thanks for any pointers in advance.
CODE
<!DOCTYPE html>
<html>
<body>
<div id="test">
<div id="node">
<div class="work_history">
<div class="row">
<strong>
<input type="text" name="company" value="ACME Company">
</strong>
</div>
<div class="row">
<input type="text" name="position" value="Cheese Taster">
</div>
<input type="text" name="start" value="1/2019">
<input type="text" name="end" value="2/2020">
<ul id="list">
<li>
<textarea id="task" name="task" rows="4" cols="50">Did some things. Tasted cheese.</textarea>
</li>
<button onclick="addTask()">Add List Item</button>
<button onclick="RemoveTask()">Delete List Item</button>
</ul>
<button onclick="addWork()">Add Work</button>
<button onclick="removeWork()">Remove Work</button>
</div>
</div>
</div>
<script>
function addWork() {
var div = document.getElementById("node");
var cln = div.cloneNode(true);
//cln.setAttribute( 'id', 'newId');
document.getElementById("test").appendChild(cln);
}
function removeWork(){
var last = document.getElementById("test");
// want to delete the last added work history not first
last.removeChild(last.childNodes[0]);
}
function addTask(){
var ul = document.getElementById("list");
var task = document.getElementById("task");
var li = document.createElement("li");
li.setAttribute('id',task.value);
li.appendChild(document.createTextNode(task.value));
ul.appendChild(li);
}
function removeTask(){
var ul = document.getElementById("list");
var task = document.getElementById("task");
var item = document.getElementById(task.value);
ul.removeChild(item);
}
</script>
</body>
</html>
You'd have to use e.currentTarget instead of document.getElementById, otherwise you're only referring to the first instance of it:
function addWork(e) {
const div = e.currentTarget.parentElement;
const cln = div.cloneNode(true);
document.getElementById("test").appendChild(cln);
}
function removeWork(e) {
const last = e.currentTarget.parentElement;
last.parentElement.removeChild(last);
}
function addTask(e) {
const ul = e.currentTarget.parentNode;
let task = ul.children[0].childNodes[1].value;
let li = document.createElement("li");
// Replace paragraph breaks
task = task.replace(/\r?\n|\r/g, " ");
li.innerText = task;
ul.appendChild(li);
}
function removeTask(e) {
const ul = e.currentTarget.parentNode;
ul.removeChild(ul.lastChild);
}
<!DOCTYPE html>
<html>
<body>
<div id="test">
<div id="node">
<div class="work_history">
<div class="row">
<strong>
<input type="text" name="company" value="ACME Company">
</strong>
</div>
<div class="row">
<input type="text" name="position" value="Cheese Taster">
</div>
<input type="text" name="start" value="1/2019">
<input type="text" name="end" value="2/2020">
<ul id="list">
<li>
<textarea name="task" rows="4" cols="50">Did some things. Tasted cheese.</textarea>
</li>
<button onclick="addTask(event)">Add List Item</button>
<button onclick="removeTask(event)">Delete List Item</button>
</ul>
<button onclick="addWork(event)">Add Work</button>
<button onclick="removeWork(event)">Remove Work</button>
</div>
</div>
</div>
</body>
</html>
This allows you to refer to the specific element where the click event occurred and add/remove any elements that are relative within the DOM.
As a side note, it's best practice to have unique id attributes, adding the same id to multiple elements goes against that.
var add_button = $(".add_form_field");
var wrapper = $(".container1");
var max_fields = 9;
var x = 1;
$(add_button).click(function (e) {
e.preventDefault();
if (x < max_fields) {
x++;
$(wrapper).append(
` <div class="email">
<label for="">Year</label>
<input type="text" name="eduYear${x}">
<label for="">Title Name</label>
<input type="text" name="eduTitle${x}">
<label for="">Institution/School Name</label>
<input type="text" name="eduPlace${x}">
<label for="">Details</label>
<input type="text" name="eduNotes${x}"> <br>Delete<hr></div>`
); //add input box
}
});
$(wrapper).on("click", ".delete", function (e) {
e.preventDefault();
$(this).parent("div").remove();
x--;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container1">
<h2>Educations</h2>
<button type="button" class="add_form_field">Add Education
<span style="font-size:16px; font-weight:bold;">+ </span>
</button>
<div class="email">
<label for="">Year</label>
<input type="number" name="eduYear1">
<label for="">Title Name</label>
<input type="text" name="eduTitle1">
<label for="">Institution/School Name</label>
<input type="text" name="eduPlace1">
<label for="">Details</label>
<input type="text" name="eduNotes1">
</div>
you can try this to create dynamic form
I'm working with HTML, JavaScript and CSS. The function objective is to create a border-radius attribute in a div element(id="surface"), and assign the value typed in inputs texts(class="chars_1") to it.
HTML
<div id="container">
<div class="input_wrapper" id="input_wrapper_tl">
<input type="text" id="input_tl" class="chars_1" value="0" onkeypress="changeSize()">
</div>
<div class="input_wrapper" id="input_wrapper_tr">
<input type="text" id="input_tr" class="chars_1" value="0" onkeypress="changeSize()">
</div>
<div class="input_wrapper" id="input_wrapper_br">
<input type="text" id="input_br" class="chars_1" value="0" onkeypress="changeSize()">
</div>
<div class="input_wrapper" id="input_wrapper_bl">
<input type="text" id="input_bl" class="chars_1" value="0" onkeypress="changeSize()">
</div>
<div id="surface">
<textarea id="code" readonly="readonly"></textarea>
<div id="options">
<input type="checkbox" checked="true" id="opt_webkit">
<label for="opt_webkit"> Webkit</label>
<input type="checkbox" checked="true" id="opt_gecko">
<label for="opt_gecko"> Gecko</label>
<input type="checkbox" checked="true" id="opt_css3">
<label for="opt_css3"> CSS3</label>
</div>
</div>
JavaScript Function
function changeSize(){
var surface = document.getElementById("surface");
var inputs = document.getElementsByClassName("chars_1");
var total = 0;
for(var x = 0; x == 3; x++){
total += Number(inputs[x].value);
}
surface.style.borderRadius = String(total)+"px";
}
First I selected both elements and assigned it to these 2 variable "surface" and "inputs". "total" being used in the "for structure" to go through every input element and select every value, and afterward convert to Number to the "total" variable.
The idea is to assign to the border-radius attribute the total variable value, which will be converted to a string so it can be recognized as a value.
Have a border
Fix the for loop for (var x = 0; x < inputs.length; x++) {
Here is an upgraded version
const changeSize = (e) => {
const tgt = e.target; // which input
if (tgt.classList.contains("chars_1")) { // ah, one of those
let total = [...document.querySelectorAll(".chars_1")].reduce(
(sum, input) => {
const val = input.value;
sum += val.trim() === "" || isNaN(val) ? 0 : +val; // only add if a number
return sum;
}, 0);
console.log(String(total) + "px")
document.getElementById("surface").style.borderRadius = String(total) + "px";
}
};
window.addEventListener("load", () => { // when page loads
document.getElementById("container").addEventListener("input", changeSize);
});
#surface {
border: 3px solid black;
}
<div id="container">
<div class="input_wrapper" id="input_wrapper_tl">
<input type="text" id="input_tl" class="chars_1" value="0">
</div>
<div class="input_wrapper" id="input_wrapper_tr">
<input type="text" id="input_tr" class="chars_1" value="0">
</div>
<div class="input_wrapper" id="input_wrapper_br">
<input type="text" id="input_br" class="chars_1" value="0">
</div>
<div class="input_wrapper " id="input_wrapper_bl ">
<input type="text" id="input_bl " class="chars_1" value="0">
</div>
<div id="surface">
<textarea id="code" readonly="readonly"></textarea>
<div id="options">
<input type="checkbox" checked="true" id="opt_webkit">
<label for="opt_webkit"> Webkit</label>
<input type="checkbox" checked="true" id="opt_gecko">
<label for="opt_gecko"> Gecko</label>
<input type="checkbox" checked="true" id="opt_css3">
<label for="opt_css3"> CSS3</label>
</div>
</div>
for(var x = 0; x == 3; x++)
that loop doesn't even execute,
change x==3 on x<3 or whatever you want to achive.
And I guess you must have border to change it's radious
I am trying to loop through the form which has label inside random elements and check if the label matches with the given label name and if matches, I am adding a class to that element. But I am not able get it working, how can I do this?
Here's what I have tried.
Form which has labels inside random elements like div
<form id="grtform">
<div id="section-1">
<lable>Currency type</lable>
<input type="text" name="currencyType">
</div>
<div id="section-2">
<lable>Currency rate</lable>
<input type="text" name="currencyRate">
</div>
<lable>Currency of country</lable>
<input type="text" name="currencyCountry">
<div id="section-3">
<div class="formData">
<lable>Currency due</lable>
<input type="text" name="currencyDue">
</div>
</div>
</form>
Jquery code:
$("#grtform").each(function(){
var matchLable = "Currency due"
var lable = $(this).find('label').text();
if(matchLable == lable){
$(this).addClass('matchFound');
}
});
You need loop through lables, not against form
$("#grtform lable").each(function(){ // selecting all labels of form
var matchLable = "Currency type"
var lable = $(this).text(); // changed here too
if(matchLable == lable){
$(this).addClass('matchFound');
}
});
In above code, this refers to currently iterating label.
After trimming a bit
$("#grtform lable").each(function(){ // selecting all labels of form
if($(this).text() == "Currency type"){
$(this).addClass('matchFound');
}
});
You can also use following way :-
var allLables = document.querySelectorAll("#grtform lable");
for(var i = 0; i < allLables.length; i++){
var matchLable = "Currency type";
var lable = allLables[i].innerText; // changed here too
if(matchLable == lable){
allLables[i].classList.add("matchFound");
}
}
<form id="grtform">
<div id="section-1">
<lable>Currency type</lable>
<input type="text" name="currencyType">
</div>
<div id="section-2">
<lable>Currency rate</lable>
<input type="text" name="currencyRate">
</div>
<lable>Currency of country</lable>
<input type="text" name="currencyCountry">
<div id="section-3">
<div class="formData">
<lable>Currency due</lable>
<input type="text" name="currencyDue">
</div>
</div>
</form>
Alright, this my be a tall order, but I am not making much headway, so I decided to ask for help.
I have a random array of names, and I would like to set these names to the HTML input, disable the HTML input with the value and move to the next one. Is that possible? and my second question is, is my randomGroup going to work, I mean, is all the 14 names be called?
all the help would be appreciated. - I am still working on it.
Here is a snippet:
var randomGroup = ["Luciano", "Patrick", "SHL", "Leo", "Marilyn", "Ranbir", "Helena", "Annie", "Saikaran", "Julie", "Albert" , "Chris", "Igor", "Staci"]
Array.prototype.randomElement = function(){
return this[Math.floor(Math.random() * this.length)]
}
var myRandomElement = randomGroup.randomElement();
/*console.log(myRandomElement);*/
function appendItem(){
var inputs = document.getElementByTagName('input').value = '';
var setInputs = document.getElementByTagName('input').innerHTML = myRandomElement;
/* myRandomElement = randomGroup.randomElement();*/
if (inputs == 0) {
inputs = setInputs;
}
}
appendItem();
body{
margin: 0 auto;
text-align: center;
}
div {
display: block;
margin-bottom: -10px;
}
#group1, #group2, #group3, #group4, #group5, #group6, #group7 {
display: inline-block;
}
<div>
<p id="group1">Group 1</p>
<input type="text" />
<input type="text" />
</div>
<div>
<p id="group2">Group 2</p>
<input type="text" />
<input type="text" />
</div>
<div>
<p id="group3">Group 3</p>
<input type="text" />
<input type="text" />
</div>
<div>
<p id="group4">Group 4</p>
<input type="text" />
<input type="text" />
</div>
<div>
<p id="group5">Group 5</p>
<input type="text" />
<input type="text" />
</div>
<div>
<p id="group6">Group 6</p>
<input type="text" />
<input type="text" />
</div>
<div>
<p id="group7">Group 7</p>
<input type="text" />
<input type="text" />
</div>
I'm not entirely sure what you're trying to achieve but here are some pointers:
There is no such function as getElementByTagName, it should be getElementsByTagName
getElementsByTagName returns a HTMLCollection. To access an element in this list you could do document.getElementsByTagName('input')[0]. This would get the first input.
This does absolutely nothing: if (inputs == 0) { inputs = setInputs; }
Your Mistakes
1.getElementsByTagName is correct . getElementByTagName doesn't exist.
2.When you get a array of elements you have to loop them to process.
3.To insert a value into a input feild you have to use value not innerHTML
FIX:(Only appenItem function has issue)
PURE JS Version Example
Note:jQuery version is commented in this fiddle
function appendItem() {
var inputs = document.getElementsByTagName('input');
for (i = 0; i < inputs.length; i++) {
inputs[i].value = myRandomElement
}
}
jQuery Version
function appendItem() {
var inputs = document.getElementsByTagName('input');
$('input[type=text]').each(function (index, Obj) {
$(this).val(myRandomElement)
})
}