Fire event once on DOM change - javascript

I'm using the following jQuery:
$('table').bind("DOMSubtreeModified",function(){
myfunction();
});
The contents of the table are modified by another function. However, this triggers the above for every element in the table that is changed.
Is there a way to fire only once after all table-changes have been made?

Use .one() to register once for an event. In this Snippet click the button to add a <td> to table, thereby triggering the DOMSubtreeModified event only once. Note any further modifications to table do not trigger anything.
SNIPPET
$('button').click(function() {
$('table tr').append('<td>TEST</td>');
});
$('table').one("DOMSubtreeModified", function() {
alert('MODIFIED');
});
table,
td {
border: 1px solid black;
}
table {
width: 300px;
height: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td></td>
</tr>
</table>
<button>addTD</button>

Related

Whole table row clickable except the button with Javascript/jQuery

I have a simple table and I write some JS code in order to achieve that whole tr become a data-href. Everything works very nice except for one thing.
Now the whole row is clickable and that is fine, but there is a small issue, if you click on the delete button, it takes you to the update page (data-href), and I want to avoid that. So my question is how can I modify that code for the whole row to stay clickable except that delete button?
Here is my code:
$("tr").each(function() {
const $tr = $(this);
$tr.attr("data-href", $tr.find("a").attr("href"))
})
$('*[data-href]').on('click', function() {
window.location = $(this).data("href");
});
.modal {
padding:5px;
background-color:red;
color:#fff;
cursor: pointer
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<table>
<tr>
<td>Name</td>
<td> Age</td>
<td>
Update
<a data-toggle="modal" class="modal" data-target="#deleteModal">Delete</a>
</td>
</tr>
</table>
Can somebody try to help me with this?
To achieve this you can use the is() method to determine what element within the tr was clicked on. If it was an a element then you can prevent the window.location from being updated.
Also note that you can update the data-href of each tr using an implicit loop which makes the code slightly more succinct. Try this:
$('tr').attr('data-href', function() {
return $(this).find('a').attr('href');
});
$('*[data-href]').on('click', function(e) {
if (!$(e.target).is('a')) {
window.location.assign($(this).data("href"));
}
});
.modal {
padding: 5px;
background-color: red;
color: #fff;
cursor: pointer
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<table>
<tr>
<td>Name</td>
<td>Age</td>
<td>
Update
<a data-toggle="modal" class="modal" data-target="#deleteModal">Delete</a>
</td>
</tr>
</table>

HTML eventlistener on each row of table

Here is the problem:
I have a table with rows that have keypress listeners
Each row is contentEditable
I want to make the wrapping tbody element contentEditable (to allow selecting multiple rows by click and dragging)
If I do make tbody contentEditable the keypress event is no longer
triggered in the rows
only the tbody element recieves the event
The main issue is that setting tbody as editable obscures the keypress events for the table rows
EDIT:
Is there any form of pointer-events:none for keyboard events?
How can I have the rows still recieve the event or how can I enable drag and select without making tbody/table contentEditable?
Would appreciate any feedback or help, thanks!
Here is an example code snippet if the description is unclear:
<style>
table{
background-color: cyan;
}
table, th,td, tr{
border: 1px solid black;
border-collapse: collapse;
}
tr,td, th {
padding: 3px;
text-align: left;
height: 2em;
}
</style>
<div>
<table>
<thead style = "background-color:white">
<tr>
<th>Value</th>
</tr>
</thead>
<tbody> <!-- need to make this tbody contenteditable -->
<tr contenteditable = 'true' onkeypress='keyPressed(event)'>
<td>v1</td>
</tr>
<tr contenteditable = 'true' onkeypress='keyPressed(event)'>
<td>v2</td>
</tr>
</tbody>
</table>
</div>
<script>
function keyPressed(){
if(event.keyCode == 13){
event.preventDefault();
row = event.target;
row.insertAdjacentHTML('afterend',"<tr contenteditable = 'true' onkeypress='keyPressed(event)'><td></td></tr>");
row.nextSibling.focus();
}
}
</script>
document.querySelectorAll('contenteditable td')
.forEach(e => e.addEventListener("click", function() {
// Here, `this` refers to the element the event was hooked on
console.log("clicked")
}));
lear more.
You can use element.target to see which element is actually being click on. For example, in my snippet tbody and the tr has contenteditable but as you can see in the console, element.target and element.currentTarget both retrieve a different field so you know you can use it that way.
But I would probably just recommend using divs instead, as they will be easier to work with.
document.querySelector('[contenteditable]').addEventListener("click", function(el) {
console.log(el.target,el.currentTarget)
});
/*
function keyPressed() {
if (event.keyCode == 13) {
event.preventDefault();
row = event.target;
row.insertAdjacentHTML('afterend', "<tr contenteditable = 'true' onkeypress='keyPressed(event)'><td></td></tr>");
row.nextSibling.focus();
}
}*/
table {
background-color: cyan;
}
table,
th,
td,
tr {
border: 1px solid black;
border-collapse: collapse;
}
tr,
td,
th {
padding: 3px;
text-align: left;
height: 2em;
}
<div>
<table>
<thead style="background-color:white">
<tr>
<th>Value</th>
</tr>
</thead>
<tbody contenteditable='true'>
<!-- need to make this tbody contenteditable -->
<tr contenteditable='true'>
<td>v1</td>
</tr>
<tr contenteditable='true'>
<td>v2</td>
</tr>
</tbody>
</table>
</div>

contenteditable change background color after edit

I am trying to build a spreadsheet-like application and using a table <td> with a tag contenteditable = "true" and I want the background color of the cell to be changed after it was changed.
From my research I figured I would need javascript or jquery to do so, however I know very little of it. Where do I start? So far I have figured how to change color when the cell is being edited. thank you!
<td contenteditable="true" >
<style>
[contenteditable="true"]:focus {
background-color: yellow;
}
</style>
"Stuff"
</td>
So I see you figured out how to change color when the cell is being edited. Now to change the cell after its done being edited you can use the following example.
jQuery has a function called focusout which triggers when the element loses focus from the user. It will then add the class orange which will change the background to orange.
$( document ).ready(function() {
$("td").focusout(function(){
$(this).addClass("orange");
});
});
td[contenteditable="true"]:focus {
background-color: yellow;
}
.orange{
background-color: orange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<td contenteditable="true" >"Stuff"</td>
</table>
Here is a fiddle to play with: https://jsfiddle.net/8zbrxwpz/
Use td[contenteditable="true"] selector, and add the table parent as well.
td[contenteditable="true"]:focus {
background-color: yellow;
}
<table>
<td contenteditable="true" >"Stuff"</td>
</table>
https://jsfiddle.net/kasyzytr/

How to NOT select only specific elements in a table with jQuery?

I have this fiddle: http://jsfiddle.net/v9s5ezpb/1/
HTML
<table>
<tr>
<td>test1</td>
<td>test2</td>
<td>test3</td>
<td>test4</td>
<td>test5</td>
<td class="no-alert">test6</td>
</tr>
</table>
CSS
table {
border: 1px solid #000;
}
table td {
border: 1px solid #000;
padding: 10px;
}
JS
$(document).on('click', 'table td:not(.no-alert, a)', function()
{
alert(1);
});
I want my code to execute an alert window on each time I click on any of the table TD items, except those items that have a specific class or has an anchor tag.
How is that possible?
A <td> can't be an <a> but it can have descendant <a> for which you could use :has() selector.
$(document).on('click', 'table td:not(.no-alert, :has(a))', function()...
EDIT: Update allowing click on <td> with <a> but not when <a> is target
$(document).on('click', 'table td:not(.no-alert)', function(event){
if(!$(event.target).closest('a').length ){
// is not click on <a>` tag
}
});
Used closest() to check target in case <a> has any children like <i> or <img> that could potentially be the actual target
DEMO

Change Cursor to Pointer and Make the text bold in <td> element

I have some question regarding html. I am using AJAX to process a element. But the problem is how do i make the text inside the td bold and change the cursor to pointer when hovering over the element. I tried onmouseover but it doesnt work.
my td element is this
<td id='buildingName$i' onclick='tdClick($i)'>".$row['PROJECTNAME']."</td>
thanks guys for your help
Why not just use CSS? You could easily do something like this:
td:hover {
font-weight: bold;
cursor: pointer;
}
Doing it using css is the best solution. Here is the jquery option if you need it.
$("#test").hover(function(event) {
$("#test").addClass("highlighted");
}, function(event) {
$("#test").removeClass("highlighted");
});
.highlighted {
font-weight: bold;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td id="test">HTML</td>
<td>Javascript</td>
</tr>
</table>
use CSS as described in other answer
remove the onclick from the TD and instead use unobtrusive delegation - for example in jQuery:
:
$(function() {
$("#tableContainer").on("click",".clickableTD",function(){
var idx = parseInt(this.id.replace("buildingName",""),10);
// here you do whatever you did in tdClick
});
});
assuming
<div id="tableContainer"></div>
and
<td id='buildingName$i' class='clickableTD'>".$row['PROJECTNAME']."</td>

Categories