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)
Related
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>
I have the following row structure that serves as a template to clone it and add it to a table each time a user presses an "Add" button, This template is hidden:
<tr class="plantilla">
<td>
<select class="cmb_arboles" id="cmb_arboles" name="arboles[]">
</select>
</td>
<td>
<input type="text" id="txttoneladas" name="txttoneladas[]"/>
</td>
<td>
<input type="text" id="txtprecio" name="txtprecio[]"/>
</td>
<td>
<select id="cmb_destino" name="destino[]">
</select>
</td>
<td class="eliminar_fila">
Eliminar
</td>
</tr>
When the "add" button is pressed, invokes:
$("#agregar").click(function()
{
nid++;
$("#plantilla tbody tr:eq(0)").clone().attr("id",nid).appendTo("#plantilla tbody");
$("#plantilla tbody tr:eq(nid)").find("td:eq(0)").find("select").attr("id","cmb_arboles_"+nid);
});
The first line, generates the sequence of the row number. The second line clones the entire template as a new row in the table and adds an id = nid to the .
The third line, accesses the row and looks for the select to add the nid sequential to the select id, but this does not work. When doing several tests, I conclude that the problem is that "tr: eq (nid)" does not accept the nid as variable, because when changing the nid by a specific integer, for example 1, it works, adding id to select. The question here is how to put the nid as a parameter in the: eq () so that it works correctly and do what I have explained ????
The same situation happens in the following line of code:
$(document).on('change', '.cmb_arboles', function () {
var $select = $(this);
var $row = $select.closest('tr');
var idd = $row.attr('id');
var valor=$("#tabla tbody tr[id=idd]").find("td:eq(0)").find("select").val();
});
Of lines 1 to 3, you get the number of the row in which you have selected in the select component.
The last line gets the value of the select that was selected, with the information of the row number where the selection was made, but this does not work. When doing several tests, I conclude that the problem is in "tr [id = idd]", which does not correctly process the variable "idd". I made the test of changing the idd by a specific integer, for example 1 and then I generate a new line in the table with id = 1 and the line of code works correctly, returning the option that was selected in the select element.
With these two examples, I want to check if someone can tell me how to place the parameters I mentioned in the two cases, so that the functionality is executed correctly and does what is expected.
I will be enormously grateful.
the issue is you have to give
("#plantilla tbody tr:eq(nid)" as (("#plantilla tbody tr:eq('"+nid+"')"
I have created a fiddle. check it out. I didn't use jquery for the same.
<style>
#template {
display: none;
}
</style>
<table><tbody id="template">
<tr class="plantilla">
<td>
<select class="cmb_arboles" id="cmb_arboles" name="arboles[]">
</select>
</td>
<td>
<input type="text" id="txttoneladas" name="txttoneladas[]" />
</td>
<td>
<input type="text" id="txtprecio" name="txtprecio[]" />
</td>
<td>
<select id="cmb_destino" name="destino[]">
</select>
</td>
<td class="eliminar_fila">Eliminar</td>
</tr></tbody>
</table>
<input type="button" id="agregar" value="Add">
<table>
<tbody id="plantilla"></tbody>
</table>
<script>
var nid = -1;
document.getElementById('agregar').onclick = function(){
var table = document.getElementById('plantilla');
var newRow = document.getElementById('template').innerHTML;
nid++;
newRow = newRow.replace('id="cmb_arboles"', 'id="cmb_arboles_'+nid+'"');
newRow.replace('id="cmb_arboles"', 'id="cmb_arboles_'+nid+'"');
table.innerHTML += newRow;
}
</script>
https://jsfiddle.net/nugee3s6/
You are hard coding the id value in $("#tabla tbody tr[id=idd]") not using the variable above it
If you wanted to use the variable it would be:
$("#tabla tbody tr[id=" +idd +"]")
But it makes no sense to use the ID to search again for the same row since you already have that row element as $row
So change to:
$(document).on('change', '.cmb_arboles', function () {
var $select = $(this);
var $row = $select.closest('tr');
var valor=$row.find("td:eq(0) select").val();
});
Then don't worry about using ID's, you don't need them
I am trying to get the value of a hidden input inside a tag in html table element through javascript in a MVC view. i have get the respective value of the hidden input which is in a loop,when the the respective row is clicked. I have tried many codes but it returns the value of the first row alone for all the rows in the table. i tried the following:
#foreach (var item in Model)
{
<tr>
<td hidden><input value="#item.QuoteId" id="QuoteID" class="QuoteID"> </td>
</tr>
}
javascript:
$("tr").click(function () {
var quoteid=document.getElementById("#QuoteID").innerHTML
alert(quoteid);
alert($('.QuoteID').val());
}
if my db contains 3 values for quote,say 12,17,18.. it alerts 12 for all the row clicks.. Pls help,I am literally stuck. I have been trying it from 3 days,i cant figure it out. I guess it is some simple mistake from my side. Pls help. I am not able to finish the work assigned to me because of this simple error.
You're using the same id multiple times. The ID has to be unique!! To make this to work you could call the unique id, or put a onclick on the specific row and call your function with this. In your function you can use this.value.
<script>
function ShowMeThePower(myElement) {
alert(myElement.innerHTML);
}
</script>
<div onclick="ShowMeThePower(this);">This is great!</div>
http://jsfiddle.net/3RJVd/
Edit:
To satisfy the OP:
<table>
<tr>
<td><input type="text" id="show1" value="test1" /></td>
</tr>
<tr>
<td><input type="text" id="show2" value="test2" /></td>
</tr>
</table>
<script>
for (var i = 1; i < 3; i++){
alert(document.getElementById('show' + i).value);
}
</script>
If you see, it's the same logic. Just be sure to use unique id's.
http://jsfiddle.net/4gMy6/
I have a table with rows and input/select form elements. At the bottom row i have a button to add a new row to the Table. Initially the table is empty with just one row with a button
Like this:
<form name="test" id="test" action="#" >
<table id="matrix">
<tr id="1">
<td><select class="parent" name="parent">
<option value="C" label="C">C</option>
<option selected="selected" value="P" label="P">P</option>
<option value="B" label="B">B</option>
</select></td>
<td><div id="my_data_1">
<span title="parent_val"></span>
</div></td>
<td> </td>
</tr>
<tr >
<td colspan="3"><input type="button" class="add_new" /></td>
</tr>
</table>
</form>
Now when i click on the button with the add_new class i clone the first row, increment its id and then insert it above the last row.
The issue is that i have an onchange event attached to the select with class parent as
$('#matrix').on('change', 'select.parent_type', function() {
var RowID = $(this).closest('tr').attr('id');
var attributes_div = $('#matrix tr#'+RowID).find('div#my_data'+RowID );
new_id = GetParentIDFormat(attributes_div, 3);
$(attributes_div +"span[title='parent_val']").html(new_id);
});
When i added two or more rows, the change function changes the Value for SPAN "parent_val" for ALL the rows rather than the specific row whose SELECT parent was changed.
There were a few errors, without the GetParentIDFormat function, I cannot provide a 100% solution, but here goes:
'select.parent_type' should be 'select.parent'
$('#matrix tr#'+RowID).find('div#my_data'); should be
$('#' + RowID).find('.my_data');.
Note that you require classes, as you cannot have multiple equivalent IDs.
$(attributes_div +"span[title='parent_val']")
Should be
$("span[title='parent_val']", attributes_div)
Resulting in:
$('#matrix').on('change', 'select.parent', function() {
var RowID = $(this).closest('tr').attr('id');
var attributes_div = $('#' + RowID).find('.my_data');
var new_id = GetParentIDFormat(attributes_div, 3);
$("span[title='parent_val']", attributes_div).html(new_id);
});
The attributes_div variable points to a jQuery object, so you can't concatenate that with a string to get a selector to select the element you want. Instead just do this:
attributes_div.find('span[title="parent_val"]').html(new_id);
That will look for the <span title="parent_val"> element inside of the specific <div> referenced by attributes_div, and therefore should be the single element you want.
However, note that if you're cloning that row, you can't use an ID of my_data on all of the <div> elements as they're supposed to be unique; consider changing to a class instead.
I have a tricky situation where I need to duplicate a table row, and then alter the names of the inputs to a very specific format. The inputs are named as follows:
data[ProjectRequirement][0][description]
data[ProjectRequirement][0][qty]
...
Now, when the above row is duplicated, the inputs need to be named as follows:
data[ProjectRequirement][1][description]
data[ProjectRequirement][1][qty]
...
And so the pattern must continue. Duplicating the row is not a problem, and I have used the following method:
$j(\'table.WfTable tr\').live(\'mousedown\', function(e){
if($j(e.target).hasClass(\'add\')){
var clone = $j(e.target).parents(\'tr\').clone();
$j(\'table.WfTable\').find(\'tbody\').append($j(clone));
// NOW I WANT TO DO THE INPUT NAME CHANGE
};
});
Ignore the escaped quotes, the JS is output via PHP. So at present, the row is duplicated and the names are the same. Is there a method whereby once duplicated, I can say:
"get the name of each input in the row, look for a field like [0] or [1] etc and change that value to the value of the rows index number in the table DOM element (ie row 1 is index 0, 2 is index 1...)?"
I can only assume that row 1 of table is at index 0 in the DOM tree of that table, and therefore think there must be a way to use that index data to apply to the input names?
Any help is much appreciated.
Simon
EDIT: Here is one table row, created dynamically (cakePHP view)
<tr class="repeat">
<td valign="top" style="width:250px;padding:10px 10px 10px 0;"><input type="hidden" name="data[ProjectRequirement][1][project_id]" value="1" id="ProjectRequirement1ProjectId"><input type="hidden" name="data[ProjectRequirement][1][id]" value="2" id="ProjectRequirement1Id"><div class="input text"><input name="data[ProjectRequirement][1][resource]" style="width:240px;" maxlength="40" type="text" value="Teachers" id="ProjectRequirement1Resource"></div></td>
<td valign="top" style="padding:10px 0;"><div class="input text"><input name="data[ProjectRequirement][1][description]" type="text" value="Any volunteer (part time) teachers" id="ProjectRequirement1Description"></div></td>
<td valign="top" style="width:150px;padding:10px 0;"><input name="data[ProjectRequirement][1][qty]" style="width:70px;float:left;clear:none;" maxlength="10" type="text" value="20+" id="ProjectRequirement1Qty"> <img src="/trusthau.net/img/buttons/btn_plus.png" style="float:right;clear:none;margin:10px 0 0 0;" class="add" alt=""></td>
</tr>
Something like this:
$().ready(function(){
$('#table tr.repeat:last').clone().appendTo('#table');
$('#table tr.repeat:last td input').each(function(){
var input = $(this),
name = input.attr('name');
name = name.replace(/(\d+)/, function(i) {
return ++i;
});
input.attr('name', name);
})
});
http://jsfiddle.net/ZFNDD/4/
Can you use last(jQuery('selector').last()) function in the jQuery code which would give you the last row every time.This would give you the appended row and then you can alter the input values by first collecting the number of rows present in the table.
I'm considering that there is going to be duplication of each and every row