jQuery selector .not() NOT working

Go To StackoverFlow.com

2

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="&#x2713;" /><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>
2012-04-04 17:00
by Nikom
Also it can be event bubbling problem. Read more about events order http://www.quirksmode.org/js/events_order.htm - antyrat 2012-04-04 17:04
So you're trying to select every tr that is not selected? Take a look at the jQuery documentation for the "selected" selector. Your syntax looks a bit off. Some DOM examples would be helpful in aiding you more however - Primus202 2012-04-04 17:04


3

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/

2012-04-04 17:26
by jfriend00
This actually works (dunno why) if i use .table-main only and click in the spacing between the cells. Not if i click on the cells directly. Do i have to assign every single class inside the table to the selector aswell - Nikom 2012-04-04 17:40
Add your actual HTML for the table to your question and we can help more specifically. You will also need to be more specific about exactly which clicks you do and don't want processed in this handler. This uses event bubbling and event delegation to solve the problem elegantly. Also, which one of the two options did you try - jfriend00 2012-04-04 17:42
Posted the rendered html in shorter form since the real table is like 5 miles lon - Nikom 2012-04-04 17:59
In that HTML, exactly which clicks do you want and not want in this event handler - jfriend00 2012-04-04 18:08
Lets say i want the selector on everything apart from 'tableformclass selected' to trigger the functio - Nikom 2012-04-04 18:18
@NikoM. - I added a new version to my answer. If this isn't exactly what you wanted, you should be able to tweak the selector as desired - jfriend00 2012-04-04 18:28
works! thanks alot : - Nikom 2012-04-04 18:42


2

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){})
2012-04-04 17:05
by Andrei
Actually it was supposed to be a boolean assigned via .data() but i guess it was incorrect synta - Nikom 2012-04-04 17:15


1

$('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">
2012-04-04 17:05
by Quentin
I wanted to call the event on mousedown everywhere aside from this only table-row. [selected] was supposed to be a boolean assigned to the row via .data(). To simplify things i can take the table only, but it is not working. Using $('html:not(.table-main)') is still reacting on .table-mai - Nikom 2012-04-04 17:20
Ads