I have this function:
calculatetabel1 = function(){
a1 = document.getElementById('pnpa1').value;
a2 = document.getElementById('pnpa2').value;
a3 = document.getElementById('pnpa3').value;
a4 = document.getElementById('pnpa4').value;
a5 = document.getElementById('pnpa5').value;
document.getElementById('totalpnp1').value =parseInt(a1)+parseInt(a2)+parseInt(a3)+parseInt(a4)+parseInt(a5);
}
This function works perfectly using onkeyup="calculatetabel1()".
Let's say I have 20 columns and rows. How do I call this function without filling 20 columns and rows? (only 1 column will do)
I already tried document.addEventListener("DOMContentLoaded", function(event) { calculatetabel1(); This does not work as I expected.
If you want to trigger this function whenever any of the fields have changed, without needing to attach an onkeyup to each one, you could do something like this:
const form = document.getElementById("pnpForm");
form.addEventListener("input", function() {
let values = [];
const inputs = form.getElementsByTagName("input");
[...inputs].forEach(input => {
if (input.value && input.value !== '' && !input.readOnly) {
values.push(input.value);
}
});
form.querySelectorAll('[readonly]')[0].value = values.reduce((a, b) => parseInt(a) + parseInt(b), 0);
});
<form id="pnpForm">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text" readonly>
</form>
This can be further generalized to support multiple tables without any extra logic:
const forms = document.getElementsByTagName("form");
[...forms].forEach(form => {
form.addEventListener("input", function() {
let values = [];
const inputs = form.getElementsByTagName("input");
[...inputs].forEach(input => {
if (input.value && input.value !== '' && !input.readOnly) {
values.push(input.value);
}
});
form.querySelectorAll('[readonly]')[0].value = values.reduce((a, b) => parseInt(a) + parseInt(b), 0);
});
});
<h3>Table 1</h3>
<form id="table1">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text" readonly>
</form>
<h3>Table 2</h3>
<form id="table2">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text" readonly>
</form>
Maybe this code seemingly works the same as the one you delivered above:
calculatetabel1 = function() {
// got an array of document.getElementById('pnpa ... ').value
const arr = Array.from({ length: 5 }).map( (_, i) => {
const idToGet = `pnpa${i+1}`;
return document.getElementById(idToGet).value;
});
// calculate total
const total = arr.reduce( (a, b) => {
return parseInt(a) + parseInt(b);
}, 0);
// assign to #totalpnp1
document.getElementById('totalpnp1').value = total;
}
Related
I created a small website where I would like to add/remove input fields dynamically. I already wrote the code to add them and it works perfect but removing the input fields is a bit of a challenge.
Below is what my document looks like after creating the inputs. Now with the "remove button" I tried to remove the last BR and the 3 inputs fields above, but whatever I try I always remove the last 3 buttons, which is ok, and both brs above and beneath the three inputs.
var total_inputs = 9;
var place_br_before = false;
function remove_inputs() {
if (total_inputs != 0) {
place_br_before = true;
for (var j = 0; j < 3; j++) {
var del = document.getElementById(("input_" + total_inputs));
del.remove();
total_inputs--;
}
$('#inputs br:last-child').remove();
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<button type="button" onclick="add_inputs()">+</button>
<button type="button" onclick="remove_inputs()">-</button>
<form id="inputs">
<input type="text" id="input_1">
<input type="text" id="input_2">
<input type="text" id="input_3">
<br>
<input type="text" id="input_4">
<input type="text" id="input_5">
<input type="text" id="input_6">
<br>
<input type="text" id="input_7">
<input type="text" id="input_8">
<input type="text" id="input_9">
<br>
</form>
I would probably simplify and abstract out the ID requirement by grouping rather than using line breaks.
function remove_inputs() {
inputGroups = document.getElementsByClassName('input-group');
inputGroups[inputGroups.length - 1].remove();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<button type="button" onclick="add_inputs()" disabled>+</button>
<button type="button" onclick="remove_inputs()">-</button>
<form id="inputs">
<div class="input-group">
<input type="text">
<input type="text">
<input type="text">
</div>
<div class="input-group">
<input type="text">
<input type="text">
<input type="text">
</div>
<div class="input-group">
<input type="text">
<input type="text">
<input type="text">
</div>
</form>
I need to write a javascript function that will loop through the input boxes and concatenates the text in each field together and displays the result in the result box. I tried multiple solutions and haven't been able to get any to work, I get that it needs an array of text fields but I can't seem to work it out.
<!DOCTYPE html>
<html>
<body>
<form id="myform">
<label for="text1">text1</label><br>
<input type="text" id="text1" name="text1"><br>
<label for="text2">text2</label><br>
<input type="text" id="text2" name="text2"><br>
<label for="text3">text3</label><br>
<input type="text" id="text3" name="text3"><br>
<label for="text4">text4</label><br>
<input type="text" id="text4" name="text4"><br>
<label for="text5">text5</label><br>
<input type="text" id="text5" name="text5"><br>
<label for="text6">text6</label><br>
<input type="text" id="text6" name="text6"><br>
<input type="button" onClick="myFunction()" value="Click This"><br>
<label for="result">result</label><br>
<input type="text" id="result" name="result">
</form>
<script>
function myFunction() {
var fields = [];
}
</script>
</body>
</html>
You can use filter and map
NOTE: I gave the button an ID of "btn"
document.getElementById('btn').addEventListener('click', function() {
const conc = [...document.querySelectorAll('#myform [id^=text]')] // id starts with text
.filter(fld => fld.value.trim() !== "") // not empty
.map(fld => fld.value) // store value
document.getElementById('result').value = conc.join(","); // join with comma
})
<form id="myform">
<label for="text1">text1</label><br>
<input type="text" id="text1" name="text1"><br>
<label for="text2">text2</label><br>
<input type="text" id="text2" name="text2"><br>
<label for="text3">text3</label><br>
<input type="text" id="text3" name="text3"><br>
<label for="text4">text4</label><br>
<input type="text" id="text4" name="text4"><br>
<label for="text5">text5</label><br>
<input type="text" id="text5" name="text5"><br>
<label for="text6">text6</label><br>
<input type="text" id="text6" name="text6"><br>
<input type="button" id="btn" value="Click This"><br>
<label for="result">result</label><br>
<input type="text" id="result" name="result">
</form>
In one pass:
document.getElementById('btn').addEventListener('click', function() {
const res = [];
[...document.querySelectorAll('#myform [id^=text]')]
.forEach(fld => { const val = fld.value.trim(); if (val !== "") res.push(val) })
document.getElementById('result').value = res.join(","); // join with comma
})
<form id="myform">
<label for="text1">text1</label><br>
<input type="text" id="text1" name="text1"><br>
<label for="text2">text2</label><br>
<input type="text" id="text2" name="text2"><br>
<label for="text3">text3</label><br>
<input type="text" id="text3" name="text3"><br>
<label for="text4">text4</label><br>
<input type="text" id="text4" name="text4"><br>
<label for="text5">text5</label><br>
<input type="text" id="text5" name="text5"><br>
<label for="text6">text6</label><br>
<input type="text" id="text6" name="text6"><br>
<input type="button" id="btn" value="Click This"><br>
<label for="result">result</label><br>
<input type="text" id="result" name="result">
</form>
function myFunction() {
const data = document.querySelectorAll("#myform input[type='text'][id^=text]");
//console.log(data);
var fields = [];
data.forEach(item => {
if (item.value != '') {
fields.push(item.value)
}
})
document.getElementById("result").value = fields.join(",")
}
<form id="myform">
<label for="text1">text1</label><br>
<input type="text" id="text1" name="text1"><br>
<label for="text2">text2</label><br>
<input type="text" id="text2" name="text2"><br>
<label for="text3">text3</label><br>
<input type="text" id="text3" name="text3"><br>
<label for="text4">text4</label><br>
<input type="text" id="text4" name="text4"><br>
<label for="text5">text5</label><br>
<input type="text" id="text5" name="text5"><br>
<label for="text6">text6</label><br>
<input type="text" id="text6" name="text6"><br>
<input type="button" onClick="myFunction()" value="Click This"><br>
<label for="result">result</label><br>
<input type="text" id="result" name="result">
</form>
I have 6 input fields in my html page like so:
<div class='inputBox'>
<form action="/" method="post">
<div>
<label>Angle of A = </label>
<input class='field' autocomplete="off" autofocus name="A" type="number">
</div>
<div>
<label>Angle of B = </label>
<input class='field' autocomplete="off" autofocus name="B" type="text">
</div>
<div>
<label>Angle of C = </label>
<input class='field' autocomplete="off" autofocus name="C" type="text">
</div>
<div>
<label>Side Length of a = </label>
<input class='field' autocomplete="off" autofocus name="a" type="text">
</div>
<div>
<label>Side Length of b = </label>
<input class='field' autocomplete="off" autofocus name="b" type="text">
</div>
<div>
<label>Side Length of c = </label>
<input class='field' autocomplete="off" autofocus name="c" type="text">
</div>
<div>
<button id='calculate' disabled="true" class='field' type="submit">Calculate</button>
</div>
</form>
</div>
I would like the button to be disabled until any 3 out of the 6 fields have a value. Here is my javascript code:
function enableButton()
{
var filled = 0;
var fields = [...document.getElementsByClassName("field")];
for (var i = 0; i < 6; i++)
{
if (fields[i].length() > 0)
{
filled += 1;
}
}
if (filled >= 3)
{
document.getElementById("calculate").disabled = false;
}
else
{
document.getElementById("calculate").disabled = true;
}
}
Unfortunately the button stays disabled despite the number of fields that have a value.
Try using a change event to the input fields, I have used onkeyup function to invoke the enableButton function. Instead of checking fields[i].length() try to check whether fields[i].value exist or not. Here is a working sample.
function enableButton() {
var filled = 0;
var fields = [...document.getElementsByClassName("field")];
for (var i = 0; i < 6; i++) {
if (fields[i].value) {
filled += 1;
}
}
if (filled >= 3) {
document.getElementById("calculate").disabled = false;
} else {
document.getElementById("calculate").disabled = true;
}
}
<div class='inputBox'>
<form action="/" method="post">
<div>
<label>Angle of A = </label>
<input class='field' autocomplete="off" autofocus name="A" type="number" onkeyup="enableButton()">
</div>
<div>
<label>Angle of B = </label>
<input class='field' autocomplete="off" autofocus name="B" type="text" onkeyup="enableButton()">
</div>
<div>
<label>Angle of C = </label>
<input class='field' autocomplete="off" autofocus name="C" type="text" onkeyup="enableButton()">
</div>
<div>
<label>Side Length of a = </label>
<input class='field' autocomplete="off" autofocus name="a" type="text" onkeyup="enableButton()">
</div>
<div>
<label>Side Length of b = </label>
<input class='field' autocomplete="off" autofocus name="b" type="text" onkeyup="enableButton()">
</div>
<div>
<label>Side Length of c = </label>
<input class='field' autocomplete="off" autofocus name="c" type="text" onkeyup="enableButton()">
</div>
<div>
<button id='calculate' disabled="true" class='field' type="submit">Calculate</button>
</div>
</form>
</div>
that ?
I just added an id on the form element, and transformed the Id attribute of the button into name, so that I only have the for to declare as const
and also remove all unnecessary divs in the form, light code is always easier to read
const myForm = document.getElementById('my-form')
, inFields = [...myForm.querySelectorAll('input.field')]
;
myForm.oninput=()=>
{
let count = inFields.reduce((a,c)=>a+=(c.value.trim().length >0)?1:0,0)
myForm.calculate.disabled = (count <3)
}
myForm.onreset=()=>
{
myForm.calculate.disabled = true
}
label, input, button { display: block; float: left; margin: .3em; }
label, button:first-of-type { clear: both; }
label { width: 10em; line-height: 2.3em; text-align: right; }
<form action="/" method="post" id="my-form">
<label>Angle of A = </label>
<input class='field' autocomplete="off" autofocus name="A" type="number">
<label>Angle of B = </label>
<input class='field' autocomplete="off" autofocus name="B" type="text">
<label>Angle of C = </label>
<input class='field' autocomplete="off" autofocus name="C" type="text">
<label>Side Length of a = </label>
<input class='field' autocomplete="off" autofocus name="a" type="text">
<label>Side Length of b = </label>
<input class='field' autocomplete="off" autofocus name="b" type="text">
<label>Side Length of c = </label>
<input class='field' autocomplete="off" autofocus name="c" type="text">
<button type="reset">reset</button>
<button name='calculate' disabled="true" class='field' type="submit">Calculate</button>
</form>
You might've had a few problems with that function, but the main problem is that you never call the enableButton function. The code below calls it whenever one of the fields are changed.
function enableButton() {
let filled = 0;
let fields = document.getElementsByClassName("field");
for (let i = 0; i < fields.length; i++) {
if (fields[i].value != "") {
filled++;
}
}
if (filled > 2) {
document.getElementById("calculate").removeAttribute("disabled");
} else {
document.getElementById("calculate").setAttribute("disabled", "");
}
}
<div class='inputBox'>
<form action="/" method="post">
<div>
<label>Angle of A = </label>
<input class='field' autocomplete="off" autofocus name="A" type="number" onchange="enableButton()">
</div>
<div>
<label>Angle of B = </label>
<input class='field' autocomplete="off" autofocus name="B" type="text" onchange="enableButton()">
</div>
<div>
<label>Angle of C = </label>
<input class='field' autocomplete="off" autofocus name="C" type="text" onchange="enableButton()">
</div>
<div>
<label>Side Length of a = </label>
<input class='field' autocomplete="off" autofocus name="a" type="text" onchange="enableButton()">
</div>
<div>
<label>Side Length of b = </label>
<input class='field' autocomplete="off" autofocus name="b" type="text" onchange="enableButton()">
</div>
<div>
<label>Side Length of c = </label>
<input class='field' autocomplete="off" autofocus name="c" type="text" onchange="enableButton()">
</div>
<div>
<button id='calculate' type="submit" disabled>Calculate</button>
</div>
</form>
</div>
How did you call the function , also put a console log to check if the function is getting called. also as #certainPerformance told .length is a property not an function
Hello I want to count the first [] of input name
<input type="text" name="Hello[a][]">
<input type="text" name="Hello[a][]">
<input type="text" name="Hello[a][]">
<input type="text" name="Hello[b][]">
<input type="text" name="Hello[b][]">
<input type="text" name="Hello[c][]">
<input type="text" name="Hello[c][]">
<input type="text" name="Hello[c][]">
<input type="text" name="Hello[c][]">
the result of count should be 3 (a, b ,c)
How could I do with jquery or javascript?
Iterate over the input elements and use an object for referring repetition, when new name occurred increment a counter.
var ref = {},
count = 0;
$('input').each(function() {
if (!(this.name in ref)) {
ref[this.name] = true;
count++
}
})
console.log(count);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" name="Hello[a][]">
<input type="text" name="Hello[a][]">
<input type="text" name="Hello[a][]">
<input type="text" name="Hello[b][]">
<input type="text" name="Hello[b][]">
<input type="text" name="Hello[c][]">
<input type="text" name="Hello[c][]">
<input type="text" name="Hello[c][]">
<input type="text" name="Hello[c][]">
I have few textboxes and data-attrribute for installment number.
<input type="text" id="54" data-instno="12"/>
<input type="text" id="124" data-instno="13"/>
<input type="text" id="88" data-instno="14"/>
<input type="text" id="126" data-instno="15"/>
<input type="text" id="102" data-instno="16"/>
<input type="text" id="8" data-instno="17"/>
<input type="text" id="87" data-instno="18"/>
<input type="text" id="112" data-instno="19"/>
If my installment number is 15. i want to get controls have data-instno>=15. that means last 5 textboxes in this case.
Use jQuery Has Attribute Selector [name] to selecting target elements and use .filter() to filtering element has data-instno great than 15.
$("[data-instno]").filter(function(){
return $(this).attr("data-instno") >= 15;
}).doSomething();
$("[data-instno]").filter(function(){
return $(this).attr("data-instno") >= 15;
}).css("background", "red");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="54" data-instno="12"/>
<input type="text" id="124" data-instno="13"/>
<input type="text" id="88" data-instno="14"/>
<input type="text" id="126" data-instno="15"/>
<input type="text" id="102" data-instno="16"/>
<input type="text" id="8" data-instno="17"/>
<input type="text" id="87" data-instno="18"/>
<input type="text" id="112" data-instno="19"/>
If you want to get value of data-instno use this
var arr = $("[data-instno]").map(function(){
return $(this).attr("data-instno");
}).get().filter(function(value){
return value >= 15;
});
var arr = $("[data-instno]").map(function(){
return $(this).attr("data-instno");
}).get().filter(function(value){
return value >= 15;
});
console.log(arr);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="54" data-instno="12"/>
<input type="text" id="124" data-instno="13"/>
<input type="text" id="88" data-instno="14"/>
<input type="text" id="126" data-instno="15"/>
<input type="text" id="102" data-instno="16"/>
<input type="text" id="8" data-instno="17"/>
<input type="text" id="87" data-instno="18"/>
<input type="text" id="112" data-instno="19"/>
Just plain JavaScript:
console.log(
[].filter.call(document.getElementsByTagName('INPUT'),
function(elem) {
return elem.dataset.instno >= 15;
})
);
<input type="text" id="54" data-instno="12"/>
<input type="text" id="124" data-instno="13"/>
<input type="text" id="88" data-instno="14"/>
<input type="text" id="126" data-instno="15"/>
<input type="text" id="102" data-instno="16"/>
<input type="text" id="8" data-instno="17"/>
<input type="text" id="87" data-instno="18"/>
<input type="text" id="112" data-instno="19"/>
var arrNumber = new Array();
$('input[type=text]').each(function(){
if($(this).attr('data-instno') >= 15){
arrNumber.push($(this).attr('data-instno'));
}
});
use this you will get this as an array