Search code examples
jqueryhtmlbackbone.jstraversal

JQuery returning empty arrays when using find() and children()


I've been having some problems lately with traversal in jQuery. We have a web app, and there are multiple panels that each have a header and a body. In the header, there is a button that is used to expand/collapse the body of the panel. The panels are set up similar to this:

<div id="panel-1" class="panel">
  <div class="panel-header>
      <span>Header Text</span>
      <div class="toggle-expansion"></div>
  </div>
  <div class="panel-body">...</div>
  <div class="panel-footer">...</div>
</div>

<div id="panel-2" class="panel"> ... </div> 
...

We are using Backbone.js to set up all the views, and there is a file named base-panel-view.js that all of the other panels extend from. I would like to put my function here if possible so I don't have to rewrite the function for every panel. Here is a snippet of the base-panel-view.js file:

...
       events: {
              ...
              "click .toggle-expansion" : "toggleExpansion"
       },
...
toggleExpansion: function() {
              var panel = $(this);                                   //Returns the entire panel
              var panelBody = panel.children(".panel-body");         //Should return the panel body
              var toggleButton = panel.find(".toggle-expansion");    //Should return the toggle button


              if(panelBody.hasClass("noDisplay")){
                     /* If the panel is collapsed, expand it */
                     panelBody.removeClass("noDisplay");
                     toggleButton.addClass("expanded").removeClass("collapsed");
              }else{
                     /* If the panel is expanded, collapse it */
                     panelBody.addClass("noDisplay");
                     toggleButton.addClass("collapsed").removeClass("expanded");                
              }             
       }
...

The panel variable gets set to the entire panel, which is what I expected, however panelBody and toggleButton are left empty. In the Chrome debugger, I am able to confirm that panel is containing the correct panel for whichever button I press, and I can see that the other variables are empty arrays. In the debugger, I can view panel's array containing it’s children, which includes the panel body, and header (which contains the button).

Is there something obvious that I’m doing wrong or not doing? I'm still relatively new to Javascript and jQuery, so it's entirely possible I'm messing up some fundamental step. Any help would be greatly appreciated.

Also I can confirm that the css is correct, since I made two buttons elsewhere that expand/collapse all panels, and I select the panel bodies there by using $(".panel-body"). However for this question, I am only concerned with the panel for the corresponding button that was pressed.


Solution

  • EDIT: I see now that you're using Backbone. Looking at this, you can see that this is the Backbone View, not a DOM element. To get the jQuery element, you have to use this.$ as seen in the code in that link, not $(this).

    EIDT2: For any future readers, this was the problem, but not the exact solution. The OP was able to (as mentioned in the comments), replace this:

    var panel = $(this);
    

    with this:

    var panel = this.$el;
    

    And everything worked accordingly.