How to call function JS for selected row only in table? - javascript

I'm trying to increment Quantity for second row only but the first row that increment and not the second ?!
this is my code Html of my table :
<table class="table">
<thead>
<tr>
<th class="">Item Name</th>
<th class="">Item Price</th>
<th class="">Quantité</th>
<th class="">Actions</th>
</tr>
</thead>
#foreach(var item in #Model.panierWebs) {
<tbody>
<tr class="">
<td class="">
<div class="product-info">
<img width="80" src="#Url.Content(item.Image)" alt="" />
#Html.DisplayFor(modelItem => item.Model)
</div>
</td>
<td class=""> #Html.DisplayFor(modelItem => item.Prix) DA</td>
<td class="">
<div class="quantity buttons_added">
<input onclick="decrement(#item.Prix,#item.Qte)" type="button" value="-" class="minus"><input type="number" name="quantity" id="qte" value="#item.Qte" title="Qty" class="input-text qty text" pattern="" inputmode=""><input onclick="increment(#item.Prix,#item.Qte)"
type="button" value="+" class="plus">
</div>
</td>
<td class="">
<a onclick="remove(#item.Id)" class="product-remove" href="#!">Remove</a>
</td>
</tr>
</tbody>
}
</table>
and my Script JS of increment and decrement Qte :
function decrement(prix, qte) {
console.log("qte avant dec" + document.getElementById("qte").value);
if (parseInt(document.getElementById("qte").value) != 1) {
qte = parseInt(document.getElementById("qte").value) - 1; // increment qte
console.log("qte apres dec" + qte);
$("#qte").val(qte); // affecter la nouvelle valeur de qte
var currenttotal = document.getElementById("total").value; // calculer le nouveau total
var newtotal = parseFloat(currenttotal) - parseFloat(prix);
$("#total").val(newtotal);
}
}
function increment(prix, qte) {
console.log("qte avant incr" + document.getElementById("qte").value);
if (parseInt(document.getElementById("qte").value) <= 5) {
qte = parseInt(document.getElementById("qte").value) + 1; // increment qte
console.log("qte apres incr" + qte);
$("#qte").val(qte); // affecter la nouvelle valeur de qte
var currenttotal = document.getElementById("total").value; // calculer le nouveau total
var newtotal = parseFloat(currenttotal) + parseFloat(prix);
$("#total").val(newtotal);
}
}

First, fix some problems:
You must avoid use duplicated identifiers in the DOM. You can use a class and work with classes instead of ids.
Also, you have tbody inside your foreach, making your table has lots of tbodys. You must put tbody tag outside the foreach
On approach to solve the problem is work with the concrete tag in which you call to your functions (the + and - buttons). To do that, add a parameter "this" to your functions. "this" is the input button in which you do the click
<input onclick="decrement(this,#item.Prix,#item.Qte)" ...>
<input type="number" ...>
<input onclick="increment(this,#item.Prix,#item.Qte)" ...>
And modify a bit your functions:
function increment(input, prix, qte) {
var number = $(input).closest("div").find("input[type=number]")
var inputVal = parseInt(number.val());
if (inputVal <= 5) {
qte = inputVal + 1; // increment qte
console.log("qte apres incr" + qte);
number.val(qte); // affecter la nouvelle valeur de qte
// ... your total part
}
}
The $(input).closest("div") give you the div that contains your buttons and the textbox. In that div, you search an input of type=number (the textbox), get it's value and do the job

Related

Problem disable fields of a select in html with JS

