HTML editable Table -> get edited Fields - javascript

I have a HTML-Table
<table style="width:100%">
<tr>
<th>id</th>
<th>Lastname</th>
<th>Age</th>
</tr>
<tr>
<td>2</td>
<td contenteditable="true">Smith</td>
<td contenteditable="true">50</td>
</tr>
<tr>
<td>3</td>
<td contenteditable="true">Jackson</td>
<td contenteditable="true">94</td>
</tr>
</table>
(Just a TEST-Table)
It is editable, but how do I get all the rows (with ID) which were edited, to send them to a PHP-Backend which saves the changes to DB?
Thanks in advance,
Patrick.

You can save ids in an Array whenever field content is changed.
Here is the Working Example: https://jsfiddle.net/79egs9tc/
var idArr = [];
$(".edited").focusout(function() {
var id = $(this).parent().attr('id');
if($.inArray(id, idArr) === -1){
idArr.push(id);
}
console.log(idArr);
});
You can add check for content is changes or not.
Hope, it will work for you.

Related

How can I get only one column value from html table?

I have a html table that shows a list of users ID, Name and E-mail. When my user clicks in any row, I get the id number of that row and send to my backend. So, I did this:
//Making the table
var trs = document.getElementsByTagName('tr');
for (var i = 0; i < trs.length; i++) {
trs[i].onclick = clickHandler;
}
Function that handles the click:
function clickHandler(event) {
var numb = this.innerText.match(/\d/g);
numb = numb.join("");
window.location.replace("chooseParticipant.php?id="+numb);
}
Table Example:
<div id="table">
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>E-mail</th>
</tr>
</thead>
<tbody>
<td>7</td>
<td>Test User</td>
<td>testuser123#example.com</td>
</tbody>
</table>
</div>
What happens then? If an user have numbers in their e-mail, the "numb" variable gets these numbers too. I don't know how to filter only the id number. Did someone have any ideas?
You could assign a class to you tag.
Something like below:-
<td class="id">7</td>
And in the javascript code you could fetch all the elements with class "id".
And then perform your click handler on each one.
var trs = document.getElementsByClassName('id');
I hope this helps.
Try this code snippet which use data-* attribute
document.addEventListener('DOMContentLoaded', function(e) {
var trs = document.querySelectorAll('#table tbody tr');
var repeater = Array.prototype.slice;
repeater.call(trs).forEach(function(tr) {
tr.addEventListener('click', function(e) {
var data = tr.querySelector('td[data-id]').dataset;
console.log('id=', data.id);
});
});
});
tbody {
cursor: pointer;
}
<div id="table">
<table border="1" cellspacing="0" cellpadding="3">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>E-mail</th>
</tr>
</thead>
<tbody>
<tr>
<td data-id="7">7</td>
<td>Test User 1</td>
<td>testuser1231#gmail.com</td>
</tr>
<tr>
<td data-id="8">8</td>
<td>Test User 2</td>
<td>testuser1232#gmail.com</td>
</tr>
<tr>
<td data-id="9">9</td>
<td>Test User 3</td>
<td>testuser1233#gmail.com</td>
</tr>
</tbody>
</table>
</div>

nested ng-repeat with open particular index with respect to repeated data

Every time the toggle is clicked, all payments are getting replaced with new payments. My problem is how to maintain the payments of a particular index of every click and show at respective index. please help me out
here is my html
<tbody data-ng-repeat="invoice in relatedInvoices>
<tr>
<td class="td-bottom-border">
{{invoice.PayableCurrencyCode}} {{invoice.PayablePaidAmount | number: 2}}<br />
<small>
<a data-ng-click="isOpenPayablePayments[$index] = !isOpenPayablePayments[$index]; togglePayablePayments(invoice.PayableInvoiceId)">Paid</a>
</small>
</td>
</tr>
<tr data-ng-show="isOpenPayablePayments[$index]">
<td>
<table>
<thead>
<tr>
<th>Transaction Id</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="payment in payablePayments">
<td>{{payment.TransactionId}}</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
Here is my javascript
var getPayments = function (invoiceId) {
paymentService.getPayments(invoiceId).then(function (paymentsResponse) {
return paymentsResponse.data;
});
};
$scope.togglePayablePayments = function(invoiceId) {
$scope.payablePayments = getPayments(invoiceId);
};
If I understood correctly, you want to have "payablePayments" for every invoice.
This is working: http://plnkr.co/edit/cj3jxZ?p=info
Try something like
// init at beginning
$scope.payablePayments = [];
$scope.togglePayablePayments = function(invoiceId) {
$scope.payablePayments[invoiceId] = getPayments(invoiceId);
};
and then
<tr data-ng-repeat="payment in payablePayments[invoice.PayableInvoiceId]">
Otherwise you overwrite the object for the preceding invoice.

