JQuery add class dynamically to first element with a particular class - javascript

I have dynamically created bootstrap accordions containing dynamically created groups in each. I want to add the in class to the first group in each accordion, which opens it as you can see in the linked bootstrap example.
<div class="panel panel-default">
<div class="panel-heading">
<h6 class="panel-title">
<a class="accordionToggle" data-toggle="collapse" data-parent="#dynamicId" href="#dynamicId">
Title
</a>
</h6>
</div>
<div class="panel-collapse collapse" id="dynamicId">
...
</div>
</div>
...
There can be any number of .panel.panel-default which can contain any number of .panel-collapse.collapse
Here is what I have tried, as well as some other variations, to add the in class to the first .panel-collapse.collapse of each .panel.panel-default but I keep ending up with it adding the class to each one and not just the first.
$(".panel.panel-default").each(function (index) {
$(this).children(".panel-collapse.collapse:first").addClass("in");
});
$(".panel.panel-default").each(function (index) {
$(this).find(".panel-collapse.collapse:first").addClass("in");
});
$(".panel.panel-default").each(function (index) {
$(this).children(".panel-collapse.collapse").first().addClass("in");
});
Any help will be appreciated!

You need to iterate the panel-group, because I think what you are trying to do is to expand the first item in each accordion
$(".panel-group").each(function (index) {
$(this).children(".panel-collapse.collapse:first").addClass("in");
});
Demo: Fiddle

Simply add this:
$(document).ready(function(){
$(".panel-collapse.collapse:first").addClass("in");
});
It works for me.

Related

Expanding an accordion and scrolling to a section after expansion

