Reputation: 1554
I apologize in advance for my english...
I'm creating an editable table's cell. In this table, I want to remove the click event on the cell (td) clicked but let clickable the other cells.
$("#idTable").on("click", "td", function (e) {
var oTxtbox = $('<input type="text" value="' + $(this).text() + '"/>');
$(this).html(oTxtbox);
// I try to remove the event
$(this).off(e);
// $("#idTable").off("click", $(this) );
// other code
});
With the statement $(this).off(e)
I remove the event of all cells, instead
$("#idTable").off("click", $(this) )
I don't remove anything: all cells are clickable.
Can you help me?
UPDATE 1: This is a demo of my example: EXAMPLE CODE
UPDATE 2: Now I have another problem with the events: If user click outside the table I want to re-bind/re-attach the event on td. This is a link with a complete code: NO RE-BIND EVENT
What am I doing wrong now?
Upvotes: 4
Views: 1002
Reputation: 22339
Edit
I just seen you found a solution, sweet :).
For completeness though I leave my answer as I finally found how to unbind the events completely.
You are using dynamic bindings and as such unbinding an individual element is quite complex due to the event always bubbling up to the static element it is bound from.
As seen in the other answer, you can overwrite the click event with a new click event and stop propagation.
However, that still leaves you with an element which has an event attached which always executes when clicked, even if it doesn't bubble up.
The example below truly unbinds the event, leaving you with no left-over and not requiring propagation being stopped as the event is completely unbound:
$(document).one('click', 'div', function(e) {
$(this).parent().find("div").one('click.NewClick', function() {
$('#result').append(this.id + " was clicked<br />");
});
$(this).click();
});
In the above demo I'm using one() through-out to ensure automatic unbinding of the event.
The outer one()
is required for the logic, the inner one()
is your requirement as you wanted the event unbound ones clicked.
I'm binding the initial click
event as usual with the dynamic selector 'div', using one()
.
However, ones I'm inside the click
event, after any of the divs have been clicked, I'm re-binding the click event to the elements, using one()
again, this time using the static
selector though as the elements now exists. I'm also using a namespace 'click.namespace'
to ensure the unbinding of the outer one()
does not get rid of the new bindings.
Now I have all my divs nicely bound with one()
, which means they automatically unbind completely after being clicked.
To prevent the user from having to click twice after the initial click, I'm automatically triggering the click event ($(this).click()
) of the element which was triggered the initial event, making is seamless to the user.
Your code should be able to use this with code similar to the below:
$("#idTable").one("click", "td", function(e) {
$(this).parent().find("td").one('click.NewClick', function() {
var oTxtbox = $('<input type="text" value="' + $(this).text() + '"/>');
$(this).html(oTxtbox);
// other code
});
$(this).click();
});
Note the use of one(), instead of on().
Off course the inner binding can be what ever you need it to be, one()
was only selected as you wanted the event unbound after the element was clicked.
Upvotes: 6
Reputation: 218752
Did you try using unbind
?
$("#idTable").on("click", "td", function (e) {
var item=$(this);
var oTxtbox = $('<input type="text" value="' + item.text() + '"/>');
item.html(oTxtbox);
item.unbind("click")
});
Remove a previously-attached event handler from the elements.
EDIT : When we need to remove a handler from itself, we need to do this approach.
So the code should be
$("#idTable").on("click", "td", function (e) {
var item=$(this);
var oTxtbox = $('<input type="text" value="' + item.text() + '"/>');
item.html(oTxtbox);
item.unbind(e)
});
The handler in this case must take a parameter, so that we can capture the event object and use it to unbind the handler after the third click. The event object contains the context necessary for .unbind() to know which handler to remove.
Working sample : http://jsfiddle.net/tRNhJ/24/
Upvotes: 1
Reputation: 3605
I don't think $(this)
is what you think it is. It is the matching <td>
, which is not where the event is caught (it is caught on the $("#idTable")
when it bubbles up.
Replacing the .off
lines with this line inside your handler will do what you want:
$this.on('click', function(e) {e.stopPropagation();} );
Upvotes: 2