find child table selector from parent table - jQuery

I have a table structure like this. Fairly simple one.
<table id="myTable" class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>Doe</td>
<td>john#example.com</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>mary#example.com</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#example.com</td>
</tr>
</tbody>
</table>
At runtime I am binding a new row to this table for a particular rowclick. This new row contains a new table.
Now on clicking the row again, I want to be able to remove the newly added row(the new table).
I am using bootstrap table.
Here is what I have tried so far.
$('#myTable').on('click-row.bs.table', function (e, row, $element) {
//if ($element.has('#newlyAddedTable').length) { ....// did not work
if ($('#myTable').has('#newlyAddedTable').length) { // this removes the table on any row click. Not what I intend to do
{
$("#newlyAddedTable").remove();
} else {
// some operation...
}
}
I want to be able to remove the newly added table on the row it was created.
Just more explanation based on the Answers below:
<tr> ----------> if i click this
<td>
<table id="newlyAddedTable"> ---------> this is added
</table>
</td>
</tr>
<tr> ----------> if i again click this or maybe any other row in the table
<td>
<table id="newlyAddedTable"> ---------> this is removed
</table>
</td>
</tr>
Update: from OP's comment below it sounds like the best way to implement the new table is to use a class selector and not an id selector. The code below has been updated accordingly. ***Where previously there was an id for newTable there is a class ---> #newTable ===> .newTable:
Just change:
$('#myTable').has('#newlyAddedTable').length
To:
$('.newlyAddedTable', $element).length //element === clicked row -- see demo
vvvvv DEMO vvvvv
$('#myTable').bootstrapTable().on('click-row.bs.table', function(e, row, $element) {
if( $('.newTable', $element).length ) {
$('.newTable', $element).remove();
} else {
$('td:first', $element)
.append( '<table class="newTable"><tr><td>NEW TABLE</td></tr></table>' );
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.7.0/bootstrap-table.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.7.0/bootstrap-table.min.css" rel="stylesheet"/>
<table id="myTable" class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>Doe</td>
<td>john#example.com</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>mary#example.com</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#example.com</td>
</tr>
</tbody>
</table>
Try replacing your remove code with this:
$(document).on("click", "#newlyAddedTable", function(){
$(this).remove();
});
The code above registers a click listener on the document. The second parameter filters those events for those with the target #newlyAddedTable. This way you don't have to register a new click handler every time you insert a row (as in #VimalanJayaGanesh's solution).
P.S. If you are adding HTML that looks like this:
<tr>
<td>
<table id="newlyAddedTable">
</table>
</td>
</tr>
Then you are probably actually wanting to remove the parent tr (not the table with the id). There are two ways to fix this.
You can change the selector that filters click events and so have the tr handle the click rather than the table element in my example code:
$(document).on("click", "tr:has(#newlyAddedTable)", function(){
You can leave the selector as is but grab the parent tr from the table and remove that changing the remove line above to:
$(this).parents("tr").first().remove()
or
$(this).parent().parent().remove()
As I don't have your complete code / fiddler, here is a possible solution.
Are you looking for something like this?
$('#add').on('click', function()
{
var newRow = '<tr CLASS="newrow"><td colspan="3"><table><tr><td>Test</td><td>User</td><td>test#example.com</td></table></td></tr>'
$('#myTableBody').append(newRow);
Remove()
});
function Remove()
{
$('.newrow').off('click').on('click', function()
{
$(this).remove();
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="myTable" class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
</tr>
</thead>
<tbody id="myTableBody">
<tr>
<td>John</td>
<td>Doe</td>
<td>john#example.com</td>
</tr>
<tr>
<td>Mary</td>
<td>Moe</td>
<td>mary#example.com</td>
</tr>
<tr>
<td>July</td>
<td>Dooley</td>
<td>july#example.com</td>
</tr>
</tbody>
</table>
<button type='button' id='add'>Add</button>
Note:
The following line indicates that,
$('.newrow').off('click').on('click', function()
the click event will be binded to the new row only once.
The reason for adding 'off('click') is, when you are dynamically adding rows (with common class 'newrow') to the table, the events will be binded several times. To avoid that, remove the previously binded click event and add a new one.

Automatically filling out a form when clicking a table row with javascript/jquery

I have a dynamically generated table that looks like this
<table width="100%">
<tr>
<th>Client ID</th>
<th>Shortname</th>
<th>Client Name</th>
<th>Client Name 2</th>
</tr>
#foreach($clients as $client)
<tr>
<td>{{$client->customer_id}}</td>
<td>{{$client->shortname}}</td>
<td>{{$client->customer}}</td>
<td>{{$client->customer_row2}}</td>
</tr>
#endforeach
I would like to be able to click on a row, and automatically populate a form with the information in the table row.
I have thought of a solution that i think should work, but I haven't really got the JS skills to write the code.
This is what im thinking:
{{$row=1}}
<table width="100%">
<tr>
<th>Client ID</th>
<th>Shortname</th>
<th>Client Name</th>
<th>Client Name 2</th>
</tr>
#foreach($clients as $client)
<tr id="row{{$num}}">
<td class="clientId">{{$client->customer_id}}</td>
<td class="shortname">{{$client->shortname}}</td>
<td class="client">{{$client->customer}}</td>
<td class="clientRow2">{{$client->customer_row2}}</td>
</tr>
{{$row++}}
#endforeach
And here's some psuedo code to help you understand what im thinking:
onclick getElementById(.this)
input element with id clientId .put(this.#clientId)
input element with id shortname .put(this.#shortname)
input element with id client .put(this.#client)
input element with id clientRow2 .put(this.#clientRow2)
I hope that everybody understands what i'm trying to accomplish, and that someone is willing to help
Regards Johan
I ended up doing this:
<tr onclick="var td = $(this).find('td');
var row1 = td.eq(0).html();
var row2 = td.eq(1).html();
var row3 = td.eq(2).html();
var row4 = td.eq(3).html();
$('.input1').val(row1);
$('.input2').val(row2);
$('.input3').val(row3);
$('.input4').val(row4);">
on each table row, not very elegant, but it gets the job done

jQuery or JS transformation of dynamic HTML table

I need to find a TABLE within a DIV tag and perform modifications on the header. The available reporting tool does not allow to identify the generated table but allows script and DIV insertion.
Consider the table below where the header is the first line:
<div id="ScrollHeader">
<table>
<tr>
<td>Browser</td>
<td>Visits</td>
<td>Pages/Visit</td>
<td>Avg. Time on Site</td>
<td>% New Visits</td>
<td>Bounce Rate</td>
<td>Avg. Time on Site</td>
<td>% New Visits</td>
<td>Bounce Rate</td>
</tr>
<tr>
<td>Firefox first</td>
<td>1,990</td>
<td>3.11</td>
<td>00:04:22</td>
<td>70.00%</td>
<td>32.61%</td>
<td>00:04:22</td>
<td>70.00%</td>
<td>32.61%</td>
</tr>
<tr>
<td>Firefox</td>
<td>1,990</td>
<td>3.11</td>
<td>00:04:22 test test test</td>
<td>70.00%</td>
<td>32.61%</td>
<td>00:04:22</td>
<td>70.00%</td>
<td>32.61%</td>
</tr>
</table>
</div>
I need a JavaScript or jQuery code to transform the table to the following:
<div id="ScrollHeader">
<table>
<thead>
<tr>
<th>Browser</th>
<th>Visits</th>
<th>Pages/Visit</th>
<th>Avg. Time on Site</th>
<th>% New Visits</th>
<th>Bounce Rate</th>
<th>Avg. Time on Site</th>
<th>% New Visits</th>
<th>Bounce Rate</th>
</tr>
</thead>
<tr>
<td>Firefox first</td>
<td class="numeric">1,990</td>
<td class="numeric">3.11</td>
<td class="numeric">00:04:22</td>
<td class="numeric">70.00%</td>
<td class="numeric">32.61%</td>
<td class="numeric">00:04:22</td>
<td class="numeric">70.00%</td>
<td class="numeric">32.61%</td>
</tr>
</table>
</div>
The code needs to identify the table within <div id="ScrollHeader">, insert THEAD before the first TR, change the TD to TH in the first line and close it with </thead>.
I have tried using $("div p[id^='ScrollHeader']").length to find the DIV and $("tr:first") to perform <table>.prepend(document.createElement('thead')); without success.
Try this:
$('#ScrollHeader table tr:eq(0)').wrap('<thead />');
$('#ScrollHeader table tr:eq(0) td').each(function () {
$('#ScrollHeader table tr:eq(0)').append($('<th />').html($(this).html()));
$(this).remove();
});
$('#ScrollHeader tr:first')
.wrap('<thead />')
.children().each(function(){
text = $(this).text();
$(this).replaceWith('<th>'+text+'</th>');
});
$('#ScrollHeader thead').insertBefore('#ScrollHeader tbody');
you can see it working here

Categories

Resources