I'm trying to retrieve the TR element's ID, whenever the user removes focus from that TR. Triggering the event is easy enough, but I can't work out how best to retrieve the ID
$(".row-identifying-class").focusout(function (e) {
var rowID = e.target.id; // Returns the ID of the TD/input/label etc the user last clicked on
alert(e.target);
})
The problem appears to be that although the function above triggers whenever I remove focus from the TR, the event is actually triggered by the child element (eg the TD, input box, button etc), not the parent element.
Is there any way to retrieve the original TR, without having to trace back through the parent of each object until I hit a TR element? Perhaps by passing the ID in directly when creating the function?
You're correct in that e.target will refer to the element that raised the new event which caused the focusout to fire on the tr.
Instead, use the currentTarget property as that will point to the event bound element instead, or more simply just this.id:
$(".row-identifying-class").focusout(function(e) {
console.log(e.currentTarget.id);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr class="row-identifying-class" id="tr">
<td>
<input type="text" value="cause a focusout on me..." />
</td>
</tr>
</table>
Use this or e.currentTarget instead of e.target
$(".row-identifying-class").focusout(function (e) {
var rowID = this.id;
alert(rowID);
});
this within a jQuery event handler will be the element instance of the matching selector the event occured on
Related
For each td element in a table I have an attached ng-click. Here is the (simplified) html for each table cell:
<td ng-click="cellClicked($event)">
<span ng-if="!cellEdit">{{event.eventName}}</span>
<input type="text" ng-if="cellEdit" ng-model="event.eventName">
</td>
And my (simplified) ng-click function:
scope.cellClicked = function (event) {
rowScope.cellEdit = true
angular.element(event.target).find('input').focus()
}
Its my goal to:
User clicks a table cell
Cell changes to "edit mode"
Give focus to the input element located inside the td.
Right now this is working as long as the user clicks inside the td element but not on the span element:
console.log(angular.element(event.target)) #--> [td...] (as desired)
However if the user clicks on the span element within the td:
console.log(angular.element(event.target)) #--> [span...]
In this use case assigning focus does not work. I was hoping to access the parent element of the span doing something like:
angular.element(event.target.closest('td'))
or
angular.element(event.target.parentNode)
But it appears when an element gets passed through via $event and accessed there is no parent context.
How can I either:
Prevent clicking the span element firing the td's ng-click
On click of span element pass through it's html parent
Changing:
angular.element(event.target)
to:
angular.element(event.currentTarget)
fixed my issue.
It seems to me using event.currentTarget is preferred to event.target in the majority of usage cases.
event.target.closest('td') won't work because event.target is a DOM element and it doesn't have method closest. You need to create a jQuery object to use this method.
Try to find closest td like this:
angular.element(event.target).closest('td')
In Angular 7.x
myClickHandler($event) {
this.selectedElement = <Element>$event.target.closest('.list-item');
}
html:
<div class="list-item" (click)="myClickHandler($event)">...</div>
I want to have a table and its cells are filled with data from MySQL.
The table have many TDs, which have an Id.
I want to pass the id of the cell to a function, so that I can edit its content:
document.getElementById(IndexedActionButton).innerHTML = '<input type="Button" name = "EditActionButton" id="EditActionButton" onClick="SaveUpdateToActionList("Cell_ID")" value="Edit Action" />';
function SaveUpdateToActionList(Cell) {
alert(Cell);
document.getElementById(Cell).innerHTML = 'Here';
}
When I have alert(Cell); displayed, I see this sends the Text "Cell_ID", whereas I wanted to see the data ActionButton386 there.
Any help appreciated.
You can pass in the element being clicked by setting your onClick script to SaveUpdateToActionList(this);
Then, in the body of SaveUpdateToActionList, Cell will refer to the button that just got clicked. You can then walk up the DOM to get to the TD it belongs to.
You can try this:
document.getElementById(IndexedActionButton).innerHTML = '<input type="Button" name = "EditActionButton" id="EditActionButton" onClick="SaveUpdateToActionList()" value="Edit Action" />';
function SaveUpdateToActionList(event) {
alert(event.target.id);
document.getElementById(Cell).innerHTML = 'Here';
}
But if i understand correctly what you are trying to do, you shoud have a single event listner that catches bubling events from all cells, rather that attaching a an onclick to each cell....
Just register the event listener separately from specifying the innerHTML property:
Document.getElementById(IndexedActionButton).addEventListener('onclick', SaveUpdateToActionList);
SaveUpdateToActionList will be called with an event object as the first argument. You can access which element was clicked by checking the event.target property. For more information check out MDN - addEventListener documentation
I'm generating and appending several spans to divs on page load.
HTML structure like:
<div id="holder">
<div id="grid"></div>
</div>
Then loop through and append spans to the nested div:
$span = $('<span />').attr('class', 'colorSquare');
$("#grid").append($span);
Then, I want to click a button and reset (delete the originally appended spans, because I don't want to reappend spans) what's inside the div's with:
$("#holder > div").html("");
On initial page load / initial generation of spans inside the div, the click event handler is registered to the div's spans on document.ready , and the following works:
$("#grid span").click(function () { console.log("working"); });
However, after resetting with $("#holder > div").html("");, the click handler doesn't work. I'm assuming this is because the handler is only assigned on initial document ready, but I wasn't expecting all handlers to be removed once you reset the div's content. How do I prevent assigned handlers from being removed?
This is because you are assigning the click handler onto the span element that you have added to #grid. When you clear #grid, you also remove the span and therefore you lose the click handler. You will either have to re-assign the handler again as soon as another span is created, or use an alternate handler that is tied to an element that does not get removed (such as #grid):
$('#grid').on('click', 'span', function() { console.log("working"); });
This alternative uses jQuery's on method, and binds the handler to the #grid element. However, the second parameter labels that you only care about clicking on span elements which are children of #grid.
I am aware that e.target contains the info of the element just below the cursor, but what if I want to know the class name of the div which has a table>tr>td>button in it and I'm clicking that button inside that td. I know this events bubbles up and there should be a way to find out if the div exists in that bubbling levels. Any help.
Scenario: button is inside a modal window. How do I find the modal windows class name on click of the button inside it.
Use .closest() to traverse up the DOM to the nearest match:
var parentDiv = $(yourButton).closest('div');
Or in the button's click:
$(yourButton).click(function() {
var nearestParentDiv = $(this).closest('div');
// And read its class
console.log(nearestParentDiv.attr('class'));
});
The selector .closest() accepts can of course be more specific than this, so if if the modal window <div> has some known class but you need to inspect its other classes, you should use the more specific selector.
Yes as you say the event will bubble up to your div, so just make the div handle the event with .on() , like this:
$('#yourdiv').on('click',':button',function(e) {
alert( $(e.delegateTarget).attr('class') );//alerts the classes of #yourdiv
alert( $(this).attr('id'));//alerts the id of the clicked button (if have one)
});
UPDATE:
Fixed obtaining the reference to the original div where the event was attached. With event.delegateTarget from the Event object . Thanks Cristophe and Kevin B. for spotting the error.
See working demo
You can use .parent() to get the parent div attributes like id: http://jsbin.com/ololad/1/edit
$('button').click(function(){
console.log($(this).parent().attr('id'));
});
I have the following function:
$("#example tbody").click(function(event) {
$(oTable.fnSettings().aoData).each(function (){
$(this.nTr).removeClass('row_selected');
});
$(event.target.parentNode).addClass('row_selected');
});
When a user clicks on a td element in a table it adds the row_selected class to the row. However when a user clicks on an input element inside of a td then it adds the row_selected
class to the td.
Is there a way that I can change event.target.parentNode so that instead of the parent
it adds the class to the parent tr?
Use closest().
$(event.target).closest('tr').addClass('row_selected');
Change your handler to use jQuery's event delegation instead of your own...
$("#example tbody").on("click", "tr", function(event) {
...then you can just use this...
$(this).addClass('row_selected');
You can use parentsUntil() function, that is sort of like finding ancestors. I cant remember the function for ancestors, but this will work:
$(event.target).parentsUntil("tr").addClass('row_selected');
you can try this
$(event.target).closest('tr').addClass('row_selected');
Instead of your line
$(event.target.parentNode).addClass('row_selected');
Using closest(), you will be able to apply row_selected class to nearest tr element of the element you click, that may be a td or any other element inside it.