I've built a jQuery selector for a function which looks like this:
$('html').not('.table-main tr[selected]').mousedown( function( e ) {
But somehow it is not filtering at all and i do not quite understand why.
Even if i just leave ('.table-main') for the selector i still trigger the function when clicking into the table... What is wrong with that?
Using document or 'body' instead of 'html' does not help, as document is not triggering at all with .not() and 'body' results in the same.
Edit:
Just tried using another block outside of the table and it works. Is there a chance i cannot use this on tables?
Update2: As requested, here is the rendered html code of the table:
<table border="0" cellspacing="2px" cellpadding="5px" class="table-main">
<tr id="tablefields">
<th style="padding: 0;">
<table cellpadding="0" cellspacing="0" border="0" align="center">
<tr><th><div class="tr-head-get" id="tr-get-0">Name</div></th></tr>
<tr><th><div class="th-header" id="th-header-0" style="top: 54px;">Name</div></th></tr>
</table>
</th>
<th style="padding: 0;"></th>
</tr>
<tr id='table_form_new_device' class='table_form_class'>
<form accept-charset="UTF-8" action="/devices" class="new_device" data-remote="true" id="new_device" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="T2dSeZpxxvgJdTP+yoE7BrVODzqJ95gyVu9Wh/v7oP8=" /></div>
<th class='tablefield'>
<input id="device_devicename" name="device[devicename]" size="10" type="text" />
</th>
<th>
<div class='submitbox' id='submitbox_new_device'>S</div>
<script>
$('#submitbox_new_device').click(function (event) {
$('#new_device').submit();
});
</script>
</th>
</form></tr>
</table>
<div class="dropdown-button" style="margin: 0 2px;">Filter</div>
You really, really want to use delegated event handling for this because you don't want to attach an event handler to every single element in the document. You want to intercept bubbled events at the document level and just check if the mousedown came from an element that was not a selected row in your table.
In addition the tr[selected] seems unlikely to work. I think you need to add a class "selected" to the selected row and then use tr.selected as the selector.
If you make that change, I'd suggest something like one of these two options:
$(document).mousedown(function(e) {
if (!$(e.target).is('.table-main tr.selected')) {
// mouse down and it wasn't in a selected row of your table)
}
})
You may also be able to let jQuery delegation do more of the work:
$(document).on('mousedown', ':not(.table-main tr.selected)', function() {
// mouse down and it wasn't in a selected row of your table)
});
After seeing your actual HTML, if I understand the problem correctly, this should work. This will give you an event anytime a click happens as long as that click is not in a row of table-main that has the selected class on it:
$(document).on('mousedown', function(e) {
// mouse down and it wasn't in a selected row of your table)
e.stopPropagation();
if (!$(e.target).closest(".table-main tr.selected").length) {
console.log("mousedown not in selected row of table-main")
}
});
Here's a demo: http://jsfiddle.net/jfriend00/5QD6N/
Using [selected] makes no sense on a element of type tr. You use selected for inputs(checkbox,radio). You can add a class .selected to the tr elements in .table-main and then use :
Edit: Like somebody posted above, you want to use select the elements nested inside the body.
$('body').find(':not(.selected)').mousedown(function(e){})
$('html') creates a jQuery object containing your HTML element.
.not('.table-main tr[selected]') removes any TR elements with a selected attribute (there is an error here, that attribute doesn't appear on TRs) that are descended from elements that are members of the table-main class. Since HTML elements are not TR elements and can't be descended from anything, this removes no elements and has no effects.
mousedown( function( e ) binds an event handler to the HTML element. Unless something stops propagation, any click will eventually bubble up to there.
I'm guessing (since you didn't actually say what you wanted to achieve) that you want to capture clicks on TR elements that aren't selected. Assuming that you switch to using classes to make the HTML valid…
$('.table-main tr:not(.selected)').mousedown(…);
and
<tr class="selected">
Related
I have a footable
. When I click on the plus to expand a row
I want to access with jQuery the yellow elements:
If I inspect the element the DOM looks like that after the click:
<table class="footable-details table">
<tbody>
<tr><th>
DOB (hide)
</th><td style="display: table-cell;">
10/16/1977
</td></tr><tr><th>
Description
</th><td class="someText" style="display: table-cell;">
Some description
</td></tr>
</tbody>
</table>
What I would like to do, is to set colspan="2" for td.someText and hide the <th>Description</th>. But I can't access td.someText
I tried to access it with
$('.footable').on('expand.ft.row', function(e, ft, row){
$(row.$details).find('td.someText'));
});
but he does not find anything. In fact, alert($(row.$details).html()); only returns
<td colspan="4">
<table class="footable-details table">
<tbody>
</tbody>
</table>
</td>
Any idea how to access the td with class someText after click?
Here is a jsFiddle
Note: This is not a duplicate of Footable and capturing the expand row event. The linked question is about how to access a row in general. This question is if I select it with the method from the API the content is not loaded correctly. The question helped me to get here, but does not to solve the here presented issue.
expand.ft.row event fires before it appends the dom content.so if you try to read the row content, it's not there.
The correct event for your case is expanded.ft.row which fires after appending the content.
$('.footable').on('expanded.ft.row', function(e, ft, row) {
alert($(row.$details).html());
});
check this demo
https://jsfiddle.net/bfmaredn/
I found this event by analyzing the source code from GitHub repository https://github.com/fooplugins/FooTable/blob/V3/src/js/classes/FooTable.Row.js
Use "async function", try the following code:
$(function() {
$(".footable").footable();
$('.footable').on('expand.ft.row', async function(e, ft, row) {
alert($(await row.$details).html());
});
});
Refer:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
I have a calendar where the day cells are clickable "td" elements. Inside each is an "a" that has a title. I need to use this title in a JavaScript function that is called when any of the "td" elements are clicked. I had to disable the PostBack for all "a" elements
Here is code for one of the cells:
<td align="center" style="width:14%;">15</td>
I just need to access the 15 text technically. I can get the month elsewhere.
Is this possible using JavaScript?
Using jQuery for this would be a pretty good idea since you can select elements pretty conveniently. With jQuery you'd use:
$('td a').attr('title');
If you still want to use pure Javascript, you can select the title of the element by using:
document.querySelectorAll('td a')[0].title;
In the end, they both get the job done but the jQuery code is shorter.
So you'd do something similar to this with jQuery.
$('td a').on('click', function() {
console.log($(this).attr('title'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<th>
<tb>
<tr>
<td>
Hey
</td>
</tr>
<tr>
<td>
Oh
</td>
</tr>
<tr>
<td>
Goodbye
</td>
</tr>
</tb>
</th>
</table>
It's not exactly clear to me what you're after, but if you can control the call, then including this in the call gives you a reference to the element that called the listener, e.g.
<a href="javascript:__doPostBack('ctl00$MainContent$Calendar2','6314', this)"...>
Then in the listener, you have a reference to the element and you can get its title property directly, e.g.
function __doPostBack(arg0, arg1, element) {
var title = element.title;
// title is the value of the element's title property
}
I had to disable the PostBack for all "a" elements
I don't understand what that means. If it means you don't want to use __doPostBack to get the title and want to add a listener to each of the links, then you can do that quite simply too:
window.onload = function(){
[].forEach.call(document.querySelectorAll('td a'), function(a){
a.addEventListener('click', showTitle, false)
});
};
function showTitle(){
console.log(this.title);
}
<table>
<tr><td><a href="#" title="foo">foo
<tr><td><a href="#" title="bar">bar
<tr><td><a href="#" title="fum">fum
</table>
I have a page that takes information from MySQL database and using PHP generates HTML.
Since this is only a test run, I began to wonder about using the ID's like this, because the final page would be using upwards of 400 different #td[i]'s and #bubble[i]'s.
Questions:
Is there a better practice I should be using?
What whould be a viable option for showing the bubble tables temporarily on mouse hover, but permanently (until another td is hovered/clicked) on click.
Script:
$(document).ready(function(){
$("#maintable").show();
$( "#td1" ).click(function() {
$("#bubble1").toggle();
$("#bubble1").css("background-color", "yellow");
});
$( "#td2" ).click(function() {
$("#bubble2").toggle();
$("#bubble2").css("background-color", "yellow");
});
$( "#td3" ).click(function() {
$("#bubble3").toggle();
$("#bubble3").css("background-color", "yellow");
});
$( "#td4" ).click(function() {
$("#bubble4").toggle();
$("#bubble4").css("background-color", "yellow");
});
$( "#td5" ).click(function() {
$("#bubble5").toggle();
$("#bubble5").css("background-color", "yellow");
});
$( "#td6" ).click(function() {
$("#bubble6").toggle();
$("#bubble6").css("background-color", "yellow");
});
});
</head>
<body>
<h1>Dynamic tables</h1>
<br>
<table id="maintable" border="1">
<tr>
<td id="td1">TD1</td>
<td id="td2">TD2</td>
<td id="td3">TD3</td>
<tr>
<td id="td4">TD4</td>
<td id="td5">TD5</td>
<td id="td6">TD6</td>
</tr>
</table>
<br><br>
<table id="bubble1" border="1">
<td>
Selected tablepart:<br>
<b>TD1</b><br>
Location:<br>
<b>R1F:D3-4:E1</b><br>
Connection:<br>
none <button id="create1">Create</button>
</td>
</table>
<table id="bubble2" border="1">
<td>
Selected tablepart:<br>
<b>TD2</b><br>
Location:<br>
<b>R1F:D3-4:E2</b><br>
Connection:<br>
none <button id="create2">Create</button>
</td>
</table>
<table id="bubble3" border="1">
<td>
Selected tablepart:<br>
<b>TB3</b><br>
Location:<br>
<b>R1F:D3-4:E3</b><br>
Connection:<br>
none <button id="create3">Create</button>
</td>
</table>
<table id="bubble4" border="1">
<td>
Selected tablepart:<br>
<b>TB4</b><br>
Location:<br>
<b>R1F:D3-4:E4</b><br>
Connection:<br>
none <button id="create4">Create</button>
</td>
</table>
<table id="bubble5" border="1">
<td>
Selected tablepart:<br>
<b>TB5</b><br>
Location:<br>
<b>R1F:D3-4:E5</b><br>
Connection:<br>
none <button id="create5">Create</button>
</td>
</table>
<table id="bubble6" border="1">
<td>
Selected tablepart:<br>
<b>TB6</b><br>
Location:<br>
<b>R1F:D3-4:E6</b><br>
Connection:<br>
none <button id="create6">Create</button>
</td>
</table>
And my CSS:
table {
margin-left:auto;
margin-right:auto;
display: none;
border: 1px solid black;
border-collapse: collapse;
}
EDIT:
The best solution so far: (Combined from several answers)
https://jsfiddle.net/Zimpari/3wm01nmL/
As i said i have cooked up a version where the data required for bubble table is implicitly stored inside each record.
https://jsfiddle.net/tLqbks0c/
<table id="maintable" border="1">
<tr>
<td id="td1" data-bubble='{"part":"TD1","location":"R1F:D3-4:E1"}'>TD1</td>
<td id="td2" data-bubble='{"part":"TD2","location":"R2F:D3-4:E1"}'>TD2</td>
<td id="td3" data-bubble='{"part":"TD3","location":"R3F:D3-4:E1"}'>TD3</td>
</tr>
</table>
<table id="bubbleTable" border="1" style="display:none;">
<td>
Selected tablepart:<br>
<b class="part"></b><br>
Location:<br>
<b class="location"></b><br>
Connection:<br>
none <button id="create3">Create</button>
</td>
</table>
$( "#maintable td" ).click(function() {
$("#bubbleTable").show();
var bubData=jQuery.parseJSON($(this).attr("data-bubble"));
console.log(bubData);
$("#bubbleTable b.part").text(bubData.part);
$("#bubbleTable b.location").text(bubData.location);
});
I have to warn you this is a fairly rough draft. You have to handle the server rendering in PHP and MySql . Converting data to JSON format in PHP is fairly easy using json_encode()
For a case like this, it's best to use event delegation. This can be accomplished by utilizing the delegation style syntax for .on(). For example:
$('#maintable').on('click', 'td', function (evt) {
var index = this.id.substring(2);
$('#bubble' + index).toggle();
$('#bubble' + index).css('background-color', 'yellow');
});
This snippet effectively replaces all the event handlers used above in the $(document).ready block. By attaching the single event to a parent element, you allow the events to bubble up the DOM tree and execute via a single handler.
This also works with dynamically generated content. When new content is added new event handlers are not needed.
Reference: .on()
It is pretty much OK to use 400 different ID's but then if there are certain consistent characteristics of these DOM elements, then you should add a class attribute to such elements. So that when trying to access it via selector calls in jQuery it is easier access.
So, even before trying to build a data heavy DOM, here is what you should do
Break your DOM elements into indivisible elements
Combine these indivisible elements into more complex objects
Build a hierarchy among these complex objects
These three steps should help you pretty much in every application.
Considering the current DOM that you are trying to build above, here are my suggestions:
Add a class='bubble' attribute to the <table> elements. Since, all seem to have consistent reason to exist
Inside them, they have <button> elements, it could be given a class='bubble-button' to show the similarity in application.
So while the button is the indivisible element, combine it with <td> to get the complex table data element.
Collection of such table data could make your bubble table.
I hope you see the hierarchy building up. While designing all this, you should realize that JS parsing is not the bottleneck in web applications. It is the modification of the DOM which takes a lot of time. So, you can have a lot of ID's but proper addressing could help you traversing the DOM tree more efficiently. Bad hierarchy in the DOM tree would cost you in the long run.
Now you could add the click and hover handlers as:
$('.bubble').on('yourevent', function(e){
/* handle the click, or onmouseover, or onmouseout events appropriately
by adding or removing CSS classes */
});
Let me know for more clarifications.
Yup. Here's all-encompassing jQuery. Should work.
#War10ck is right, substring is better.
$('td').each(function(){ //you might want to add a class selector, but whatever
var mybubble=$('#bubble'+this.id.substring(2));
$(this).click(function(){
mybubble.toggle().css('background-color','yellow');
});
$(this).mouseover(function(){
if(mybubble.css('display')=='none'){
mybubble.toggle().css("background-color", "yellow")
.attr('data-mouseover','true');
}
});
$(this).mouseout(function(){
if(mybubble.attr('data-mouseover')=='true'){
mybubble.toggle().css("background-color", "yellow")
.attr('data-mouseover','false');
}
});
});
I have a table and the TDs have a class and based on that class I'm adding click events to it like this
$('#regRegionsTable').on('click', '.toggleDetail', toggleDetail);
I'm using on because the table appears, goes away, and returns, and so on, so I need to be able to add events to the table as it gets added to the DOM. In certain circumstances I need to disable the events for a specific row. I'm trying it like this, but it's not working.
$(row).off('click', '.toggleDetail');
row is the TR DOM node. So I'm trying to get all of the TDs in the row that have the toggleDetail class and turn off the click event binding.
This is an example that could be useful. I add the click event on each td. On certain circumstances (clicking on a button in my example) I disable the click event for all the td on a specific row (the first row) using unbind()
$('#regRegionsTable td.toggleDetail').on('click', toggleDetails);
function toggleDetails(){
console.log("click avvenuto")
}
$("button").on("click",function(){
$('#regRegionsTable tr:first-of-type td.toggleDetail').unbind('click', toggleDetails);
})
function toggleDetails(){
console.log("click avvenuto")
}
<table id="regRegionsTable" border="1">
<tr>
<td class="toggleDetail">1</td>
<td class="toggleDetail">2</td>
<td class="toggleDetail">3</td>
</tr>
<tr>
<td class="toggleDetail">4</td>
<td class="toggleDetail">5</td>
<td class="toggleDetail">6</td>
</tr>
</table>
<button>Remove event on a specific tr</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I have a table containing Employee Names. I would like to add a hidden row after each row that contained contact information for that particular employee. I would like to use JQuery to do a slideDown animation that reveals that information.
If I was using Javascript, I would do something like name the TR element with an ID such as "employee-xx" and the hidden line as "hidden-xx" where xx is the employeeid. I would do an onClick event that called a function(using the employeeid as a parameter) to hide or unhide the line. As I am just starting JQuery, I don't know how to code this elegantly. I would like to tell it "When you click a visible line in the table, slideDown the invisible line below it", but don't know how to do that. If I use the ID of the row, how do I access the ID via JQuery? I know it's probably simple, but I am stuck.
Thank you,
John
http://www.w3schools.com/jquery/jquery_traversing_siblings.asp
var clickhandler = function(e) {
$(e.target).next().show();
}
btw, this has been answered on here before.
Retrieve previous and next rows in a table using jQuery
EDIT: Fixed a derpy mistake with missing class name. Fiddle has been updated.
I think this is what you want? Clicking on a row with a name causes the hidden row underneath to slide down. Click again to retract.
HTML:
<table>
<tr class="show">
<td>Bob Robertson</td>
</tr>
<tr class="hide">
<td>
<div>(555)123-4567</div>
</td>
</tr>
<tr class="show">
<td>Richard Johnson</td>
</tr>
<tr class="hide">
<td>
<div>(000)000-0000</div>
</td>
</tr>
</table>
JS:
$('.hide').toggle().find('div').slideToggle();
$('.show').on('click', function () {
var next = $(this).next();
if (next.css('display') == 'none') {
next.toggle();
next.find('div').slideToggle();
} else {
next.find('div').slideToggle(function () {
next.toggle();
});
}
});
Here's a fiddle.