Count number of inputs and sum depending on its values - javascript

I would like to do two things:
I want to count the number of inputs that have a value. (doesn't matter if the value is A or X).
Then, count the number of inputs whose value is equal to A
therefore, the results should contain 6 of 14 items
This is what I tried to count the inputs that already have value:
var filledInputs = $(".col input").filter(function() {
return !!this.value;
}).length;
const test2 = document.querySelectorAll(".result");
test2.forEach((item) => {
item.innerHTML = filledInputs;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<div class="col">
<input type="text" value="A">
<input type="text" value="A">
<input type="text" value="X">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text" value="A">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text" value="X">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text">
<input type="text">
<input type="text">
</div>
<div class="results"></div>

One possible implementation with jQuery:
let any = 0;
let a = 0;
$(".col input").each((idx, item) => {
if (!item.getAttribute("value")) {
return;
}
if (item.getAttribute("value") == "A") {
a += 1;
}
any += 1;
});
$(".results").html(a + " of " + any + " items")
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col">
<input type="text" value="A">
<input type="text" value="A">
<input type="text" value="X">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text" value="A">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text" value="X">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text">
<input type="text">
<input type="text">
</div>
<div class="results">
6 of 14 items
</div>

Use the same logic that you made to find the filled inputs, to find the inputs with value A
const filledInputs = $(".col input").filter(function () {
return !!this.value;
}).length;
const inputWithValA = $(".col input").filter(function () {
return this.value === 'A';
}).length;
console.log(filledInputs)
console.log(inputWithValA)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<div class="col">
<input type="text" value="A" />
<input type="text" value="A" />
<input type="text" value="X" />
<input type="text" value="X" />
<input type="text" value="A" />
</div>
<div class="col">
<input type="text" value="A" />
<input type="text" value="X" />
<input type="text" value="A" />
</div>
<div class="col">
<input type="text" value="X" />
<input type="text" value="X" />
<input type="text" value="A" />
</div>
<div class="col">
<input type="text" />
<input type="text" />
<input type="text" />
</div>
<div class="results">6 of 14 items</div>

var $inputs = $(".col input").filter(function() {
return !!$(this).val();
});
var inputsFilled = $inputs.length
var inputsA =$inputs.filter(function() {
return $(this).val() == 'A';
}).length
console.log(inputsFilled)
console.log(inputsA)
$(".results").html(`${inputsA} of ${inputsFilled} are A`)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col">
<input type="text" value="A">
<input type="text" value="A">
<input type="text" value="X">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text" value="A">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text" value="X">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text">
<input type="text">
<input type="text">
</div>
<div class="results"></div>

Here's a minimal solution:
var AInputs = $(":input[value='A']").length;
console.log(AInputs);
Full snippet:
var filledInputs = $(".col input").filter(function() {
return !!this.value;
}).length;
console.log(filledInputs);
var AInputs = $(":input[value='A']").length;
console.log(AInputs);
const test2 = document.querySelectorAll(".result");
test2.forEach((item) => {
item.innerHTML = filledInputs;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col">
<input type="text" value="A">
<input type="text" value="A">
<input type="text" value="X">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text" value="A">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text" value="X">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text">
<input type="text">
<input type="text">
</div>
<div class="results"></div>

Don't mix DOM and jQuery like that
You are looping over one element
Perhaps you meant this:
const $breakdown = $("#breakdown");
const $results = $(".results")
let totalA = 0;
let totalNonEmptyInput = 0;
$(".col").each(function(i, ele) {
const $inputs = $(ele).find("input");
let As = 0;
const notEmpty = $inputs.filter(function() {
const val = this.value.trim();
if (val === "A") {
As++;
totalA++;
}
totalNonEmptyInput += val !== "";
return val !== ""
}).length;
$results.html(`${totalA} of ${totalNonEmptyInput}`)
$breakdown.append(`<li>${(i+1)}: ${notEmpty}/${$inputs.length} - found ${As} A</li>`)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col">
<input type="text" value="A">
<input type="text" value="A">
<input type="text" value="X">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text" value="A">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text" value="X">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text">
<input type="text">
<input type="text">
</div>
<div class="results"></div>
<ul id="breakdown"></ul>

const cols_ = document.querySelectorAll('.col');
let inputs_val_a = []; // matched input will stored here
cols_?.forEach(function(col,col_i){
col.querySelectorAll('input')?.forEach(function(ipt, ipt_i){
if( ipt.value == 'A' ){
// match
console.log('cols:'+col_i+' input:'+ipt_i+' have value "A"');
inputs_val_a.push(ipt);
}
})
});
document.querySelector('.results').innerHTML = 'there is '+ inputs_val_a.length + ' inputs with value == A';
<div class="results"></div>
<div class="col">
<input type="text" value="A">
<input type="text" value="A">
<input type="text" value="X">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text" value="A">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text" value="X">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text">
<input type="text">
<input type="text">
</div>

Maybe the easiest method (and marginally more performant than filtering) in vanilla JS is to do three selections: one on all inputs, and then two selections using the value attribute.
const inputs = document.querySelectorAll('input');
const inputsAll = document.querySelectorAll('[value]');
const inputsA = document.querySelectorAll('[value="A"]');
console.log(`${inputsAll.length} of ${inputs.length} items`);
console.log(`${inputsA.length} of ${inputs.length} items`);
<div class="col"> <input type="text" value="A"> <input type="text" value="A"> <input type="text" value="X"> <input type="text" value="X"> <input type="text" value="A"></div><div class="col"> <input type="text" value="A"> <input type="text" value="X"> <input type="text" value="A"></div><div class="col"> <input type="text" value="X"> <input type="text" value="X"> <input type="text" value="A"></div><div class="col"> <input type="text"> <input type="text"> <input type="text"></div><div class="results"></div>

If you want updated counts while you are filling in the fields you could recalculate it in an event driven function:
const inps=$(".col input").get();
$("body").on("input",".col input",upd8);
function upd8(){
[any,A]=inps.reduce((a,c)=> (c.value&&++a[0]&&c.value.toUpperCase()=="A"&&++a[1],a),[0,0]);
$(".results").html(A + " of " + any + " items")
};
upd8();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col">
<input type="text" value="A">
<input type="text" value="A">
<input type="text" value="X">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text" value="A">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text" value="X">
<input type="text" value="X">
<input type="text" value="A">
</div>
<div class="col">
<input type="text">
<input type="text">
<input type="text">
</div>
<div class="results">
6 of 14 items
</div>

Related

How to validate jquery validation together

I am working on javascript/jquery and i have following form and i want to validate
without "validation engine",So how can i validate all fields together ? I tried with following code
async function completeListing(elm)
{
var type= $("input[name='selct-type']:checked").val();
var quantity= $("#number").val();
var price= $("#priice").val();
if(type=="")
{
$("#radio_error").show();
}
if(price=="")
{
$("#price_error").show();
}
if(quantity=="")
{
$("#quantity_error").show();
}
else
{
//further code
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="radio_error" style="display:none";>Please select any field</div>
<div class="select-type">
<div class="radio">
<input type="radio" name="selct-type" value="sell"/><label>Sell </label>
</div>
<div class="radio">
<input type="radio" name="selct-type" value="auction"/><label>Auction </label>
</div>
</div>
<div id="price_error" style="display:none";>Please enter your price</div>
<input class="form-control" placeholder="Price" id="priice" name="price" type="number" />
<div id="quantity_error" style="display:none";>Please enter quantity</div>
<input class="form-control" id="number" placeholder="quanity" type="number" name="quantity"/>
<input type="submit" name="listing" value="Complete listing" onclick="completeListing(this)" >
You can use .prop('checked') to validate the radio input. It returns true if button is checked otherwise false.
async function completeListing(elm)
{
var type= $("input[name='selct-type']").prop('checked');
var quantity= $("#number").val();
var price= $("#priice").val();
if(type==false)
{
$("#radio_error").show();
}
if(price=="")
{
$("#price_error").show();
}
if(quantity=="")
{
$("#quantity_error").show();
}
else
{
//further code
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="radio_error" style="display:none";>Please select any field</div>
<div class="select-type">
<div class="radio">
<input type="radio" name="selct-type" value="sell"/><label>Sell </label>
</div>
<div class="radio">
<input type="radio" name="selct-type" value="auction"/><label>Auction </label>
</div>
</div>
<div id="price_error" style="display:none";>Please enter your price</div>
<input class="form-control" placeholder="Price" id="priice" name="price" type="number" />
<div id="quantity_error" style="display:none";>Please enter quantity</div>
<input class="form-control" id="number" placeholder="quanity" type="number" name="quantity"/>
<input type="submit" name="listing" value="Complete listing" onclick="completeListing(this)" >

get multiple form values as an array of object using a single click

I have multiple forms in a div. I would like to get the values of each form as an array of object in a single click.
<form data-category="1">
<div class="form-group">
<label for="usr">First Name:</label>
<input type="text" class="form-control" id="usr" name="username" />
</div>
<div class="form-group">
<label for="pwd">Last Name:</label>
<input type="text" class="form-control" id="pwd" name="lname" />
</div>
</form>
<form data-category="2">
<div class="form-group">
<label for="usr">Name:</label>
<input type="text" class="form-control" id="usr" name="username" />
</div>
<div class="form-group">
<label for="usr">Age:</label>
<input type="number" class="form-control" id="usr" name="age" />
</div>
<div>
<p>Gender></p>
<div class="form-check">
<label class="form-check-label">
<input
type="radio"
class="form-check-input"
name="optradio"
/>Male
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input
type="radio"
class="form-check-input"
name="optradio"
/>Female
</label>
</div>
</div>
</form>
<button type="submit" class="btn btn-primary">Submit</button>
I would like to get the result where exh object has a key called form whose value is the form number and the another key called inputdata which is an object whose keys represnt the input numbers and value are input values:
[{
form:1,
inputdata:{1:"John",2:"John Doe"}
},
{
form:2,
inputdata:{1:"Jane",2:25,3:"female"}
}]
You can probably do the following:
One other option can be to serialize the form data and then get the value of form, but this would work as well
const form = document.querySelectorAll('form');
function submitForm() {
const data = [];
for(let i=0; i<form.length; i++) {
const elements = form[i].elements;
data.push({form: form[i].getAttribute('data-category'), inputData: {}});
for(let j=0; j<elements.length; j++) {
if(elements[j].type !== 'radio') {
data[i].inputData[[elements[j].name]] = elements[j].value;
} else {
if(elements[j].checked) {
data[i].inputData[[elements[j].name]] = elements[j].value;
}
}
}
}
console.log(data);
}
<form data-category="1">
<div class="form-group">
<label for="usr">First Name:</label>
<input type="text" class="form-control" id="usr" name="firstName" />
</div>
<div class="form-group">
<label for="pwd">Last Name:</label>
<input type="text" class="form-control" id="pwd" name="lastName" />
</div>
</form>
<form data-category="2">
<div class="form-group">
<label for="usr">Name:</label>
<input type="text" class="form-control" id="usr" name="firstName" />
</div>
<div class="form-group">
<label for="usr">Age:</label>
<input type="number" class="form-control" id="usr" name="age" />
</div>
<div>
<p>Gender></p>
<div class="form-check">
<label class="form-check-label">
<input
type="radio"
class="form-check-input"
name="gender"
value="M"
/>Male
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input
type="radio"
class="form-check-input"
name="gender"
valeu="F"
/>Female
</label>
</div>
</div>
</form>
<button type="submit" class="btn btn-primary" onclick="submitForm()">Submit</button>
You may use FormData and Object.fromEntries to get the form data easily like below:
const btn = document.querySelector("#submit");
btn.addEventListener("click", () => {
const forms = document.querySelectorAll("form");
const output = [];
forms.forEach(form => {
output.push({
form: form.dataset.category,
inputData: Object.fromEntries(new FormData(form)),
});
});
console.log(output);
});
<!DOCTYPE html>
<html lang="en">
<head> </head>
<body>
<form data-category="1">
<div class="form-group">
<label for="usr">First Name:</label>
<input
type="text"
class="form-control"
id="usr"
name="username"
/>
</div>
<div class="form-group">
<label for="pwd">Last Name:</label>
<input type="text" class="form-control" id="pwd" name="lname" />
</div>
</form>
<form data-category="2">
<div class="form-group">
<label for="usr">Name:</label>
<input
type="text"
class="form-control"
id="usr"
name="username"
/>
</div>
<div class="form-group">
<label for="usr">Age:</label>
<input type="number" class="form-control" id="usr" name="age" />
</div>
<div>
<p>Gender</p>
<div class="form-check">
<label class="form-check-label">
<input
type="radio"
class="form-check-input"
name="gender"
value="1"
/>Male
</label>
</div>
<div class="form-check">
<label class="form-check-label">
<input
type="radio"
class="form-check-input"
name="gender"
value="0"
/>Female
</label>
</div>
</div>
</form>
<button id="submit" type="button" class="btn btn-primary">
Submit
</button>
</body>
</html>

Get the containers with inputs and their values

I need to get a DOM container (entire HTML code inside it), inside it has some input texts. When I save this DOM in the database the input values are not there.
I have tried:
$(".container").html()
$(".container").prop('outerHTML')
$(".container").text()
$(".container").get(0).outerHTML
Example:
As it is in the database now:
<div class="container stackExemple">
<input type="text" name="1">
<input type="text" name="2">
<input type="text" name="3">
<input type="text" name="4">
</div>
As i need it to be:
<div class="container stackExemple">
<input type="text" name="1" value="value1">
<input type="text" name="2" value="value2">
<input type="text" name="3" value="value3">
<input type="text" name="4" value="value4">
</div>
You should set the value attribute using .each() and .attr()
$(".container [type=text]").each(function(i){
$(this).attr('value', 'value'+(i+1));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container stackExemple">
<input type="text" name="1">
<input type="text" name="2">
<input type="text" name="3">
<input type="text" name="4">
</div>
How about writing the val() back as a value attribute on demand?
$('#test').on('click',function(){
var $container = $('.container');
$('input',$container).each(function(){
$(this).attr('value',$(this).val());
});
console.log($container.html());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container stackExemple">
<input type="text" name="1">
<input type="text" name="2">
<input type="text" name="3">
<input type="text" name="4">
</div>
<button id="test">Click for html</button>
Updating the html attribute value will update the value of the input, but updating the the value of the input, will not update the html attribute.
The trick is to update the value attribute of the elements before you read the html.
$("#print").on("click", function() {
$("#results").text(JSON.stringify(getContainer(), (key, value) => (!key || !isNaN(key)) ? value : undefined, 4).replace(/\\n/g, "\n").replace(/\\"/g, "'"));
});
function getContainer() {
return $(".container").map(function() {
$("input", this).each(function() {
this.setAttribute("value", this.value);
});
return this.outerHTML;
});
}
#results {
display: block;
white-space: pre;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container stackExemple">
<input type="text" name="1">
<input type="text" name="2">
<input type="text" name="3">
<input type="text" name="4">
</div>
<div class="container stackExemple">
<input type="text" name="5">
<input type="text" name="6">
<input type="text" name="7">
<input type="text" name="8">
</div>
<button id="print">Print</button>
<code id="results"></code>

reset form not working

function resetForm() {
document.getElementById('myForm').reset();
}
<div id="myForm">
<label class="form ">First name:</label><br/>
<input type="text" id="Fname" name="first name"></input><span id="first"></span><br>
<label class="form ">last name:</label><br>
<input type="text" id="Lname" name="last name"></input><span id="last"></span><br>enter code here
<label class="form"> address:</label><br>
<input type="text" id="Address" name="address name"></input> <span id="add"></span><br>
<label class="form"> email:</label><br>
<input type="text" id="Email" name="email name"></input> <span id="ema"></span><br>
<label class="form"> gender:</label><br>
<input type="radio" class="Gend" id="Male" value="male" name="Gender"><b><i>Male</i></b></input>
<input type="radio" class="Gend" id="Female" value="female" name="Gender"><b><i>Female</i></b></input><span id="Ge"></span><br>
<label class="form">Phone number:</label><br>
<input type="text" id="Phone" name="phone"></input><span id="ph"></span><br><br>
<input type="button" class="button " value="Submit" onclick="myFun()"></input>
<input type="button" class="button " name="Save" value="Save" onclick="savedRow()" /><br>
<input type="reset" class="button" name="Reset" value="reset" onclick="resetForm()" />
</div>
I think you need a form
not a
div
just look this example:
https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_form_reset
The element you're targetting needs to be a <form> tag :
function resetForm() {
document.getElementById('myForm').reset();
}
<form id="myForm">
<label class="form ">First name:</label><br/>
<input type="text" id="Fname" name="first name"></input><span id="first"></span><br>
<label class="form ">last name:</label><br>
<input type="text" id="Lname" name="last name"></input><span id="last"></span><br>enter code here
<label class="form"> address:</label><br>
<input type="text" id="Address" name="address name"></input> <span id="add"></span><br>
<label class="form"> email:</label><br>
<input type="text" id="Email" name="email name"></input> <span id="ema"></span><br>
<label class="form"> gender:</label><br>
<input type="radio" class="Gend" id="Male" value="male" name="Gender"><b><i>Male</i></b></input>
<input type="radio" class="Gend" id="Female" value="female" name="Gender"><b><i>Female</i></b></input><span id="Ge"></span><br>
<label class="form">Phone number:</label><br>
<input type="text" id="Phone" name="phone"></input><span id="ph"></span><br><br>
<input type="button" class="button " value="Submit" onclick="myFun()"></input>
<input type="button" class="button " name="Save" value="Save" onclick="savedRow()" /><br>
<input type="reset" class="button" name="Reset" value="reset" onclick="resetForm()" />
</form>
You are using div instead of form. Just updated the first tag of your html code and voila it will start working.
Hope this solves your query.
function resetForm() {
document.getElementById('myForm').reset();
}
<form id="myForm">
<label class="form ">First name:</label><br/>
<input type="text" id="Fname" name="first name"></input><span id="first"></span><br>
<label class="form ">last name:</label><br>
<input type="text" id="Lname" name="last name"></input><span id="last"></span><br>enter code here
<label class="form"> address:</label><br>
<input type="text" id="Address" name="address name"></input> <span id="add"></span><br>
<label class="form"> email:</label><br>
<input type="text" id="Email" name="email name"></input> <span id="ema"></span><br>
<label class="form"> gender:</label><br>
<input type="radio" class="Gend" id="Male" value="male" name="Gender"><b><i>Male</i></b></input>
<input type="radio" class="Gend" id="Female" value="female" name="Gender"><b><i>Female</i></b></input><span id="Ge"></span><br>
<label class="form">Phone number:</label><br>
<input type="text" id="Phone" name="phone"></input><span id="ph"></span><br><br>
<input type="button" class="button " value="Submit" onclick="myFun()"></input>
<input type="button" class="button " name="Save" value="Save" onclick="savedRow()" /><br>
<input type="reset" class="button" name="Reset" value="reset" onclick="resetForm()" />
</form>

JQuery: Combine sets of field names and values into an object and then push into an array

I have a form with three sets of fields.
Like this:
<form>
<div class="food">
<input type="text" name="" value="" />
<input type="text" name="" value="" />
<textarea name="" value=""></textarea>
</div>
<div class="drinks">
<input type="text" name="" value="" />
<input type="text" name="" value="" />
<textarea name="" value=""></textarea>
</div>
<div class="gifts">
<input type="text" name="" value="" />
<input type="text" name="" value="" />
<textarea name="" value=""></textarea>
</div>
</form>
How do I combine field names and values in each div into their own json object, push the objects into an array, and then add the array to a hidden input field before submission?
You can use map() and get() to create array and inside you can return object for each div.
var data = $('form > div').map(function() {
var obj = {}
$(this).find('input, textarea').each(function() {
obj[$(this).attr('name')] = $(this).attr('value');
})
return obj;
}).get()
console.log(data)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<div class="food">
<input type="text" name="a" value="1" />
<input type="text" name="b" value="11" />
<textarea name="c" value="111"></textarea>
</div>
<div class="drinks">
<input type="text" name="a" value="2" />
<input type="text" name="b" value="22" />
<textarea name="c" value="222"></textarea>
</div>
<div class="gifts">
<input type="text" name="a" value="3" />
<input type="text" name="b" value="33" />
<textarea name="c" value="333"></textarea>
</div>
</form>

Categories