I'm writing some JavaScript to clone a table row containing form elements.
It's working well so far but there's one piece I can't quite figure out.
The element names have a number which increases with every row.
E.g:
<table>
<tbody>
<tr>
<td><input type="text" name="name[0][abc]" /></td>
<td><button class="add-row-button">+</button></td>
</tr>
<tr>
<td><input type="text" name="name[1][abc]" /></td>
<td><button class="add-row-button">+</button></td>
</tr>
</tbody>
</table>
I need the cloned row to update the number. There are multiple fields in each row which need this updated number so I can't just include the new name in the jQuery code. What I think has to happen is I need get the name, use a regex replace, then update the attribute.
Here's my current (simplified for the example) jQuery:
// Current num of elements. Names are 0 based so this will be the number used
// for the new name.
var formRowCount = $('table tr').length;
$('.add-row-button').click(function() {
// Clone the last row.
$(this).closest('tr').last().clone().insertAfter($(this).closest('tr'));
// Set the new field selector.
var $newRow = $(this).closest('tr').next();
$newRow.find('input[type="text"]').val('');
formRowCount++;
});
Can someone point me in the right direction. Before formRowCount++; I need to get the current element name and update the number with formRowCount.
Yeah, you can use regex if you want.
var formRowCount = $('table tr').length;
$('.add-row-button').click(function() {
// Clone the last row and insert it.
$(this).closest('tr').last().clone().insertAfter($(this).closest('tr'));
// Select the input field
var $newInput = $(this).closest('tr').next().find('input[type="text"]');
// Update the input value and name attribute
var newName = $newInput.attr('name').replace(/^(name\[)\d+(\].+)$/, '$1' + formRowCount + '$2');
$newInput.val('').attr('name', newName);
// Update the number
formRowCount++;
});
Related
With the code below, I don't seem to be able to just set the textbox to the value of an TD element. What I need to achieve is to populate Enter Refund Amount box with the already present value of Grand Total field above. Nothing else is needed except copying the content from one element to the other.
window.onload = function() {
var src = document.getElementById("grand_total").innerHTML;
dst = document.getElementById("refund_amount").innerHTML;
src.addEventListener('#refund_amount', function() {
dst = src;
});
};
Firstly, #refund_amount isn't a valid event name. Given the context of the code and your goal I would assume that should be click instead. You also need to bind the event handler on the Element reference, not the a string variable containing its innerHTML value. In addition, to set the value of an input element you need to use the value property of the Element directly. Try this:
var src = document.getElementById("grand_total");
var dst = document.getElementById("refund_amount");
src.addEventListener('click', function() {
dst.value = src.textContent;
});
<table>
<tbody>
<tr>
<td>Grand total:</td>
<td id="grand_total">26.58</td>
</tr>
<tr>
<td>Refund amount:</td>
<td><input type="text" id="refund_amount" /></td>
</tr>
</tbody>
</table>
I've a PHP file which is a view (so mainly HTML) composed of several tables.
When the user click on one of the button, I want that the variables that are into my cells (and into the correct table) are sent to a Table in my Database.
To do this i'll use AJAX later, but at the moment i've a problem using JS/Jquery.
So I did something like this :
$('.boutton').click(function(){
$(?).find('td input').each(function(){
console.log($(this));
console.log($(this).val());
var iValue = $(this).val();
var sAllId = $(this).attr('id');
var sName = $(this).attr('name')
});
});
My table and buttons are into a div which has as id "table" + the number of the table.
I don't know what to do since I want this to work on every table, and on every button. It has to select only the td input that is into the table where the button was clicked.
My HTML is into a variable $sHtml since everything in this table are made of datas (in my DB) but it should be something like this :
<table id = "domaine-1-south">
<tr>
<th>BlaBla</th> // Several times
</tr>
<tr>
<td>Blabla</td>
<td><input id = "1#1#1#" name="high"></td>
<td><input id = "1#1#1#" name="mid"></td>
<td><input id = "1#1#1#" name="low"></td>
</tr>
<tr>
<td>Blabla</td>
<td><input id = "1#1#2#" name="high"></td>
<td><input id = "1#1#2#" name="mid"></td>
<td><input id = "1#1#2#" name="low"></td>
</tr>
For the id 1#1#1# the last 1 is for the number of the line and the second one is for in which table I'm.
You could use "start with" selector ^= to select all tables that have an id start with table :
$('[id^="table"]').find('td input').each(function(){
But in your OP you want to select the specific table related with the clicked button .boutton, so i guess that you have this button inside the table so you could select the current table using :
$(this).closest('table[id^="table"]').find('td input').each(function(){
Hope this helps.
I've got a strange question. We have buttons that have data attributes with an id in it. [v1, v2 and v3].
<table id="table-1" data-car-id="v1">
<tr><td>Header1</td></tr>
<tr><td>Content1 <input type="text" name="car[v1][marked][12]" /></td></tr>
<tr><td>Footer</td></tr>
</table>
<button id="copy-2" data-car-id="v2">Copy Table</button>
<table id="table-2">
</table>
<button id="copy-3" data-car-id="v3">Copy Table</button>
<table id="table-3">
</table>
A little piece of Javascript copies the body of the above table to closest next one. (That works).
$("button[id^='copy']").click(function() {
var $carId = $(this).attr('data-car-id');
alert($carId);
var $prevTable = $(this).prev("table[id^='table-']").prop('innerHTML');
var $nextTable = $(this).next("table").html($prevTable);
});
But now the tricky part, the input name of all inputs in that tbody should be replace. While the market should remain unchanged
car[v1][marked][12] => car[v2][marked][12]
How can I do that? Make it yourself easy and use the JSFiddle I created: https://jsfiddle.net/ra35z8ff/
After copying the HTML over to the next table element, select all the children input elements and iterate over them. Use the .replace() method to replace the previous table element's data-car-id attribute with the current button element's data-car-id attribute.
Updated Example
$("button[id^='copy']").on('click', function () {
var id = $(this).attr('data-car-id'),
previousId = $(this).prev('button').attr('data-car-id');
html = $(this).prev("table[id^='table-']").prop('innerHTML');
$(this).next("table").html(html).find('input').each(function () {
this.name = this.name.replace(previousId, id);
});
});
I have a table which has input checkboxes.
When user selects checkbox I'm saving this value attribute to an array...so the user is clicking, checking and unchecking and after some time he will press the button.
In the button click event I'm trying to iterate through each of the records and check if the each input[type="checkbox"] has the same value as the one in the array, so if the values are the same then I will read all the td values from that row.
This is my code:
$('#something').click(function(){
$( "tr td input" ).each(function(index) {
//selected is an array which has values collected from the checked checkboxes..for example [2,3]
for(var i=0;i<selected.length;i++)
{
if($(this).val()==selected[i][0].value)
{
alert($('tr').eq(index).find('td').eq(1).text());
}
}
});
});
And html code:
<table>
<tbody>
<tr>
<td><input type="checkbox" value="on"></td>
<td>ID</td>
<td>Name</td>
</tr>
<tr>
<td><input type="checkbox" value="0"></td>
<td>1</td>
<td>John</td>
</tr>
<tr>
<td><input type="checkbox" value="1"></td>
<td>2</td>
<td>Steve</td>
</tr>
</tbody>
</table>
So for example if I have value [1] in the array. How can I get all the row information from that? My code is not working. Any idea?
I created a plunk that iterates over each input, reads the values and writes them to an array:
var checkBoxCollection = new Array();
var cb = {};
$("button").click(function(){
$("input").each(function(index, el){
id = $(el).attr("id");
val = $(el).val();
isChecked = $(el).is(':checked');
console.log(index, id, val);
checkBoxCollection.push({'id': id, 'val': val, 'isChecked': isChecked});
}); // each
console.log(checkBoxCollection);
}); // button.click
You could use this way to select the cell value as soon as the button is clicked and would only have to test if the box was checked. To learn how to use the console and the chrome dev tools you may take a look at this 7 minute video
Update with one checkbox for all
In my updated plunk you can see that i use two different selectors
// using different selector - see my comment and tell me if you can not do that
Select all <input class="cbAll" type="checkbox" id="cbAll" value="on">
// and each checkbox like this
<input class="cb" type="checkbox" id="cb0" value="0">
And the javascript
$("input.cbAll").click(function(){
$("input.cb").each(function(index, el){
// javascript ternary operator is optional this switches each checked state
$(el).is(':checked')
? $(el).prop('checked', false)
: $(el).prop('checked', true);
}); // each
});
Update including the copy of the text inside the <td>
In this plunk the text from the cells in the same tablerow of the checbox is copied into the array. The relevant code are these lines
isChecked = $(el).is(':checked');
if(isChecked){
var cells = $(el).parent().parent().children();
var cellId = cells.eq(1).text();
var cellName = cells.eq(2).text();
checkBoxCollection.push({'id': id, 'val': val
, 'isChecked': isChecked
, 'cellId': cellId
, 'cellName': cellName});
console.log(index, id, val, cellId, cellName);
}
In the screenshot you can see that the values of each checked textbox are copied.
As far as i can tell i solved all your questions:
use of jquery each to iterate over checkboxes
copy the text of cells within a tablerow into an array if the checkbox of that row is checked
If i understood your questions not fully please clarify what you would like to know.
It appears that the condition if($(this).val()==selected[i][0].value) is not true.
If it is a simple array, you don't need .value in the end. Simply compare with selected[i][0]
if($(this).val()==selected[i][0])
My html
<tr id="uniqueRowId">
<td>
<input class="myChk" type="checkbox" />
</td>
<td class="from">
<textarea class="fromInput" ...></textarea>
</td>
<td class="to">
<textarea ...></textarea>
</td>
</tr>
I have a table where each row is similar to the above with only one exception: not all rows will have textreas. I need to grab all rows that have textareas AND checkbox is not "checked".
Then I need to leaf through them and do some stuff.
I tried something like:
var editableRows = $("td.from .fromInput");
for (s in editableRows)
{
$s.val("test value");
}
but it didn't work.
1) how do I grab ONLY the rows that have checkboxes off AND have fromInput textareas?
2) how do I leaf through them and access the val() of both textareas?
I am sure this could be optimized, but I think it will work.
$("tr:not(:has(:checked))").each(function(i, tr) {
var from = $(tr).find("td.from textarea").val();
var to = $(tr).find("td.to textarea").val();
//now do something with "from" and "to"
});
See it working on jsFiddle: http://jsfiddle.net/RRPqb/
You can use this to select the rows:
$('tr', '#yourTable').has('input:checkbox:not(:checked)').has('textarea')
Live demo: http://jsfiddle.net/simevidas/Zk5EH/1/
As you can see in the demo, only the row that has a TEXTAREA element and a unchecked checkbox will be selected.
However, I recommend you to set classes to your rows: the TR elements that contain TEXTAREA elements should have a specific class set - like "directions". Then you could select those rows easily like so:
$('tr.directions', '#yourTable').each(function() {
if ( $(this).find('input:checkbox')[0].checked ) return;
// do your thing
});
$("tr:not(:has(:checked)):has(input.fromInput)")
Should be what you need. All the rows that don't have anything checked but that do have an input with the class 'fromInput'
If you want to loop through them to get the value of any textarea just extend your selector:
$("tr:not(:has(:checked)):has(textarea.fromInput) textarea")
Or as above if you want to be able to distinguish them:
$("tr:not(:has(:checked)):has(textarea.fromInput)")
.each(function() {
var from = $(this).find("td.from textarea").val();
var to = $(this).find("td.to textarea").val();
})
I don't know how much performance is a concern here, but if it is, then rather then writing a selector to find rows that contain a textarea you may find it helps to add a class to the row itself.
<tr class="hasTextarea">
Then you could alter your JQuery as so:
$("tr.hasTextarea:not(:has(:checked))")