2

firstly here's the fiddle: http://jsfiddle.net/krish7878/rwz7egdz/1/

What I am trying to do is very simple, there are two div's on with class "panel-heading" and other with class "panel-collapse", there are two conditions,

Condition 1: if 'panel-collapse' has class 'collapse' add some html to 'panel-heading'

Condition 2: if 'panel-collapse' has class 'collapse' add some different html to 'panel-heading'

Here's the code:

HTML:

<div class="panel-heading">
Panel Heading
</div><!-- /.panel-heading-->
<div class="panel-collapse collapse">
    Panel Collapse with a just a collapse
</div><!-- /.panel-collapse -->
<br><br>
<div class="panel-heading">
Panel Heading
</div><!-- /.panel-heading-->
<div class="panel-collapse collapse in">
    Panel Collapse with collapse &amp; in 
</div><!-- /.panel-collapse -->

JS Code:

 $( ".panel-heading" ).next().hasClass(".collapse").append( "<i class='fa fa-plus'></i>" );

 $( ".panel-heading" ).next().hasClass(".collapse.in").append( "<i class='fa fa-minus'></i>" );

I am quite sure I am missing something in the js part. Any help would be appreciated.

2
  • Check the wording of your two conditions. They look conflicting to me. Commented Aug 21, 2014 at 1:18
  • Hi GregL, they seem okay. if panel-collapse has 'collapse' class, panel-heading should be added with some html. Commented Aug 21, 2014 at 1:22

2 Answers 2

3

You don't need to chain next and hasClass. You can just query next().

$(".panel-heading").next(".collapse:not(.in)")
                   .append("<i class='fa fa-plus'></i>");

$(".panel-heading").next(".collapse.in")
                   .append("<i class='fa fa-minus'></i>");

The above works in your fiddle.

For the reason why your initial solution failed, see @cgatian's answer.

EDIT: updated to reflect comment:

$(".panel-heading + .collapse:not(.in)").prev().append("<i class='fa fa-plus'></i>");
$(".panel-heading + .collapse.in").prev().append("<i class='fa fa-minus'></i>");

So why does this work? we are using the sibling operator to immediately find all .collapse/.collapse.in elements then traversing back up one element and appending to that.

Sign up to request clarification or add additional context in comments.

3 Comments

Hi Darko Z, they get added inside 'panel-collapse', any chance that they get added to 'panel-heading' instead?
@user3486430 that's a slightly different issue and would mean you are doing something along the lines of: $(".panel-heading").next().is(selector).previous(".panel-heading").append(...) but this is a pretty rubbish solution even though it would work. Optimally you would iterate through the .panel-heading array $(selector).each() and for each of them check that the next is appropriate and append the right html.
the reason that iterating through your headings is better is because you are doing less selection and can keep references to your elements instead of constantly reselecting.
3

The actual reason this failed is because you used:

.hasClass(".collapse")

There was an extra period within the method call. It should be:

.hasClass("collapse")

Has class does not need a selector, just the string of the class name


Update:

After the selector is fixed, hasClass() returns a boolean, not the elements that have the class. Building on @Darko Z's answer you need the following.

$( ".panel-heading" ).next(".collapse").append( "<i class='fa fa-plus'></i>" );

 $( ".panel-heading" ).next(".collapse.in").append( "<i class='fa fa-minus'></i>" );

http://jsfiddle.net/brrbq03L/

4 Comments

+1 for the actual reason, forgot to include that in my answer :)
@cgatian, thank you for the correction, but even after I change it, it does not work.
@user3486430 hasClass returns a boolean so it will never work in your case. api.jquery.com/hasClass you are trying to use a jquery method on a true/false value
Yeah @DarkoZ has the correct answer. I still feel like there should be an even better way to do this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.