Let me first explain why I need to do this so that it makes sense. On the page there are various labels/titles for sections. Users might want to name these titles something else or use a different language. Instead of "Color" maybe "Hue". There is a table holding the information for the label and the section information. So, "color" and "red", and so on.
What I need is when the user changes a label input field in the table and clicks save - for the corresponding label(s) on the page to change. Within the table, the first column is the id of the matching label and also the class of the corresponding input. http://jsfiddle.net/NNpCB/4/
jQuery
// dynamically give table text inputs, with correct label classes
var valueCol = $("table#ruleTable tr td:nth-child(2)");
valueCol.html(function(){
return '<input value="' + $(this).text() + '" class="' + $(this).prev().text() + '" />';
});
// save new label text
$('.saveLbl').click(function () {
// for each input that was changed, find the corresponding label(s) and change the label text
// the input .class matches the label #id
});
HTML
<label id="lblcolor">Colors</label>
<ul>
<li>Red</li>
<li>Blue</li>
<li>Yellow</li>
</ul>
<label id="lblshape">Shapes</label>
<ul>
<li>Square</li>
<li>Circle</li>
<li>Rectangle</li>
</ul>
<br /><br />
<table id="ruleTable" border='1' cellpadding='15'>
<thead>
<tr>
<th>Label</th>
<th>Display Value</th>
<th>Language</th>
</tr>
</thead>
<tbody>
<tr>
<td>lblcolor</td>
<td>Colors</td>
<td>ENG</td>
</tr>
<tr>
<td>lblshape</td>
<td>Shapes</td>
<td>ENG</td>
</tr>
</tbody>
</table>
<br /><br />
<button class='saveLbl'>Save</button>
Try the following code : ( http://jsfiddle.net/W4k7W/ )
$('.saveLbl').click(function () {
// for each input that was changed, find the corresponding label and change the label text
// the input .class matches the label #id
var rows=$("#ruleTable tbody").children();
for(var i=0;i<rows.length;i++){
var rowKids = $(rows[i]).children();
var labelClass=$(rowKids[0]).text();
var value=$($(rowKids[1]).children()[0]).val(); // <--- rowKids[1] is the td , its first child is the input row
$("#"+labelClass).text(value);
}
});
Related
I have a table with attributes where every tr id has an attribute_id.
each tr contains 6 td's whereas the first td includes an input select box.
I am trying to automate the process of selecting input select boxes when the third td contains a specific word. I tried do this with jQuery but I cant get it work. I could not get the two for eaches work since I have attributes containing all different id's.
My current code looks as follows:
var id = 1;
while(id != 10000){
jQuery('#attribute_ " + id + " > tbody > tr').each(function(index, value) {
jQuery('#+"+id+" > tbody > tr').each(function(index, value) {
$('td:contains("metal")', td[1].select());
});
});
}
my html code:
<tr class="combination loaded" id="attribute_7892" data="7892" data-index="7892" style="display:
table-row;">
<td width="1%">
//select this when contains metal
<input class="js-combination" type="checkbox" data-id="7892" data-index="7892">
</td>
<td class="img"><img src="http://image" class="img-responsive"></td>
//contains metal:
<td>Chain - plastic, left - right, skin - metal silver - V6, color - dark/gray</td>
<td class="attribute-price">5.00</td>
</tr>
The basic process would be like this:
Loop through each tr
Check if the tr has an id matching 'attribute_[number]'
Check if the 3rd td of that tr contains the word 'metal'
Set checked to true if so, otherwise set to false.
Here is an example:
var search = 'metal';
var rows = $('tr.combination.loaded');
rows.each(function(index, value) {
if (/(attribute\_)(\d+)/g.test(value.id)) {
$(this).children(0).children(0).attr('checked', ($(this).children(2).text().indexOf(search) !== -1));
};
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr class="combination loaded" id="attribute_7892" data="7892" data-index="7892" style="display:
table-row;">
<td width="1%">
//select this when contains metal
<input class="js-combination" type="checkbox" data-id="7892" data-index="7892">
</td>
<td class="img"><img src="http://image" class="img-responsive"></td>
//contains metal:
<td>Chain - plastic, left - right, skin - metal silver - V6, color - dark/gray</td>
<td class="attribute-price">5.00</td>
</tr>
</table>
I'm using a function which I've adapted to clone table rows when a certain button is clicked (see this fiddle), and assign the new row an incremented ID (i.e. table-rows-1 to table-rows-2). After creating a new row, I want a function I'm making to find an input in a td in this row and change its name from input-text-1 to input-text-2. I'm not very confident with Javascript, and am having trouble accessing the input element within the row. Heres an example:
<table>
<tbody>
<tr class="modal-rows" id="table-rows-1">
<td>
<input type="text" class="input-text" name="input-text-1">
</td>
</tr>
<tr class="modal-rows" id="table-rows-2"> <<< DUPLICATED ROW WITH INCREMENT ID
<td>
<input type="text" class="input-text" name="input-text-1">
</td>
</tr>
</tbody>
</table>
How can I access the inner inputs of this table in order to change their name? Heres what I've tried:
var rowNum = document.getElementsByClassName("modal-rows").length
$('#table-rows-' + rowNum + ' .input-text').attr('name', 'input-text-' + rowNum);
$('#table-rows-' + rowNum).find('.input-text').attr('name', 'input-text-' + rowNum);
$('#table-rows-' + rowNum).children('.input-text').attr('name', 'input-text-' + rowNum);
Can anyone let me know where I'm going wrong?
You can use below code inside your duplicate function:
clone.children[0].setAttribute('name', 'input-text'+ ++i)
I have a html table created using jQuery:
success: function(data, textStatus, errorThrown) {
var rows ="";
function formatItem(data) {
return '<td>'+data.name + '</td> <td> ' + data.price + ' </td><td>' + "<input></input>" +'</td>';
}
$.each(data, function (key, item) {
$('<tr>', { html: formatItem(item) }).appendTo($("#foodnames"));
});
}
This is what the interface looks like:
The table is working fine with all the data showing.
The problem is finding the sum of the third column. Where I can enter a number and display it using an id.
Is there anyway to do it?
What you want to do is to use jQuery to select the table, and all of the third td's for each row, then sum it. The basic pseudocode is:
Clear the output box.
ForEach TR
Select the third TD
Add that value to the output box.
End ForEach
To do that in jQuery, you just need to know how to select the right values. Assigning relevant class/id names is helpful.
I put together a basic example that you can run. It will tabulate the total of the third column dynamically, as you change the value. I hard coded the price column, but you could easily put some other values or input there.
I put it in an onChange event handler, but if you are loading the data from a server or something, you could do document onLoad or whenever your ajax is complete.
//trigger an event when the input receives a change
$("#exampleTableContainer table td input").off("change").on("change", function(ele) {
//clear the out put box
$("#totalOut").val("0");
//for the table container, select all tr's within the table's tbody.
//Excluding tbody will also select the thead.
$("#exampleTableContainer table tbody tr").each(function(index, rowElement) {
//tablulate the cost of the current row
var rowCost = parseInt($(rowElement).find(".cost").text()) * parseInt($(rowElement).find(".amount input").val());
//if the rowCost is a valid number, add it to whatever is in the output box
if (rowCost) $("#totalOut").val(parseInt($("#totalOut").val()) + rowCost)
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="exampleTableContainer">
<table>
<thead>
<tr>
<th class="item">Item</th>
<th class="cost">Cost</th>
<th class="amount">Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td class="item">Item 1</td>
<td class="cost">123</td>
<td class="amount">
<input type="number">
</td>
</tr>
<tr>
<td class="item">Item 2</td>
<td class="cost">1</td>
<td class="amount">
<input type="number">
</td>
</tr>
<tr>
<td class="item">Item 3</td>
<td class="cost">2</td>
<td class="amount">
<input type="number">
</td>
</tr>
<tr>
<td class="item">Item 4</td>
<td class="cost">4</td>
<td class="amount">
<input type="number">
</td>
</tr>
</tbody>
</table>
<br>
<div>
Total:
<input id="totalOut" readonly value="0">
</div>
</div>
I'm not sure if you plan to use this in a production environment or not, so maybe this is overkill for what you're trying to accomplish, but I would recommend using an underlying data model bound to the table. Then you can get your sum from your data:
const data = [
{food: "Veggie burger", price: 200, qty:1},
// ...Add as many food items as you like
]
You would be able to use the data to build your table:
// Get a reference to the table and create a document fragment
const table = document.getElementById("table-body");
const body = document.createDocumentFragment();
// Fill the fragment with your data:
data.map((value, key) => {
// Row-building logic goes here
// this probably isn't what you actually do here:
const row = document.createElement("tr");
row.className = key;
for (let x in value) {
const dataCell = document.createElement("td");
dataCell.className = x;
dataCell.innerHTML = value[x];
row.appendChild(dataCell);
}
body.appendChild(row);
});
table.innerHTML = "";
table.appendChild(body);
Then you can calculate your sum based on the data, not the UI:
const subTotal = data
.map((value) => value.price * value.qty)
.reduce((a, b) => a + b);
document.getElementById("total").textContent = subTotal;
You would set an event listener on the table(parent node) and use event.target to find the row and column (.qty in this case) and update the corresponding field (qty) in the data object when the input is changed.
$("#my-table").on("input", (e) => {
// You would probably be better off using a custom attribute than a class since there can be multiple classes, but we'll use class to keep it simple:
const column = $(e.target).parent("td").attr("class");
const row = $(e.target).parent("td").parent('tr').attr("class");
data[row][column] = e.target.value;
console.log(data);
});
This pattern also makes it easy to send the updated data back to the REST API to update your database later.
https://jsfiddle.net/79et1gkc/
I know you said you're using jQuery, but ES6 is much nicer in my opinion.
Try this:
$(document).ready(function(){
var total = 0;
$("#submit").click(function(){
$(".user_input").each(function(){
var value = parseInt($(this).val());
total += value;
});
$("#output").text(total);
});
});
HTML
<input type="text" name="value1" class="user_input"/>
<input type="text" name="value2" class="user_input"/>
<input type="text" name="value3" class="user_input"/>
<button name="submit" id="submit" value="calculate">
Calculate
</button>
<div>
<span>Total:</span><div id="output">
</div>
In my given example, i have two text boxes. when value in first text box changed i want to find the immediate next text box (note : without id) and change its value.
The example given contains only single text box group. actually it can be more than one text boxes. (group of from & to text boxes of Financial Data)
so, when value in from text box (txtFinancialYearFrom) changed, i want to find the to text box (txtFinancialYearTo) and change its value as well.
JsFiddle Link - Example
Thanks in advance for the help!!
<table class="fotm-table">
<tr>
<td class="text-right" width="120">
<span id="ContentPlaceHolder1_lblFinancialYear">Financial Data :</span>
</td>
<td>
<span>
<input type="text" id="txtFinancialYearFrom"
name="ctl00$ContentPlaceHolder1$txtFinancialYearFrom">
</span>
</td>
<td width="20" align="center">
<span style="align-content: center">to</span>
</td>
<td>
<span>
<input type="text" id="txtFinancialYearTo"
name="ctl00$ContentPlaceHolder1$txtFinancialYearTo">
</span>
</td>
</tr>
</table>
Using the given information, since you are going to have more blocks (that should be rows on your table), this solution should work:
var rows = $('.fotm-table tr');
$(rows).each(function(){
$('input:first', $(this)).on('change', function(){
var fromValue = $(this).val();
var row = $(this).closest('tr');
$('td:last input', row).val(parseInt(fromValue) + 1);
});
});
The code gets all the rows from your table and for each one of them, it will add a listener that when you change the first textbox (input), it will change the value of the next textbox (here it's adding 1 to it).
If I've understood correctly, you need something like this:
/* Loop through all table rows */
$('tr','table.fotm-table').each(function() {
var tr = this;
/* Cache all inputs a jquery object - you may want to specify which type of input you are targeting i.e. $('input[type="text"]') */
var inputs = $('input',tr);
/* Cache the slave (second in the example) input in a jquery object - you can do the same for multiple inputs, simply by modifying the eq() index parameter
*/
var slaveInput = inputs.eq(1);
/* Listen for changes on the master input */
var masterInput = inputs.eq(0).on('change',function() {
/* Do smt on the slave input - fill it with the next year in the example */
var year = $(this).val();
var followingYear = parseInt(year,10)+1
slaveInput.val(followingYear);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="fotm-table">
<tr>
<td class="text-right" width="120">
<span id="ContentPlaceHolder1_lblFinancialYear">Financial Year :</span>
</td>
<td>
<span>
<input type="text" id="txtFinancialYearFrom"
name="ctl00$ContentPlaceHolder1$txtFinancialYearFrom">
</span>
</td>
<td width="20" align="center">
<span style="align-content: center">to</span>
</td>
<td>
<span>
<input type="text" id="txtFinancialYearTo"
name="ctl00$ContentPlaceHolder1$txtFinancialYearTo">
</span>
</td>
</tr>
</table>
Here's an updated fork of the jsFiddle you provided:
https://jsfiddle.net/jkdaza/thonfzwu/5/
You can use this tricky solution from link:
$('#txtFinancialYearFrom').change(function(el) {
$(':input:eq(' + ($(':input').index(this) + 1) + ')').val('test');
});
https://jsfiddle.net/g34yqL0u/2/
I have a table that needs some custom theming. It has a lot of text inputs and they all need custom widths. I figured it would be nice to simply add custom CSS classes based on the label name of each field. I am part of the way there but for some reason I am picking up all the label names for any given label in the table, not simply the closest one as I desire.
Here is my JQuery:
$('td.label-text', this).each(function() {
// add class with name of the label text
$('td.input-text').addClass($(this).text().replace(/[^a-z]/gi,'').toLowerCase() + ' ').closest("td.label-text");
});
Here is some sample HTML output:
<tr>
<td class="label-text">Rule Name*:</td>
<td class="input-text effectivedate rulename employeeid createrulefor ipaddress active searchby">
<input type="text" name="ruleName" value="">
</td>
</tr>
<tr>
<td class="label-text">Employee ID:</td>
<td class="input-text effectivedate rulename employeeid createrulefor ipaddress active searchby">
<input type="text" name="employeeId" value="" id="empnotext">
</td>
</tr>
As you can see all label names get added to every td .input-text class, not the nearest (closest) one. I am sure I am doing something wrong but not sure what.
I am also wondering if a class can be added based on the input name
You have to use this inside the loop. Currently, you're selecting all elements with selector td.input-text (at each iteration). Fiddle: http://jsfiddle.net/WCTyz/2/
$('td.input-text input', this).each(function() {
// add class with name of the label text
var $this = $(this);
var addclass = $this.parents("tr:first").children("td:first")
.text().replace(/[^a-z]/gi,'').toLowerCase();
$this.addclass(addClass);
});
Also, the addClass method automatically deals with separating spaces. You don't have to manually postfix your class name by a space.
Explanation of selector:
td.input-text input For each <td class="input-text"> ???? <input> ??? </td> :
Get class name:
.parents("tr:first") Select the current row
.children("td:first") Select the first cell
.text() Get the textual value