0

I was hoping to set up a click event in one line of code for all html tags that have a specific class name. Apparently it doesn't recognize this as an html object or container that references itself and myFunction never executes on any click. I am trying to use this because I want to search inside the tag that was clicked for other html elements, and I would rather the tags not have to have unique ids and click events for each one because there are many of these.

$(document).ready(){
  $(".myClass").click(function () { 
       toggleDriver(this); 
   });
};

function toggleDriver(driver) {
    zoomed = false;
    $("#zoomer").css("display", "none");
    map.fitBounds(bounds);
    var dContainers = $("orders").find(".driverSection"); // first find all driver sections and loop through each
    for (var x = 0; x < dContainers.length; x++) {
        var tContainer = $(dContainers[x] + " .transactions"); // find transaction section for this driver section
        if (dContainers[x].attr('id') == $(driver).attr('id')) {  // is this the driver section that was clicked?
            if ($(tContainer).css("display") == "none"){ // if collapsed
                $(tContainer).slideDown("fast"); // expand it
                exp = $(driver).attr("id"); // save which driver is expanded in global var
                setDeliveryMarkers(); // set the map with driver marker and his delivery markers
            }
            else {
                $(tContainer).slideUp("fast"); // it was expanded so collapse it
                exp = ""; // save the fact that no driver transactions are expanded
                if (trans != "") { //any transaction for this driver that had focus (white border) needs to lose it
                    $("#" + trans).css("border-color", "transparent");
                    // we need to stop the marker animation for this transaction that no longer has focus
                    for (var x = 0; x < deliveryMarkers.length; x++) {
                        if (deliveryMarkers[x].getTitle() == trans) {
                            deliveryMarkers[x].setAnimation(null);
                            break;
                       }
                    }
                }
                trans = ""; // clear this value to show that no transactions are in focus
                setDriverMarkers(); // since no transaction section is expanded, show all drivers markers instead
            }
        }
        else {
            $(tContainer).css("display", "none"); // transaction container is not inside clicked driver section so close it
        }
    }
}

Does anybody know a better way to achieve what I want? Seems like just one small detail I'm missing. Thx.

POST EDIT: These html tags with this class name are loaded after document.ready so maybe someone can offer an answer geared towards that potential problem. Thx.

user192632
  • 266
  • 1
  • 17
  • 2
    Without seeing `myFunction`, it's pretty hard to help you. In the little code you did quote, `this` will indeed refer to the `.myClass` element that triggered the handler. – T.J. Crowder Oct 07 '16 at 17:29
  • That should work.... How does it not work in myFunction, maybe your issue is in there? Can you show that method? – epascarello Oct 07 '16 at 17:30
  • Make sure `myFunction` uses its argument variable, not `this`. – Barmar Oct 07 '16 at 17:30
  • Also, to add to this. You can simplify your code to `$(".myClass").click(myFunction);` and on your `function myFunction(){ }` you can reference `this` inside that function to get that same element. – Ross Oct 07 '16 at 17:36
  • As per request, I edited the question to provide the called function. It's not failing at all according to the debugger, and instead it never gets called. – user192632 Oct 07 '16 at 17:41
  • Your document.ready setup is incorrect. You want `$(document).ready(function () { ... });` I wouldn't be surprised if there are syntax errors in your console right now. – Heretic Monkey Oct 07 '16 at 17:47
  • I just added the document.ready myself, so that I don't have to add all the code in there and the actual call is correct as everything that is actually in document.ready works . I just didn't add the actual document.ready call that I am actually doing, but that isn't the problem – user192632 Oct 07 '16 at 17:52
  • If your elements with `.myClass` are getting dynamically loaded, you need to use *event delegation*. It would look like this: `$(document).on("click", ".myClass", function () {...});` Docs here: https://learn.jquery.com/events/event-delegation/ – mhodges Oct 07 '16 at 17:53
  • Are you adding elements *after* the document has loaded? (dynamically loaded) - check here: http://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements – freedomn-m Oct 07 '16 at 17:55
  • That's the right track. These html tags are loaded via async ajax calls, so you might have something there and you might want to offer it as an answer. – user192632 Oct 07 '16 at 17:55

4 Answers4

1

Please change this to $(this) The this refers to something else

this refers to a DOM element and $(this) refers to the current jQuery object our code is wrapped in i.e $(this) would refer to the class holding our event handler while this refers to native JavaScript recalling that jQuery is a library(a child of JavaScript)

The this would refer to usage of pure JavaScript and $(this) would call our library object

  • Please add some explanation of why this code helps the OP. This will help provide an answer future viewers can learn from. See [answer] for more information. – Heretic Monkey Oct 07 '16 at 17:37
  • $(".driverSection").click(function () { toggleDriver($(this)); }); doesn't seem to work. I have a breakpoint on the first line of toggleDriver function, but when I click on an instance of the driverSection class in the html, it should trap on breakpoint but it never gets there which means it's never called or it doesn't know who to effect – user192632 Oct 07 '16 at 17:46
  • Using **$(this)** in the **toggleDriver()** would refer to the toggleDriver() store the $(this) in a variable like this : `var $this= $(this);` then call the $this inside the `toggleDriver($this)` – Abolarin stephen Oct 07 '16 at 17:51
  • I think it's more because I am loading the html tags via dynamic ajax after page load like someone else has asked me about, so that "seems" to be where some of the problem lies as the click is often set up when those tags don't exist yet. – user192632 Oct 07 '16 at 17:57
1

Passe the jQuery object $(this) that refer to current clicked element.

Or use :

$("body").on('click', '.myClass', myFunction); //Using event delegation 'on()'
//OR 
$('.myClass').click( myFunction );

Then you could access the current object inside myFunction using $(this).

NOTE : if you want to use $(driver) then you could pass native javascript object using e.target like :

$("body").on('click', '.myClass', function (e) { 
    toggleDriver(e.target); 
})

Hope this helps.

Zakaria Acharki
  • 66,747
  • 15
  • 75
  • 101
1

try this :

jQuery(document).ready(function ($) {
    $(".myClass").click(function () { 
       toggleDriver($(this)); 
    });
}(jQuery));
Razib Al Mamun
  • 2,663
  • 1
  • 16
  • 24
1

Since the elements are dynamically loaded, you will need to use Event Delegation

It would look like the following:

$(function () {
  $(document).on("click", ".myClass", function () { 
       toggleDriver(this); 
   });
});
mhodges
  • 10,938
  • 2
  • 28
  • 46
  • Looks like this will work. Would I put that in document.ready? – user192632 Oct 07 '16 at 18:07
  • @ZakariaAcharki Missed that driver was getting jQuery wrapped inside the toggleDriver function. I have update my answer – mhodges Oct 07 '16 at 18:18
  • @user192632 Use this code in place of your document.ready. `$(function () {...});` is just a short hand version of `$(document).ready(...)` – mhodges Oct 07 '16 at 18:19