Reputation: 85
I have a javaScript function in view/loadMoreDataWater.php
<td ondblclick="updateCell()">
</td>
Now in table.php
in public_html
folder I have a table when onscroll is supposed to load more data:
qlimit =0;
$("#waterDBTable tbody").scroll(function() {
if ($("#waterDBTable").scrollTop() > $("#waterDBTable").height() - 300) {
qlimit = qlimit + 5;
$("#loadingDiv").css('display','block');
$.ajax({
url: "controllers/loadMoreDataWater.php?qlimit=" + qlimit + "&table=water",
success: function(result) {
$("#waterDBTable").append(result);
$("#loadingDiv").css('display','none');
}
});
}
});
Now when the content is loaded by ajax. ondblclick function is not working. I found something about using
$(body).on('click', '#something', function() {
but I got confused and it didn't work for me, I didn't know in which file I must place such code.
Thank you
Upvotes: 0
Views: 106
Reputation: 85
Thank you for your contributions. The problem was in the id of the new embedded elements as it contained a variable and this variable caused duplication of the id. it works fine now. thanks @amdouglas
Upvotes: 0
Reputation: 1903
You were reading about event delegation.
$('body').on('click', '#something', function() {
// do stuff
});
This code would add an event listener to the body
element, listening for a click
event and attaching a handler function to any click
event which bubbled up from an element with an id
of 'something
'.
The idea is instead of having an ondblclick=
attribute, you attach one event listener like this:
$('body').on('dblclick', 'td', function() {
// do whatever updateCell() does, using `$(this)` for the td that was clicked
});
So in effect you're delegating the event handler to one element. This is useful for several reasons, chief among them is that the body element doesn't go anywhere when you remove content and neither does the event handler need to be attached to new elements when being added to the DOM.
To understand how this works, reverse engineer it. Imagine what this is actually doing: all events bubble up from their source to the top level node. This means that every click event registers as a click on the event target (the element you're adding an event handler to) and on the body element, because you clicked the body too in clicking the element.
"So", one might wonder, "why add many event listeners to many individual elements when you can just add one giant event listener to the body and implement some switchboard logic in the event handler function?"
Without jQuery, you can do a basic event dispatcher like so:
document.body.addEventListener('dblclick', function(){
var el = this;
if ( el.classList.contains('dblclick-to-update') ){
updateCell(el);
}
// other if statements could be below, handling other dblclick events, on elements other than td cells, if necessary
});
So, instead of saying:
potentially dozens or even hundreds of times, we say:
Ideally, each of your td
elements would be given a CSS class like class="dblclick-update"
or a data- attribute like data-dblclickupdate="true"
, either of which you could then use as a selector for your delegated event handler. This would be instead of using 'td
' as a selector, which would screw up if you have other td
elements which do not need to have the updateCell()
behaviour attached to them.
So your code might look like this:
$('body').on('dblclick', '.dblclick-update', function(){
updateCell($(this));
});
Using updateCell($(this))
will give you the td
which was clicked, but you'll need to change the updateCell()
function to work with the element being passed in as a parameter. In your function definition, you'll need firstly to state that the function expects a parameter, so where you probably have this:
function updateCell() {
// do stuff to 'this'
}
you need to define the function like this instead:
function updateCell(cell) {
// do stuff to 'cell', which is passed in as a parameter now
}
Obviously, if you choose to use event delegation, you won't need those ondblclick=
attributes anymore, so remove those and just have <td class="dblclick-update"></td>
or something like that.
As for why the ondblclick="updateCell()"
wasn't working for newly added td
elements, my guess would be that you defined your updateCell()
function within a $(document).ready
block, which means that the function is not available to newly added elements because it's not in the global scope.
Try putting the function in the global scope instead, either by defining updateCell()
outside of $(document).ready
(and outside of any other functions for that matter) or by referencing it directly in the global window
object like this:
window.updateCell = function(){
// do stuff to cell
};
Or, if you use event delegation,
window.updateCell = function(cell){
// do stuff to cell
};
Upvotes: 1