I have an html table that is wrapped by a form with each cell having an input element in it.
I was wondering if there is a way to obtain the first cell's input value of a particular column and pasting that value in the rest of the cells in that column. In other words, the user will type into the input field of first cell and then click on button to duplicate that entry into the rest of the cells of that column.
Assuming you have a table with a button on each row, give the button a class so that it can have an event assigned:
<button type='button' class='copybtn'>copy</button>
don't use IDs as you need multiple buttons;
$(".copybtn").click(function() {
You can get the button's column using var col = $(this).closest("td").index() (add 1 as .index() is 0-based, but we need 1-based :nth-child).
Get the column cells using:
var cells = $("table").find("tr > td:nth-child(" + col + ")");
Various ways to handle this - eg get all the cells as above, then get the first for the input and last for the button or get the input from the first row's nth-child (as in the snippet)
To get the value: var val = inp.val()
To copy the values, depends on your HTML, you could give each destination cell a class then:
cells.find("td.dest").text(val);
or you can get all cells and exclude first/last:
tbl.find("tr:not(:first):not(:last) > td:nth-child(" + col + ")").text(val);
Altogether:
$(".copybtn").click(function() {
// get 0-based column index
var col = $(this).closest("td").index() + 1;
var tbl = $(this).closest("table");
var val = tbl.find("tr:first td:nth-child(" + col + ")").find("input").val();
tbl.find("tr:not(:first):not(:last) > td:nth-child(" + col + ")").text(val);
});
input {
width: 50px;
}
td {
min-width: 20px;
border: 1px solid #CCC;
margin: 0;
padding: 5px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id='t'>
<tbody>
<tr>
<td><input type='text' class='inp' /></td>
<td><input type='text' class='inp' /></td>
<td><input type='text' class='inp' /></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td><button type='button' class='copybtn'>copy</button></td>
<td><button type='button' class='copybtn'>copy</button></td>
<td><button type='button' class='copybtn'>copy</button></td>
</tr>
</tbody>
</table>
If I understand correctly, you'll need something like this:
const copy=(id) => {
var value = document.getElementById("col"+id+"-input").value
var list = document.getElementsByClassName("col"+id+"-input")
for (i = 0; i < list.length; i++)
list[i].value = value
}
document.getElementById("col1-button").addEventListener("click", ()=>copy(1))
document.getElementById("col2-button").addEventListener("click", ()=>copy(2))
document.getElementById("col3-button").addEventListener("click", ()=>copy(3))
<table>
<tr>
<td><input id="col1-input" class="col1-input"><button id="col1-button">OK</button><br>
<td><input class="col1-input"></td>
<td><input class="col1-input"></td>
<td><input class="col1-input"></td>
<td><input class="col1-input"></td>
</tr>
<tr>
<td><input id="col2-input" class="col2-input"><button id="col2-button">OK</button><br>
<td><input class="col2-input"></td>
<td><input class="col2-input"></td>
<td><input class="col2-input"></td>
<td><input class="col2-input"></td>
</tr>
<tr>
<td><input id="col3-input" class="col3-input"><button id="col3-button">OK</button><br>
<td><input class="col3-input"></td>
<td><input class="col3-input"></td>
<td><input class="col3-input"></td>
<td><input class="col3-input"></td>
</tr>
</table>
Try this... JQuery solution.
Good luck!
$(function() {
$('button').on('click', function() {
var inputVal = $(this).prev().val();
// Plus one because arrays start at zero
var colIndex = $(this).parent().parent().children().index($(this).parent()) + 1;
$('table tr td:nth-child('+colIndex+')').not(':first')
.html(inputVal);
});
});
body { margin: 10px; }
table { max-width: 600px; }
td { min-width: 280px; }
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="">
<table class="table table-bordered">
<tr>
<td><input type="text"><button type="button">Copy</button></td>
<td><input type="text"><button type="button">Copy</button></td>
<td><input type="text"><button type="button">Copy</button></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
</form>
Related
I have dynamic table that in one td passes php vales of prices and on end of the table is sum of those prices. There is also a checkbox in every row default checked. I need to empty the content of row where checkbox is unchecked so it removes that price value out of sum calculation.
Question, will that even remove that value? I know setting the td field to hide does not.
Value cell:
<td style="width:10%" class="rowDataSd" id="value">
<?php echo
str_replace(array(".", ",",), array("", "."), $row['rad_iznos']);
?>
</td>
Checkbox cell:
<td style="width:3%">
<input class="w3-check" type="checkbox" checked="checked" id="remove" name="uvrsti" value="<?php echo $row['rad_id']?>">
</td>
I tried with this but nothing happens with no errors:
$(document).ready(function(){
if($("#remove").is(':checked')) {
$("#value").show();
} else {
$("#value").empty();
}
});
I can pass the unique values into each checkbox and value element into id's like:
id="<?php echo $row['rad_id']?>"
. So they tie each other but don't know how to say in JS to empty those elements.
I was also thinking something along the lines of, if on some row checkbox is unchecked empty closest td with id="value". My guess is that would be best solution but I don't know how to write it.
Or even if checkbox is unchecked remove css class .rowDataSd to closest td with id="vale" based on whom calculation is made.
Sum script:
var totals=[0,0,0];
$(document).ready(function(){
var $dataRows=$("#sum_table tr:not('.totalColumn, .titlerow')");
$dataRows.each(function() {
$(this).find('.rowDataSd').each(function(i){
totals[i]+=parseFloat( $(this).html());
});
});
$("#sum_table td.totalCol").each(function(i){
$(this).html('<span style="font-weight: bold;text-shadow: 0.5px 0 #888888;">'+totals[i].toFixed(2)+' kn</span>');
});
});
As seen on picture need to remove row out of calculation if checkbox is unchecked. Keep in mind I dont want to delete to row, just remove it our of calculation.
Any help with how to approach this is appreciated.
Here is a basic example.
$(function() {
function getPrice(row) {
var txt = $(".price", row).text().slice(1);
var p = parseFloat(txt);
return p;
}
function calcSum(t) {
var result = 0.00;
$("tbody tr", t).each(function(i, r) {
if ($("input", r).is(":checked")) {
result += getPrice(r);
}
});
return result;
}
function updateSum(tbl) {
var t = calcSum(tbl);
$("tfoot .total.price", tbl).html("$" + t.toFixed(2));
}
updateSum($("#price-list"));
$("#price-list input").change(function() {
updateSum($("#price-list"));
});
});
#price-list {
width: 240px;
}
#price-list thead th {
width: 33%;
border-bottom: 1px solid #ccc;
}
#price-list tfoot td {
border-top: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="price-list">
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td class="item name">Item 1</td>
<td class="item price">$3.00</td>
<td><input type="checkbox" checked /></td>
</tr>
<tr>
<td class="item name">Item 2</td>
<td class="item price">$4.00</td>
<td><input type="checkbox" checked /></td>
</tr>
<tr>
<td class="item name">Item 3</td>
<td class="item price">$5.00</td>
<td><input type="checkbox" checked /></td>
</tr>
</tbody>
<tfoot>
<tr>
<td>Sum</td>
<td class="total price">$0.00</td>
<td> </td>
</tr>
</tfoot>
</table>
It all boils down to setting up an event handler for the checkboxes. The event handler should perform the following:
Track the checkbox change event for all checkboxes and the DOM ready event
Calculate the total of all rows with checkbox checked
Set the total to the total element
It call also perform any desired changes on the unchecked row .. not done in sample code below
THE CODE
$(function() {
$('.select').on('change', function() {
let total = $('.select:checked').map(function() {
return +$(this).parent().prev().text();
})
.get()
.reduce(function(sum, price) {
return sum + price;
});
$('#total').text( total );
})
.change();//trigger the change event on DOM ready
});
THE SNIPPET
$(function() {
$('.select').on('change', function() {
let total = $('.select:checked').map(function() {
return +$(this).parent().prev().text();
})
.get()
.reduce(function(sum, price) {
return sum + price;
});
$('#total').text( total );
})
.change();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Item</th>
<th>Price</th>
<th>Select</th>
</tr>
</thead>
<tbody>
<tr>
<td>Item 1</td>
<td>1000</td>
<td><input type="checkbox" class="select" checked></td>
</tr>
<tr>
<td>Item 2</td>
<td>1200</td>
<td><input type="checkbox" class="select" checked></td>
</tr>
<tr>
<td>Item 3</td>
<td>800</td>
<td><input type="checkbox" class="select" checked></td>
</tr>
<tr>
<td>Item 4</td>
<td>102000</td>
<td><input type="checkbox" class="select" checked></td>
</tr>
</tbody>
</table>
<span>TOTAL</span><span id="total"></span>
I need to increment an html table column value by 1.
For example, I have three columns in the table and the column value for the first row is 1, the second should be 2 etc.
So, If I have Roll No column with first column value is 1 then the next two rows Roll No value should be 2 and 3.
The following script does not work.
<!DOCTYPE html>
<html>
<head>
<script>
function myFunction() {
//document.getElementById('info').innerHTML = "";
var myTab = document.getElementById('sample_table');
var rollNo=document.getElementById('input2').value;
// LOOP THROUGH EACH ROW OF THE TABLE AFTER HEADER.
var count=0;
for (var i = 1; i < myTab.rows.length; i++) {
// GET THE CELLS COLLECTION OF THE CURRENT ROW.
var objCells = myTab.rows.item(i).cells;
// LOOP THROUGH EACH CELL OF THE CURENT ROW TO READ CELL VALUES.
for (var j = 0; j < objCells.length; j++) {
count++;
//alert('hi'+count);
if(count>1){
myTab.rows[i].cells[j+1].innerHTML=rollNo+1;
}
}
}
}
</script>
</head>
<body onload="myFunction()">
<table id='sample_table'>
<tr>
<th> Name</th>
<th> Roll No</th>
</tr>
<tr>
<td><input id='input1' value='abc' readonly></td>
<td><input id='input2' value='1' ></td>
</tr>
<tr>
<td><input id='input3' value='def' readonly></td>
<td><input id='input4' ></td>
</tr>
<tr>
<td><input id='input5' value='xyz' readonly></td>
<td><input id='input6' ></td>
</tr>
</table>
</body>
</html>
You can get all the inputs in a column using querySelectorAll, like this:
document.addEventListener('DOMContentLoaded', function() {
// Collects all the inputs from the 2nd column
const inputs = document.querySelectorAll('#sample_table td:nth-child(2) input');
// Get the value of the first input in the collection, and convert it to number
const first = +inputs[0].value;
// Iterate through the inputs in the collection excluding the first one
for (let n = 1, eN = inputs.length; n < eN; n++) {
inputs[n].value = first + n;
}
});
<table id="sample_table">
<tr>
<th> Name</th>
<th> Roll No</th>
</tr>
<tr>
<td><input id="input1" value="abc" readonly></td>
<td><input id="input2" value="5"></td>
</tr>
<tr>
<td><input id="input3" value="def" readonly></td>
<td><input id="input4"></td>
</tr>
<tr>
<td><input id="input5" value="xyz" readonly></td>
<td><input id="input6"></td>
</tr>
</table>
If the column of the inputs is changed, the number in nth-child() can be changed to point to the correct column. This indexing is 1-based.
I'm guessing something like
rowspan="2"
or
colspan="2"
but we need the code the image is good for reference but we need something to work with.
I have two input fields with label empID and Name and table with 3 columns tblempID, tblName and tblTxt.
How to set empID value to be the same tblmpID value when any tblTxt cell value changed in each row in table.
T tried the following:
$(document).ready(function(){
tblTxtchange();
$('.tbl1').on('change', tblTextchange);
function tblTxtchange() {
$('.tbl1 tbody tr').each(function () {
$(this).find('.tblTxt').each(function () {
$('.tblTxt').change(function(){
$('.empID').val($('.tblText')
.closest('tr').find($('.tblEmpID').val()));
});
});
});
}
});
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
<input id="empID"/>
<input id="Name"/>
<table style="width:100%" class="tbl1">
<tr>
<th>tblempID</th>
<th>tblName</th>
<th>tblTxt</th>
</tr>
<tr>
<td><input class="tblEmpID" /></td>
<td><input class="tblName" /></td>
<td><input class="tblTxt" /></td>
</tr>
<tr>
<td><input class="tblEmpID" /></td>
<td><input class="tblName" /></td>
<td><input class="tblTxt" /></td>
</tr>
<tr>
<td><input class="tblEmpID" /></td>
<td><input class="tblName" /></td>
<td><input class="tblTxt" /></td>
</tr>
</table>
I suspect you're overthinking it. (You're also using .find() incorrectly.) At its simplest, you want a handler for .tblTxt elements which finds the corresponding tblEmpID value and sets it to the #empID element. There's no need for loops, function calls, etc. Something like this:
$('.tblTxt').on('change', function () {
let empID = $(this).closest('tr').find('.tblEmpID').val();
$('#empID').val(empID);
});
I have a running code for your problem please update if you are looking for something else
$('.tblTxt').change(function () {
var row_emp_id = $(this).closest('tr').find('.tblEmpID').val();
$('#empID').val(row_emp_id);
});
I have 3 textboxes in each row. At least one of the rows should be filled completely. All the textboxes in any of the rows should not be empty. I have tried below code, it's for the first row only.
var filledtextboxes= $(".setup_series_form tr:first input:text").filter(function () {
return $.trim($(this).val()) != '';
}).length;
We want to get the maximum number of non-empty textboxes in any row, TIA.
Loop through all the rows. In each row, get the number of filled boxes. If this is higher than the previous maximum, replace the maximum with this count.
var maxboxes = -1;
var maxrow;
$(".setup_series_form tr").each(function(i) {
var filledtextboxes = $(this).find("input:text").filter(function () {
return $.trim($(this).val()) != '';
}).length;
if (filledtextboxes > maxboxes) {
maxboxes = filledtextboxes;
maxrow = i;
}
});
You are targeting only first tr here $(".setup_series_form tr:first input:text") so you will not get the expected output.
You have to iterate with every row(tr) inside form and then find the count of
text field having not empty values and store in a maxCount variable by comparing it previous tr count.
Here is a working snippet:
$(document).ready(function() {
var maxCountInRow =0;
var rowNumber;
$(".setup_series_form tr").each(function(index){
var filledtextboxes= $(this).find("input:text").filter(function () {
return $.trim($(this).val()) != '';
}).length;
if(filledtextboxes>maxCountInRow){
maxCountInRow=filledtextboxes;
rowNumber=index;
}
});
console.log("Row Number:"+rowNumber+" having maxCount: "+maxCountInRow);
});
.registrant_table{width: 100%;border: 1px solid #ccc;text-align: center;}
.registrant_table tr td{border: 1px solid #ccc;height: 42px;font-weight: bolder;}
.registrant_table input{border: 0px !important;width: 100%;height: 42px;text-align: center;font-weight: normal;}
label.error{color: red !important;}
.err-fields{background-color:red;color: white !important;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form class="setup_series_form">
<div>
<table class="registrant_table">
<tr class="title">
<td>No</td>
<td>Official Full Name</td>
<td>Mobile Contact</td>
<td>Email</td>
</tr>
<tr class="in-fields">
<td>1</td>
<td><input type="text" value="sas" name="firstname[]"></td>
<td><input type="text" value="" name="phone[]"></td>
<td><input type="text" value="" name="email[]"></td>
</tr>
<tr class="in-fields">
<td>2</td>
<td><input type="text" value="sas" name="firstname[]"></td>
<td><input type="text" value="sas" name="phone[]"></td>
<td><input type="text" name="email[]"></td>
</tr>
<tr class="in-fields">
<td>3</td>
<td><input type="text" name="firstname[]"></td>
<td><input type="text" name="phone[]"></td>
<td><input type="text" name="email[]"></td>
</tr>
</table>
</div>
</form>
I'm using JQuery and I'm sure this is pretty simple stuff but I was unable to find a solution. I have an employee table with "Number" column which is editable(text box). I want to find the duplicates in the "Number" column and highlight those textboxes. For example in the table below I want to highlight all textboxes with values 10 and 20. Also when a edit is done and there are no longer duplicates, remove the highlight.
Here's the JSFiddle
Any Ideas?
<table id="employeeTable">
<tr>
<th>Id</th>
<th>Name</th>
<th>Number</th>
</tr>
<tr>
<td>1</td>
<td>John</td>
<td>10</td>
</tr>
<tr>
<td>2</td>
<td>Sally</td>
<td>20</td>
</tr>
<tr>
<td>3</td>
<td>Mary</td>
<td>10</td>
</tr>
<tr>
<td>4</td>
<td>Sam</td>
<td>30</td>
</tr>
<tr>
<td>5</td>
<td>Chris</td>
<td>20</td>
</tr>
</table>
There are different possibilities, basically you'll have to test if the value of an array exists more than one time, for example like this.
Update:
Using the value selector works fine in the initial state, but it seems that when a value is changed by direct user input or by calling .val(), the HTML attribute value is not changed (only the native JS .value). Therefore - to use the value selector in this context, the html value attribute is always updated with the JS .value.
function highlightDuplicates() {
// loop over all input fields in table
$('#employeeTable').find('input').each(function() {
// check if there is another one with the same value
if ($('#employeeTable').find('input[value="' + $(this).val() + '"]').size() > 1) {
// highlight this
$(this).addClass('duplicate');
} else {
// otherwise remove
$(this).removeClass('duplicate');
}
});
}
$().ready(function() {
// initial test
highlightDuplicates();
// fix for newer jQuery versions!
// since you can select by value, but not by current val
$('#employeeTable').find('input').bind('input',function() {
$(this).attr('value',this.value)
});
// bind test on any change event
$('#employeeTable').find('input').on('input',highlightDuplicates);
});
Updated fiddle is here.
I guess this is what you are exactly looking for:
Working : Demo
1) First for loop for taking all input values into an array inpValArr[]
2) Second for loop for sorting and finding out the duplicate ones.
3) Third for loop for adding class .highLight to duplicate ones.
Now all this is in a function: inputCheck() which is called on DOM Ready and after you edit the text field.
inputCheck();
$("#employeeTable input").bind("change paste keyup", function() {
inputCheck();
});
function inputCheck() {
var totalInp = $("#employeeTable input").length;
var inpValArr = [];
for (var j = 0; j < totalInp; j++) {
var inpVal = $("#employeeTable input:eq(" + j + ")").val();
inpValArr.push(inpVal);
}
var sorted_arr = inpValArr.sort();
var results = [];
for (var i = 0; i < inpValArr.length - 1; i++) {
if (sorted_arr[i + 1] == sorted_arr[i]) {
results.push(sorted_arr[i]);
}
}
$('#employeeTable input').removeClass('highLight');
for (var k = 0; k < totalInp; k++) {
$('#employeeTable :input[value="' + results[k] + '"]').addClass('highLight');
}
}
#employeeTable th,
#employeeTable td {
padding: 0.8em;
border: 1px solid;
}
#employeeTable th {
background-color: #6699FF;
font-weight: bold;
}
.highLight {
background: red;
}
<table id="employeeTable">
<tr>
<th>Id</th>
<th>Name</th>
<th>Number</th>
</tr>
<tr>
<td>1</td>
<td>John</td>
<td>
<input type="text" value="10" />
</td>
</tr>
<tr>
<td>2</td>
<td>Sally</td>
<td>
<input type="text" value="20" />
</td>
</tr>
<tr>
<td>3</td>
<td>Mary</td>
<td>
<input type="text" value="10" />
</td>
</tr>
<tr>
<td>4</td>
<td>Sam</td>
<td>
<input type="text" value="30" />
</td>
</tr>
<tr>
<td>5</td>
<td>Chris</td>
<td>
<input type="text" value="20" />
</td>
</tr>
</table>
You could easily give a class such as 'hasInput' to all td with inputs and then try a .each on all of them and check for value if they are 10 or 20 and then add a class to make them styled as you wish.
html:
<table id="employeeTable">
<tr>
<th>Id</th>
<th>Name</th>
<th>Number</th>
</tr>
<tr>
<td>1</td>
<td>John</td>
<td class="hasInput"><input type="text" value = "10"/></td>
</tr>
<tr>
<td>2</td>
<td>Sally</td>
<td class="hasInput"><input type="text" value = "20"/></td>
</tr>
<tr>
<td>3</td>
<td>Mary</td>
<td class="hasInput"><input type="text" value = "10"/></td>
</tr>
<tr>
<td>4</td>
<td>Sam</td>
<td class="hasInput"><input type="text" value = "30"/></td>
</tr>
<tr>
<td>5</td>
<td>Chris</td>
<td class="hasInput"><input type="text" value = "20"/></td>
</tr>
css:
#employeeTable th, #employeeTable td{
padding:0.8em;
border: 1px solid;
}
#employeeTable th{
background-color:#6699FF;
font-weight:bold;
}
.colored {
background-color: red;
}
js:
$('.hasInput > input').each(function() {
if ($(this).val() == 10 || $(this).val() == 20) {
$(this).addClass('colored');
}
});
DEMO
This would work:
var dupes=[], values=[];;
$('.yellow').removeClass('yellow');
$('#employeeTable td:nth-child(3) input').each(function(){
if($.inArray($(this).val(),values) == -1){
values.push($(this).val());
}
else{
dupes.push($(this).val());
}
});
$('#employeeTable td:nth-child(3) input').filter(function(){return $.inArray(this.value,dupes) == -1 ? false : true }).addClass('yellow');
#employeeTable th, #employeeTable td{
padding:0.8em;
border: 1px solid;
}
#employeeTable th{
background-color:#6699FF;
font-weight:bold;
}
.yellow{
background-color:yellow;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="employeeTable">
<tr>
<th>Id</th>
<th>Name</th>
<th>Number</th>
</tr>
<tr>
<td>1</td>
<td>John</td>
<td><input type="text" value = "10"/></td>
</tr>
<tr>
<td>2</td>
<td>Sally</td>
<td><input type="text" value = "20"/></td>
</tr>
<tr>
<td>3</td>
<td>Mary</td>
<td><input type="text" value = "10"/></td>
</tr>
<tr>
<td>4</td>
<td>Sam</td>
<td><input type="text" value = "30"/></td>
</tr>
<tr>
<td>5</td>
<td>Chris</td>
<td><input type="text" value = "20"/></td>
</tr>
</table>
Expanding on the answer provided by #axel.michel using .count() selector of Linq.js. I decided to go this route because I couldn't get the JQuery selector to work correctly provided in his answer. And I really like the Linq.js and find myself loving it more each time i implement a use of it.
var allTextBoxes = $().find('input:text');
// loop over all input fields on page
$(allTextBoxes)
.each(function() {
// select any other text boxes that have the same value as this one
if (Enumerable.from(allTextBoxes).count("$.value == '" + $(this).val() + "'") > 1) {
// If more than 1 have the same value than highlight this textbox and display an error message
$(this).addClass('duplicate');
$('#custom-field-validator').html('Custom fields must have unique names.');
valid = false;
} else {
// otherwise remove
$(this).removeClass('duplicate');
}
});
This is working fine without needing to worry about the value selector and syncing the value attributes.