I try to disable a field when an option is chosen in a select. I have created a script with a function in JS to disable it, more however it does not work. Any ideas what to do? When I select "T in% compared to the previous day", I need the "Time /%" field to be disabled, which I have not achieved.
So the code I have implemented for the select is this
Here I create the selectable menu with the fields that they will have and then through a script I pass it to fill the fields and I also create the function to disable the "Hours" boxes. So, here the problem arises, inside the script when const select = document.querySelector (# 'TipoPatron2') is started The table disappears, more however when the query selector is commented the table is still there
<table border="0">
<body>
<td><strong>Patrón 2</strong>(
<select name="TipoPatron2" id="TipoPatron2">
<option value="00">T desde el encendido</option>
<option value="01" selected="selected">T desde las 12:00</option>
<option value="10">T en % respecto día anterior</option>
</select>)</td>
<td><input type="button" onclick="changeP2();" value="Actualizar"> <label id="Error2" style="color: red"></label>
</td>
</tr>
<tr>
<td>
<table>
<thead>
<tr color="#ccff00">
<td>Cambio</td>
<td>Hora/%</td>
<td>Minutos</td>
<td>Dimado</td>
<td>Dimado Entrada</td>
<td>Color</td>
</tr>
</thead>
<tbody id="mytbody2">
</tbody>
<script language="javascript">
let tbody2 = document.querySelector("#mytbody2");
var I = 1;
for (I = 1; I <= 8; I++) {
document.writeln("<tr align=center>");
document.writeln("<td>" + I + " <input type=\"checkbox\" checked id=\"AP2C" + I + "\"></td>");
document.writeln("<td><input type=\"text\" onpaste = \"alerta()\" value=\"0\" id=\"HP2C" + I + "\" maxlength=3 size=3></td>");
document.writeln("<td><input type=\"text\" value=\"0\" id=\"MP2C" + I + "\" maxlength=2 size=2></td>");
document.writeln("<td><select name=\"dimado\" id=\"DP2C" + I + "\"><option value =\"0\">0%</option><option value =\"1\">1%</option><option value =\"2\">2%</option><option value =\"3\">3%</option><option value =\"4\">4%</option><option value =\"5\">5%</option><option value =\"6\">6%</option><option value =\"7\">7%</option><option value =\"8\">8%</option><option value =\"9\">9%</option><option value=\"10\">10%</option><option value=\"11\">11%</option><option value=\"12\">12%</option><option value=\"13\">13%</option><option value=\"14\">14%</option><option value = \"15\">15%</option><option value=\"16\">16%</option><option value=\"17\">17%</option><option value=\"18\">18%</option><option value=\"19\">19%</option><option value = \"20\">20%</option><option value=\"21\">21%</option><option value=\"10\">10%</option><option value = \"22\">22%</option><option value = \"23\">23%</option><option value = \"24\">24%</option><option value = \"25\">25%</option><option value = \"26\">26%</option><option value = \"27\">27%</option><option value = \"28\">28%</option><option value = \"29\">29%</option><option value = \"30\">30%</option><option value = \"31\">100%</option></select></td>");
document.writeln("<td><input type=\"text\" value=\"0\" id=\"IP2C" + I + "\" maxlength=2 size=2></td>");
document.writeln("<td><input type=\"text\" value=\"0\" id=\"CP2C" + I + "\" maxlength=2 size=2></td>");
document.writeln("</tr>");
}
//Creo una selector para que valide si se selecciona la opción de "T%" se ejecute la función desactivar
/*const select = document.querySelector('#TipoPatron2')
select.onchange = () => {
if (select.value == '10') {
desact()
}
}
*/
//Se crea la función alerta para cuando se haga un pegado en los box se ejecute la alerta
function alerta() {
alert("Seguro que quieres actualizar?");
}
//Se crea una función desactivar que se efectua en un for de 0 a 8 con el ID de las horas
function desact() {
for (let i = 1; i <= 8; i++)
document.getElementById('HP2C' + i).setAttribute("disabled", "disabled");
}
</script>
<tr align="center">
</tbody>
</table>
</body>
</td>
Photos when when queryselector is not commented
Now, I go to the page and the table disappears enter image description here
And if I comment the const select = document.querySelector ('# TipoPatron2') the table appears enter image description here
I need this query selector, since this is in charge of disabling the "Hora/%" when "T en % respecto día anterior" is selected in the first select. Any ideas what to do pls?
Have a look at this
I made the creation of the select simpler
I assume you mean to disable the HP2Cs when TipoPatron2 have value "10"
const tbody2 = document.getElementById("mytbody2");
tbody2.innerHTML = Array.from({length: 8}, (_, index) => index + 1).map(i => `<tr align=center>
<td>${i}<input type="checkbox" checked id="AP2C${i}" /></td>
<td><input type="text" value="0" id="HP2C${i}" maxlength=3 size=3 /></td>
<td><input type="text" value="0" id="MP2C${i}" maxlength=2 size=2 /></td>
<td><select name="dimado" id="DP2C ${i}">${Array.from({length: 29}, (_, index) => index + 1).map(i => `<option value="${i}">${i}%</option>`).join("") }
<option value = "31">100%</option></select></td>
<input type="text" value="0" id="IP2C${i}" maxlength=2 size=2 /></td>
<td><input type="text" value="0" id="CP2C${i}" maxlength=2 size=2 /></td>
</tr>`).join("")
const HP2Cs = document.querySelectorAll("[id^=HP2C]")
document.getElementById("TipoPatron2").addEventListener("change", function() {
const dis = this.value==="10";
HP2Cs.forEach(hp2c => hp2c.disabled = dis)
})
tbody2.addEventListener("paste", e => {
const tgt = e.target;
if (tgt.id.startsWith("HP2C")) alert("Seguro que quieres actualizar?");
})
<table border="0">
<tbody>
<tr>
<td><strong>Patrón 2</strong>(
<select name="TipoPatron2" id="TipoPatron2">
<option value="00">T desde el encendido</option>
<option value="01" selected="selected">T desde las 12:00</option>
<option value="10">T en % respecto día anterior</option>
</select>)</td>
<td><input type="button" onclick="changeP2();" value="Actualizar"> <label id="Error2" style="color: red"></label></td>
</tr>
<tr>
<td>
<table>
<thead>
<tr color="#ccff00">
<td>Cambio</td>
<td>Hora/%</td>
<td>Minutos</td>
<td>Dimado</td>
<td>Dimado Entrada</td>
<td>Color</td>
</tr>
</thead>
<tbody id="mytbody2">
</tbody>
</table>
</td>
</tr>
</tbody>
</table>

How can I validate dynamically added dependent calendar fields

I've a form on my website where I'm getting multiple event details from my customers. They can share event details and event date.
I want to let them able to add multiple events with details but dynamically. Currently I wrote JavaScript for this and it's working fine.
Now, what I want is each time the value for next date should be grater than the previous one. So If they added 2 events suppose, the date for the second event should be based on date for first event and should be greater and same is true for upcoming dates.
How can I do that?
var tableCount = 1;
var index = 1;
$(document).on('click', 'button.add_time', function(e) {
e.preventDefault();
tableCount++;
$('#timeTable').clone().attr('id', "timeTable" + tableCount).appendTo('#table');
$('#timeTable' + tableCount).find("input").val("");
index++;
$('#timeTable' + tableCount + ' .aa').html(tableCount);
});
$(document).on('click', 'button.removeTime', function() {
var closestTable = $(this).closest('table');
if (closestTable.attr('id') != "timeTable") {
closestTable.remove();
}
tableCount--;
if (tableCount < 1) {
tableCount = 1;
}
return false;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="table" class="form-group">
<table id="timeTable" class="tg">
<tr class="form-group">
<td class="aa">1</td>
<td class="tg-yw4">
<button class="btn form-control btn-danger removeTime">Remove Events</button>
</td>
<td class="col-sm-4">
<input placeholder="Event Date" name="events[]" class="input-lg" type="text" onfocus="(this.type='date')">
</td>
</tr>
<tr>
<td class="aa">1</td>
<td class="tg-yw4">Event Description:</td>
<td>
​<input name="event_descriptions[]" type="text" placeholder="Event description:" />
</td>
</tr>
</table>
</div>
<div class="my-5">
<button class="add_time btn btn-info">Add More Events</button>
</div>
Whenever user inputs the date in input box you can check if the date which he/she has enter is less then previous date by looping through all previous dates inputs using each loop and depending on this show some error message.
Demo Code :
var tableCount = 1;
var index = 1;
//on input of date
$(document).on('input', 'input[name*=events]', function(e) {
//get that date
var edate = new Date($(this).val());
var $this = $(this).siblings("span.error");
$this.text("")//empty previous error if any
//loop through dates inputs
$("input[name*=events]").each(function() {
if ($(this).val() != null) {
//get input value
var sdate = new Date($(this).val())
//check user input is less then previous date
if (edate < sdate) {
console.log("date is less then previous date");
$this.text("date is less then previous date")//show eror
}
}
})
});
$(document).on('click', 'button.add_time', function(e) {
e.preventDefault();
tableCount++;
$('#timeTable').clone().attr('id', "timeTable" + tableCount).appendTo('#table');
$('#timeTable' + tableCount).find("input").val("");
index++;
$('#timeTable' + tableCount + ' .aa').html(tableCount);
});
$(document).on('click', 'button.removeTime', function() {
var closestTable = $(this).closest('table');
if (closestTable.attr('id') != "timeTable") {
closestTable.remove();
}
tableCount--;
if (tableCount < 1) {
tableCount = 1;
}
return false;
});
.error {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="table" class="form-group">
<table id="timeTable" class="tg">
<tr class="form-group">
<td class="aa">1</td>
<td class="tg-yw4">
<button class="btn form-control btn-danger removeTime">Remove Events</button>
</td>
<td class="col-sm-4">
<!--added this to show error -->
<span class="error"></span>
<input placeholder="Event Date" name="events[]" class="input-lg" type="text" onfocus="(this.type='date')">
</td>
</tr>
<tr>
<td class="aa">1</td>
<td class="tg-yw4">Event Description:</td>
<td>
​<input name="event_descriptions[]" type="text" placeholder="Event description:" />
</td>
</tr>
</table>
</div>
<div class="my-5">
<button class="add_time btn btn-info">Add More Events</button>
</div>

Generate Sl No on the Form on button click

I have a form with three input fields named sl no ,stationerytype and stationeryqty There is a symbol + and - to append or delete these three field on click. I am trying the sl no field to generate Sl no automatically when i click the plus symbol and if I click - it will automatically adjust the sl no. but My sl no field remains blank .my code is
<table class="table table-bordered" id="tb" >
<tr class="tr-header">
<th class= "col-md-1" align="centre">Sl.No.</th>
<th class= "col-md-6" align="centre">STATIONARY TYPE</th>
<th class= "col-md-4" align="centre">STATIONARY QUANTITY</th>
<th class= "col-md-1"><span class="glyphicon glyphicon-plus"></span></th>
</tr>
<tr>
<?php
for($i=1;$i<=1;$i++)
{
?>
<td><input type="text" style="text-decoration: none" name="slno" value= "<?php echo $i; ?>" ></td>
<td><input type="text" style="text-decoration: none" name="stationerytype" ></td>
<td><input type="number" name="stationeryqtyrecd" id="stationeryqtyrecd" min="0"></td>
<td><a href='javascript:void(0);' class='remove'><span class='glyphicon glyphicon-remove'></span></a></td>
</tr>
<?php }?>
</table>
<button type="submit" name="add" class="btn btn-info" align="middle" >ADD </button>
<script>
var max = 4;
var count = 1;
$(function(){
$('#addMore').on('click', function() {
if(count <= max ){
var data = $("#tb tr:eq(1)").clone(true).appendTo("#tb");
data.find("input").val('');
count++;
}else{
alert("Sorry!! Can't add more than five samples at a time !!");
}
});
$(document).on('click', '.remove', function() {
var trIndex = $(this).closest("tr").index();
if(trIndex>1) {
$(this).closest("tr").remove();
} else {
alert("Sorry!! Can't remove first row!");
}
});
});
</script>
</div>
Thanks for any suggestion :-)
in your addMore function after erasing data from the newly created row just add one more line to set the serial number in first td.
$('#addMore').on('click', function() {
if(count <= max ){
var data = $("#tb tr:eq(1)").clone(true).appendTo("#tb");
debugger;
data.find("input").val('');
//set the count value in first td
data.find("input")[0].value = ++count;
}else{
alert("Sorry!! Can't add more than five samples at a time !!");
}
});
working javascript fiddle example

Filtering by drop down menu value in an HTML table using JavaScript

I have created a very simple table in HTML. The column "Sector" has 4 possible selections in a drop down list. I type manually the amount of money in the second column. What I want to do is to display Total Money in the third column, which should be:
Total money = (Amount of money) * 1, in case that Sector = Footbal (and therefore value "s1")
Total money = (Amount of money) * 9, in any other case
For some reason it multiplies always by 9. How can I make this work?
function getValue() {
var selectedValue1 = document.querySelectorAll(".sector");
if (selectedValue1 == 's1') {
CONSTANT = 1;
} else {
CONSTANT = 9;
}
}
var Initial = document.querySelectorAll('.number1');
var Double = document.querySelectorAll('.number2');
Initial.forEach(myFunction);
function myFunction(item, index) {
getValue()
item.addEventListener('change', (event) => {
var initialValue = event.target.value;
Double[index].value = initialValue * CONSTANT;
});
}
<! --COMIENZO TABLA -->
<table class="egt">
<! --SEGUNDA LINEA -->
<tr>
<th>Sector</th>
<th>Amount of money</th>
<th>Total money</th>
</tr>
<! --TERCERA LINEA -->
<tr>
<td>
<select class="sector">
<option value="s1">Football</option>
<option value="s2">Basketball</option>
<option value="s3">Volleyball</option>
<option value="s4">Rugby</option>
</select>
</td>
<td>
<input type="number" class="number1">
</td>
<td>
<input type="number" class="number2">
</td>
</tr>
<! --CUARTA LINEA -->
<tr>
<td>
<select class="sector">
<option value="s1">Football</option>
<option value="s2">Basketball</option>
<option value="s3">Volleyball</option>
<option value="s4">Rugby</option>
</select>
</td>
<td>
<input type="number" class="number1">
</td>
<td>
<input type="number" class="number2">
</td>
</tr>
</table>
<! --FINAL TABLA -->
You should delegate and get the value from the select on change
I added thead and tbody
const table = document.querySelector(".egt");
table.addEventListener("input", function(e) { // when ANYTHING changes
[...table.querySelectorAll("tbody tr")].forEach(row => { // loop over all rows
const sectorValue = row.querySelector(".sector").value == 's1' ? 1 : 9; // from this row
const num1 = row.querySelector(".number1").value;
row.querySelector(".number2").value = num1 * sectorValue;
});
})
<! --COMIENZO TABLA -->
<table class="egt">
<thead>
<! --SEGUNDA LINEA -->
<tr>
<th>Sector</th>
<th>Amount of money</th>
<th>Total money</th>
</tr>
</thead>
<! --TERCERA LINEA -->
<tbody>
<tr>
<td>
<select class="sector">
<option value="s1">Football</option>
<option value="s2">Basketball</option>
<option value="s3">Volleyball</option>
<option value="s4">Rugby</option>
</select>
</td>
<td>
<input type="number" class="number1">
</td>
<td>
<input type="number" class="number2">
</td>
</tr>
<! --CUARTA LINEA -->
<tr>
<td>
<select class="sector">
<option value="s1">Football</option>
<option value="s2">Basketball</option>
<option value="s3">Volleyball</option>
<option value="s4">Rugby</option>
</select>
</td>
<td>
<input type="number" class="number1">
</td>
<td>
<input type="number" class="number2">
</td>
</tr>
</tbody>
</table>
<! --FINAL TABLA -->
NOTE: I use the spread operator [...collection] to convert an HTML Collection into an array - it is to handle older EDGE browsers which do not have native forEach on a collection. You can do table.querySelectorAll("tbody tr").forEach() if you do not care to support older Edge
Your cade has some fundamental problems (f.e. since selectedValue1 is a Node list, it can't be equal to "s1"), but also your approach is incorrect.
I don't see any reason to create loop here, but if need it:
Loop through each row, and then get the value of selection as well as number, and calculate the output and set it. This is easier and the correct way.
First, Give your table thead and tbody tags to create a wrapper around data.
let CONSTANT = 1;
let rows = document.querySelectorAll("tbody tr");
[...rows].forEach(row => {
let selection = row.querySelector(".sector").value;
CONSTANT = selection === "s1" ? 1 : 9;
let number = row.querySelector(".number1").value;
row.querySelector(".number2").value = CONSTANT * number;
})
But this is also not the best way. Instead of looping, just add event listeners and call a function to calculate.
let rows = document.querySelectorAll("tbody tr");
[...rows].forEach(row => {
row.querySelector(".number1").addEventListener("input", () => {
calculate(row)
})
row.querySelector(".sector").addEventListener("change", () => {
calculate(row)
});
})
function calculate(row) {
let constant = row.querySelector(".sector").value === "s1" ? 1 : 9;
let num1 = row.querySelector(".number1").value;
row.querySelector(".number2").value = constant * num1;
}

Autocomplete an Input based on another Input with Percentages

first of all, please excuse me if I'm missing any info or I'm not being clear, I'm very new at this, still getting the hang of it.
I have the following form:
Form
I need the two % input fields to autocomplete so the sum is 100%. If input one is 90%, input 2 should autocomplete to 10% and vice-versa.
This is the HTML:
<!-- Tabla - - - - - - - -->
<div id="distDosFondos" class="table-responsive cambioDist">
<p>Selecciona fondos y porcentajes a distribuir:</p>
<!--table-responsive-->
<table class="table">
<thead>
<tr>
<th>Fondo</th>
<th>%</th>
</tr>
</thead>
<tbody>
<!-- Fila Cambio y Distribución de Fondos -->
<tr>
<td>
<div class="inputForm">
<select class="chosen" id="fondos1" name="fondos1">
<option value="">Fondo</option>
</select>
</div>
</td>
<td>
<div class="inputForm">
<input id="porcentage1" name="porcentage" type="text" class="form-control porcentage porcentaje1">
</div>
</td>
</tr>
<!-- //Fila Cambio y Distribución de Fondos -->
<!-- Fila Cambio y Distribución de Fondos -->
<tr>
<td>
<div class="inputForm">
<select class="chosen" id="fondos2" name="fondos2">
<option value="">Fondo</option>
</select>
</div>
</td>
<td>
<input id="porcentage2" name="porcentage" type="text" class="form-control porcentage porcentaje2">
</td>
</tr>
<!-- //Fila Cambio y Distribución de Fondos -->
</tbody>
</table>
</div>
<!-- Tabla - - - - - - - -->
There are a number of ways that you could approach this, but this is a pretty simple solution.
First, set up a handler for the input event of your two inputs
$("[name='porcentage']").on("input", function() {
...
});
Now, inside of this, you'll be handling changing the other input. First, let's make sure the percentage can't be over 100 and can't be below 0.
if($(this).val() > 100)
$(this).val(100);
else if($(this).val() < 0)
$(this).val(0);
Next, you need to get the other input, the one you want to change.
var otherInput = $(this).attr("id") == "porcentage1" ? $("#porcentage2") : $("#porcentage1");
Finally, set the other input's value to make the two add up to 100.
$(otherInput).val(100 - $(this).val());
Full code:
$("[name='porcentage']").on("input", function() {
if($(this).val() > 100)
$(this).val(100);
else if($(this).val() < 0)
$(this).val(0);
var otherInput = $(this).attr("id") == "porcentage1" ? $("#porcentage2") : $("#porcentage1");
$(otherInput).val(100 - $(this).val());
});
Fiddle
One possibility is to use the jQuery library:
$('#porcentage1, #porcentage2').on('input', function (event) {
var inputValue = parseInt($(this).val());
if (inputValue >= 0 && inputValue <= 100) { //ensure number is between 0 and 100
var otherValue = 100 - inputValue;
if (this.id === 'porcentage1') { //determines which input element was filled
$('#porcentage2').val(otherValue);
} else {
$('#porcentage1').val(otherValue);
}
}
})
You may have to use other validations/checks to make sure that the user is actually inputting a number, etc.
Without jQuery:
// attach a bunch of events to both inputs to handle any kind of change
['change', 'keyup', 'paste'].forEach(function(event) {
// .bind here essentially serves to pass reference of the current updated input, and the other input wich will be updated
porcentage1.addEventListener(event, onPercentageChange.bind(null, porcentage1, porcentage2));
porcentage2.addEventListener(event, onPercentageChange.bind(null, porcentage2, porcentage1));
});
function onPercentageChange(updatedInput, otherInput) {
var updatedValue = parseInt(updatedInput.value) || 0;
otherInput.value = 100 - updatedValue;
}
https://jsfiddle.net/tb7a7joc/
works IE9+

Categories