This question already has answers here:
contenteditable change events
(21 answers)
Closed 6 years ago.
I am trying to show to alert When a row of my table is modified but esta not work. Here my code . Thanks!
$(document).ready(function(){
$("#table").change(function(){
alert("The text has been changed.");
});
});
<table border="3" id='table' >
<thead>
<tr>Heading 1</tr>
<tr>Heading 2</tr>
</thead>
<tbody>
<tr>
<td contenteditable='true' id='bebe'>a</td>
<td contenteditable='true'>a</td>
</tr>
<tr>
<td contenteditable='true'>a</td>
<td contenteditable='true'>a</td>
</tr>
</tbody>
</table>
UPDATED
This is when you want to check whenever the user pres a key in their keyboard
$(document).ready(function(){
var val1;
var val;
$("#table tbody tr td").on('keypress',function(){
val = $(this).text();
//alert(val);
});
$("#table tbody tr td").keyup(function(){
val1 = $(this).text();
if(val1!=val){
alert("text has changed");
}
});
});
This is if you want to trigger only when user leaves the box
$(document).ready(function(){
var val1;
var val;
$("#table tbody tr td").on('focus',function(){
val = $(this).text();
//alert(val);
});
$("#table tbody tr td").focusout(function(){
val1 = $(this).text();
if(val1!=val){
alert("text has changed");
}
});
});
Related
I have a function in which I take the first TR of my table and then I take all the TD of this TR.
Now I need to modify this function: when I take the first TR I need to check that if all the TD of my TR have the class 'HD1' I need to take the second TR of the table.
I put my function below. Thanks in advance.
function getColumnsIdx(id) {
var header = $("table#" + id + " thead tr:eq(1)");
var header_fields = $("td", header);
var header_idx = new Object();
header_fields.each(function(idx, val) {
var $$ = $(val);
var key = $$.text();
header_idx[key] = idx;
});
return header_idx;
}
You can look for the first td without that class, and then take its parent:
var header = $("table#" + id + " thead tr td:not(.HD1):eq(0)").parent();
This could, however, result in getting the third/fourth/etc row. If you must always return the second row, even if those cells also all have the HD1 class:
var header = $("table#" + id + " thead tr:eq(0)");
var header_fields = $("td", header);
if (header_fields.length && header_fields.length == header_fields.filter(".HD1").length) {
header = header.next();
header_fields = $("td", header);
}
Note: :eq() uses a zero-based index, so use eq(0) to select the first element.
You can check if the first row contains only class="HD1" elements by comparing the length of that selector to the length of the <td> elements in general.
If they're the same length (all of the <td> are HD1) - use the second row. Otherwise, use the first.
With HD1:
let $row = $("thead tr:first > .HD1").length === $("thead tr:first > td").length
? $("table tr").eq(1)
: $("table tr").first();
$row.css("color", "red");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td class="HD1">1</td>
<td class="HD1">2</td>
<td class="HD1">3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</table>
Without HD1:
let $row = $("thead tr:first > .HD1").length === $("thead tr:first > td").length
? $("table tr").eq(1)
: $("table tr").first();
$row.css("color", "red");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
</table>
After receiving the data via JSON and add content on a table, was used the event delegation to capture the links of this content, but when you click the link that was created dynamically want to access the prev () the tr element containing the data-id. But this is me returning undef. Can someone help me? The prev() is being called by editarComercial()
Javascript:
$(document).ready(function(){
function editarComercial(trthis) {
alert($(trthis).prev().prev().data('id'));
}
function listaComercial(){
url = BASE_URL + 'comercial/ajaxrequest/listagem';
$.getJSON(url,function(data){
var trs = [];
$.each(data,function (key){
tr = "<tr data-id=\""+data[key].id+"\">";
tr += "<td>"+data[key].nome+"</td>";
tr += "<td>Editar";
tr += "Excluir</td>";
tr += "</tr>";
trs.push(tr);
});
$("<tbody/>",{
html: trs.join("")
}).appendTo("#listagemComercial");
});
}
$(document).on('click','a.edit-comercial',function(){
editarComercial(this);
});
listaComercial();
});
HTML:
<div id="content">
<table id="listagemComercial">
<thead>
<tr>
<th>Nome</th>
<th>Ações</th>
</tr>
</thead>
</table>
</div>
.edit-comercial doesn't have a previous element, it's the first element in the TD.
You probably wanted closest() instead, to traverse up to the row
function editarComercial(trthis) {
alert( $(trthis).closest('tr').data('id') );
}
I have a html table with 4 columns and multiple rows
column1 : simple text
column2 : simple text
column3 : select list with 2 values
column4 : Button that performs some operation
At run time, I want to get the selected / entered values for all the columns of that row against which column4 button is clicked. I know a little of JavaScript/jQuery.
Here is the static table code
<table id="invoiceTbl" border="1">
<thead>
<tr>
<th>Broker info</th>
<th>Receivable Amount</th>
<<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody></tbody>
</table>
And I am populating table i.e. inserting data on AJAX call like this:
$.ajax({
type: "POST",
data: $('#searchDetails').serialize(),
async: false,
cache: false,
url: "/opsadmin/search.json",
dataType: 'json',
success: function (result) {
var i = 1;
$.each(result, function (index, value) {
alert(index + ": " + value.brokerInfo);
$('table#invoiceTbl TBODY').append('<tr> <td>' + i + '</td><td>' + value.brokerInfo + '</td><td>' + value.receivableAmount + '</td><td><select name="act" id="s"><option>PENDING</option><option>CLEARED</option></select></td><td><input type="button" value="Process" onclick="updateStatus(\'' + index + '\')"</input></td></tr>');
i++;
});
}
});
return false;
First set the unique ID to each of your "select" with help of index like:
'<select name="act" id="s'+ index +'">'
and pass the index with "updateStatus(index)" function call.
function updateStatus(index) {
$('#s'+index).val(); // value of selected box.
}
$("#invoiceTbl input[type=button]").click(function(e){
$(e.target).closest("tr").find("td").slice(0,2).each(function(){
console.log($(this).text());
});
});
On #button click you will get an array (arr) that holds the values of the clicked row cells:
$('#button').on('click', function() {
var arr = [];
$(this).closest('tr').find('td').each(function() {
var that = $(this);
if (that.find('input[type="text"]').length > 0) {
arr.push(that.find('input[type="text"]').val());
} else if (that.find('select').length > 0) {
arr.push(that.find('select').val());
} else {
arr.push(that.text());
}
});
alert(arr);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>text</td>
<td>text2</td>
<td>
<select>
<option value="opt1">opt1</option>
<option value="opt2">opt2</option>
<option value="opt3">opt3</option>
</select>
</td>
<td><button id="button">Click</button></td>
</tr>
</tbody>
</table>
There's already a few good answers, but my solution is a bit different:
$("#invoiceTbl tr").each(function(){
var select = $(this).find("select");
var button = $(this).find("button");
button.click(function(){
alert(select.val());
});
});
If you also want the content of the other columns, that's a bit more difficult:
$("#invoiceTbl tr").each(function(){
var tr = $(this);
var button = $(this).find("button");
button.click(function(){
tr.find("td").each(function(){
var select = $(this).find("select");
var td_button = $(this).find("button");
if(!td_button.length)
{
if(select.length)
console.log(select.val());
else
console.log($(this).text());
}
});
});
});
Check out https://jsfiddle.net/cgfjewoe/ to see it run.
I have a table hooked up to the jQuery datatable. Based on this example I want to add "hidden" child rows to show extra information.
I have the following jsfiddle where I have a name/value pair.
<tr data-child-name="Name1" data-child-value="Value 1">
<td class="details-control"></td>
function format ( name, value ) {
return '<div>' + name + ': '+ value + '</div>';
}
$(document).ready(function () {
var table = $('#example').DataTable({});
// Add event listener for opening and closing details
$('#example').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
} else {
// Open this row
row.child( format(tr.data('child-name'), tr.data('child-value') )).show();
tr.addClass('shown');
}
});
});
My question is how do I add more than one name/value pair? So that I can define various rows like in the datatables.net example.
My source is a php-script that generates html like in the jsfiddle example.
It's probably an easy task but my jQuery skills are very limited :-)
Thank you.
UPDATE:
The data comes from an ldap query:
$ldapResults[$i]
echo "<td>" . utf8_encode($ldapResults[$i]['sn'][0]) . "</td>"
If you want to keep data attributes for your data source, you can do something like this
function format ( dataSource ) {
var html = '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">';
for (var key in dataSource){
html += '<tr>'+
'<td>' + key +'</td>'+
'<td>' + dataSource[key] +'</td>'+
'</tr>';
}
return html += '</table>';
}
$(function () {
var table = $('#example').DataTable({});
// Add event listener for opening and closing details
$('#example').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
} else {
// Open this row
row.child(format({
'Key 1' : tr.data('key-1'),
'Key 2' : tr.data('key-2')
})).show();
tr.addClass('shown');
}
});
});
td.details-control {
background: url('http://www.datatables.net/examples/resources/details_open.png') no-repeat center center;
cursor: pointer;
}
tr.shown td.details-control {
background: url('http://www.datatables.net/examples/resources/details_close.png') no-repeat center center;
}
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://cdn.datatables.net/responsive/1.0.1/js/dataTables.responsive.min.js"></script>
<script src="http://cdn.datatables.net/1.10.2/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" href="http://cdn.datatables.net/1.10.2/css/jquery.dataTables.css" />
<table id="example" class="display nowrap" cellspacing="0" width="100%">
<thead>
<tr>
<th></th>
<th>Item 1</th>
<th>Item 2</th>
<th>Item 3</th>
<th>Item 4</th>
</tr>
</thead>
<tbody>
<tr data-key-1="Value 1" data-key-2="Value 2">
<td class="details-control"></td>
<td>data 1a</td>
<td>data 1b</td>
<td>data 1c</td>
<td>data 1d</td>
</tr>
<tr data-key-1="Value 1" data-key-2="Value 2">
<td class="details-control"></td>
<td>data 2a</td>
<td>data 2b</td>
<td>data 2c</td>
<td>data 2d</td>
</tr>
</tbody>
</table>
You can create an array of the data you need to show for each row
EG :
var data = [
{ key1 :'value1', key2 :'value2', key3 :'value3'}, //Row1
{ key1 :'value1', key2 :'value2'} //Row2
];
And updated the format()
function format (index ) {
var json_data = data[parseInt(index)];
var op = '';
$.each(json_data, function(key, value){
op +='<div>' + key + ': '+ value + '</div>';
});
return op;
}
Now just add the index of the array in a custom attribute <tr data-child-index="1">
And finally row.child(format(tr.data('child-index'))).show();
EDIT : No html changes needed.
Calculate the index dynamically using jQuery index()
row.child(format($('#example td.details-control').index($(this)))).show();
DEMO
If are are getting json data to show as child then try it like,
else {
// Open this row
// pass your json data to show in details
row.child( format(myJsonData)).show();
tr.addClass('shown');
}
And in the format function change it like,
function format ( json ) {
var $json=$.parseJSON(json);// if not parsed
var str='';
$json.each(function(key,value){
str += '<div>'+key+':'+value+'</div>';
});
return str;
}
I have a question about dynamic tr with keep the content of td.
I have a table like flowing code:
<table id="map2">
<tr>
<td class="15c">15</td>
<td class="16c">16</td>
<td class="17c">17</td>
</tr>
<tr>
<td class="15c">15</td>
<td class="16c">16</td>
<td class="17c">17</td>
</tr>
</table>
I added some jQuery code that create a column dynamically. Like flowing code:
$('#map2').on('mouseenter', 'td:last-child', function(){
var tdClass = $(this).attr('class');
var newClass = parseInt(tdClass);
if(newClass <= 30) {
$(this).after('<td class="'+ (newClass+1) +'c">'+ (newClass+1) +'</td><td class="'+ (newClass+2) +'c">'+ (newClass+2) +'</td><td class="'+ (newClass+3) +'c">'+ (newClass+3) +'</td>');
} else {
alert('end!')
}
});
$('#map2').on('mouseenter', 'td:first-child', function(){
var tdClass = $(this).attr('class');
var newClass = parseInt(tdClass);
if(newClass >= 3) {
$(this).before('<td class="'+ (newClass-3) +'c">'+ (newClass-3) +'</td><td class="'+ (newClass-2) +'c">'+ (newClass-2) +'</td><td class="'+ (newClass-1) +'c">'+ (newClass-1) +'</td>');
} else {
alert('end!')
}
});
That code create a td for me, now I want to create a tr (row) with keep the content. For example when the new row was created, that had content like before td in before tr.
I tried some code like this:
$('#map2').on('mouseenter', 'tr:first-child', function(){
var trCont = $(this).html;
// $(this).before('<tr>'+ trCont +'</tr>');
$(this).before('<tr><td>new row</td></tr>');
});
but didn't work.
How can I solve this problem?
http://jsfiddle.net/H6MSS/2/