I have a comments section and a review form at the bottom of the comments section. I have the entire comments section wrapped in a Bootstrap Accordion with the class of Collapse:
CODEPEN:
Check out the demo. Note clicking the "leave a review" link expands the review_form, but does not scroll to.
Working codepen
I've tried onClick="window.scrollTo(#review_form)", but that does not work.
Basic HTML:
<div class="review-collapse">
<button class="woocommerce button review-button" data-toggle="collapse" data-target="#commentList" aria-expanded="false" aria-controls="commentList">SHOW ALL REVIEWS'</button>
</div>
<div class="collapse" id="commentList">
<div class="leave-review">
<a data-toggle="collapse" data-target="#review_form_wrapper" aria-expanded="false" aria-controls="review_form_wrapper" onClick="window.scrollTo(#review_form)">Leave a review?></a>
</div>
<ol class="commentList">
//Comments here
</ol>
<div id="review_form_wrapper" class="collapse">
<div id="review_form">
//review form to be expanded
</div>
</div
I want to focus on the a in .leave-review: I would like to expand the #review_form_wrapper on click, and then scroll to the section immediately after. I can get the form to expand, but I cannot get the form to scroll into view.
Any suggestions? I would like to use Vanilla JS if possible, but jQuery is fine as well.
I was able to fix this by not using window.scrollTo(#reviewForm) but the scrollIntoView() method. I had to check if the #review_form_wrapper had the class of show before scrolling, which I used a setTimeout() for:
function productReviewJS() {
const link = document.querySelector("#scrollToReview");
link.addEventListener("click", function () {
window.setTimeout(function () {
if (reviewForm.classList.contains("show")) {
form.scrollIntoView({ behavior: "smooth" });
}
}, 400);
});
}
productReviewJS();

angularjs expand all accordion inside ng-repeat

I am getting data from a service, so the number of accordions will be variable. I used ng-repeat to dynamically display the accordion
<div ng-controller = "groupController">
<div ng-repeat = "groups in groupNames">
<div class = "panel-group" id = "accordion">
<div class = "panel panel-default">
<div class="panel-heading">
<div class = "panel-title">
<a data-toggle= "collapse" data-parent="#accordion" href="#collapse{{$index}}"> {{groups.team}} </a>
</div>
</div>
<div id="collapse{{$index}}" class = "panel-collapse collapse">
<div class = "panel-body">
<!-- display some data in the panel body -->
</div>
</div>
</div>
</div>
</div>
<button class = "btn btn-primary">collapseAll</button>
<button class = "btn btn-primary">expandAll</button>
</div>
How do I achieve collapse all and expand all using the controller. The answers that I found mainly solved the accordion provided by ui-bootstrap. In particular how do I manipulate the hrefs in angularjs to get collapse all and expand all?
At first you should remember to set close-others=false for your accordion, because in ui-bootstrap it is close-others=true by default which means that you can only expand one group at a time.
Then you can control the is-open property of the accordion-group by binding it to some variable in your controller. And then link the buttons to some function in your controller that set all these variables to be true or false.
Here is an example on Plunker.

Bootstrap 3 collapsible panel without id or data

I need to handle panel collapse behavior without using ID or data attributes. Ideally by setting a "collapsible" class on the parent div that can collapse its content, and a click on the heading should trigger the collapse
Here's the target HTML I'd like to write to handle collapse behavior automatically
<div class="panel-group collapse-all-but-one">
<div class="panel panel-primary panel-collapsible>
<div class="panel-heading">Click me to collapse</div>
<div class="panel-body">I will collaaaaaaapse</div>
</div>
<div class="panel panel-warning panel-collapsible">
<div class="panel-heading">Hey another one</div>
<div class="panel-body">I will close when the other one opens</div>
</div>
</div>
Here's my magic piece of code (the ready stuff ensures compatibility with rails/angularJS)
var ready
ready = function(){
$(".panel-collapsable")
.children(".panel-heading")
.click(function(){
var group = $(this).parent().parent()
if (group.hasClass("panel-group one-at-a-time")){
group.children(".panel").children(".panel-body")
.collapse('hide')
}
$(this)
.next('.panel-body')
.collapse('toggle')
})
}
$(document).ready(ready);
$(document).on('page:load', ready);
Remember to add some bootstrap classes like .collapse .in or .collapsed to initialize correct behaviour or the first click isn't going to do anything.
<div class="panel-body collapse in">I am expanded on page load</div>
...
<div class="panel-body collapse">I am collapsed on page load</div>

Bootstrap 3 Collapse - changing the glyphicon in the panel heading depending on collapse state

I know that this has been asked several times but I cannot get any of the answers to work in my code.
I am using Bootstrap 3 panels and collapse to show adverts. In the basic view, only the advert heading is shown together with a chevron down glyph to indicate that there is more information.
When the user clicks on the chevron-down, the main panel body containing the advert text is shown. At this point, I would like the chevron-down glyph to change to a chevron-up glyp.
I am using the following code:
<script language="JavaScript" type="text/javascript">
$('#Advert').on('show.bs.collapse', function(){
$('#Glyp-Advert').removeclass('glyphicon glyphicon-chevron-down').addclass('glyphicon glyphicon-chevron-up');
});
$('#Advert').on('hide.bs.collapse', function() {
$('#Glyp-Advert').removeclass('glyphicon glyphicon-chevron-up').addclass('glyphicon glyphicon-chevron-down');
});
</script>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a id="Heading-Advert" data-toggle="collapse" data-parent="#accordion" href="#Advert">
Heading
<span class="pull-right"><span id="Glyp-Advert" class="glyphicon glyphicon-chevron-down"></span></span>
</a>
</h4>
</div>
<div id="Advert" class="panel-collapse collapse">
<div class="panel-body">
Advert text<br />
</div>
</div>
</div>
This succeeds in displaying the main advert panel but will not change the glyph.
Any help would be appreciated. Note that the page will contain several adverts; so I intend to repeat the above code several times on the page but change the id's to contain the word 'Advert1' or 'Advert2' etc instead of just 'Advert'.
JavaScript is case-sensitive.
As such, your calls to removeclass and addclass are invalid because removeClass and addClass are the actual method names (notice the capital 'C' in each name).
Your code works otherwise. See http://jsfiddle.net/wilsonjonash/SXYZ2/
The answer from Jonathan Wilson was spot on BUT it failed to mention that the script needs to be AFTER the html and not before in my sample code.
Therefore, the correct code should be
<div class="panel panel-default"><div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<a id="Heading-Advert" data-toggle="collapse" data-parent="#accordion" href="#Advert">
<span class="pull-right"><span id="Glyp-Advert" class="glyphicon glyphicon-chevron-down"></span></span>
Heading
</a>
</h4>
</div>
<div id="Advert" class="panel-collapse collapse">
<div class="panel-body">
Advert text<br />
</div>
</div>
</div>
<script language="JavaScript" type="text/javascript">
$('#Advert').on('show.bs.collapse', function(){
$('#Glyp-Advert').removeClass('glyphicon glyphicon-chevron-down').addClass('glyphicon glyphicon-chevron-up');
});
$('#Advert').on('hide.bs.collapse', function() {
$('#Glyp-Advert').removeClass('glyphicon glyphicon-chevron-up').addClass('glyphicon glyphicon-chevron-down');
});
</script>
You don't necessarily need Javascript. You can do this with a few CSS styles. Here's how I've done it.
Make sure all your panel-title a links have this class: accordion-toggle
Add this CSS to your style sheet:
.
/* symbol for open panels */
.panel-heading .accordion-toggle:after {
font-family: 'FontAwesome';
content: "\f068";
float: right;
color: #474747;
}
/* symbol for closed panels */
.panel-heading .accordion-toggle.collapsed:after {
content: "\f067";
}
Note, I've used FontAwesome here, but you can change the font and characters to whatever you need, such as up and down chevrons.

Change text in the anchor tag while typing in text input in Jquery

Ok, this sounds easy, but I'm having problems trying to identify the anchor tag. The HTML block repeats itself.
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#q1">
Question 1
</a>
</h4>
</div>
<div id="q1" class="panel-collapse collapse">
<div class="panel-body">
<div class="form-group">
<label for="inputQ1" class="col-sm-2 control-label">Question</label>
<div class="col-sm-7">
<input type="text" class="form-control" id="inputQ1" placeholder="e.g How was our service?">
</div>
</div>
</div>
</div>
I got the answer I need over here
how to show text while typing in textarea in jquery
What I need to know is, how do I make it so that the text in the anchor tag changes? I don't want to put in an ID for all of them. I should be using parent() and siblings(), right?
Try
jQuery(function ($) {
$('.panel-body input').keyup(function(){
$(this).closest('.panel-collapse').prev('.panel-heading').find('a').text(this.value)
})
});
Demo: Fiddle
Note: To be more specific I might add an additional class as shown in this fiddle
You can do this with keyup and html:
$(document).ready(function(){
$("#text").keyup(function(){
$("#q1").html($(this).val());
});
});
Where #text is the textarea and #q1 is the anchor:
JSFiddle
You can use:
$('#inputQ1').keyup(function(){
var $this = $(this);
$this.closest('#q1').prev().find('a').html($this.val());
});
Fiddle Demo
I think the best (because the logic) if you could create a parent around this code (if you can)
<div class="parent">
<h4>
<a>...</a>
</h4>
<div>
<input>
</div>
</div>
in the event $(this) is your input
you can use $(this).closest('parent').find('a') to find the for the
Try using anchor parent:
$('.panel-title a').text( /* textarea text */ );
try this
$('.panel-title a').text( 'new text' );

Categories

Resources