Enumerating data-targets in ng-repeat - javascript

I have an accordion in my HTML that is dynamically populated as such -
<div class="accordion">
<div class="accordion-panel">
<div class="accordion-heading>
<a data-target="#collapse" data-toggle="collapse">{{x.header}}</a>
</div>
<div id="collapse" class="accordion-body">
....
</div>
</div>
</div>
The problem is that the data-target remains static. So all the open/close buttons only open one piece of the accordion! The solution would be to enumerate the data-target/ids based on $index, but I don't know how to do that.
Is there a way to enumerate attributes in the way that I described? Or is there another solution I can use?

Just replace data-target value with #collepse-{{$index}} and ID of body with 'collapse-{{$index}}'
Hope this might be helpful to you!!

Related

Trying to access a specific child div from a container div

I am having trouble with a little site I have been working on; I want a sort of "stream" container that holds "cards" of "content," where this "content" is some "text" as well as some "stats."
This is the HTML I currently have:
<div id="stream">
<div class="card">
<div class="content">content
<div class="text">
blahblahblah
</div>
<div class="stats">
blahblahblah
</div>
</div>
</div>
<div class="card">
<div class="content">content
<div class="text">
blahblahblah
</div>
<div class="stats">
blahblahblah
</div>
</div>
</div>
<div class="card">
<div class="content">content
<div class="text">
blahblahblah
</div>
<div class="stats">
blahblahblah
</div>
</div>
</div>
</div>
Eventually, I want users to be able to prepend "cards" to this "stream" as well.
Now, however, I am trying to implement some jQuery function to hide the "stats" of a card until it is clicked on. So after setting display to none in CSS of the stats, I made this in a javascript file:
$(document).ready(function(){
$("#stream, div.card").click(function() {
$(this).find($("div.stats")).show();
});
});
It sort of works; the stats of a card are hidden until I click on a card. When I click on a card, however, all the cards' stats divs are shown.
I was hoping to somehow make it that the specific card clicked is also the (only) one that gets shown. Obviously, the current way I am doing this opens all of them as jQuery I have selects all the cards at once; how can I remedy this?
Again, I apologize if this question has been asked; I could not seem to find something similar, and I really want this to work . . .
P.S. I tried to search for this particular instance; alot of suggestions were to just give divs ids, but this feels inconvenient when I eventually want users to prepend cards?
Your selector ->
"#stream, div.card"
was basically asking for all #stream and all div.card..
But what you really meant was, find all div.card inside #stream. and this would be, (aka without the ,).
"#stream div.card"
Also you jquery find doesn't require you to convert into a jquery object, so find("div.stats") will do the trick.

materializecss collapsible panel with a different html structure

I'm trying to create a custom collapsible panel using materialize but I don't know why the button is not triggering and showing the panel body. I have created a fiddle with my custom example that doesn't work and one materilaize example with their structure that works.
From my inspect I saw that the active class is not being added on panel body while clicking on panel header which is quite strange.
So if anyone can help me with that please ... modifying materialize components is like a pain in the ass !
<div class="collapsible">
<div class="box">
<div class="1left">Left</div>
<div class="2center">Center</div>
<div class="3right">Right
<a class="collapsible-header">Colapse header</a>
</div>
</div>
</div>
<div class="collapsible-body">
This should be the body collapsed
</div
http://jsfiddle.net/zt5515zt/90/
In Materialize you need both collapsible-header and collapsible-body at the same level in order to make Collapsible work.
Just Change the level of you collapsible-body as shown below and it will work.
<a class="collapsible-header">Colapse header</a>
<div class="collapsible-body">
This should be the body collapsed
</div>
Hope this helps you solve the problem.

ng-repeat repeats the div the directive is on

I have the following code:
<div ng-repeat="item in selectedCategory">
<div class="repertoire-composer">
<div data-toggle="collapse" data-target="#compositions{{$index}}"
class="repertoire-composer-title">
<span class="fa fa-chevron-right"></span>
{{item.composer}}
<span class="fa fa-plus"></span>
</div>
<div id="compositions{{$index}}" ng-repeat="composition in item.compositions" class="repertoire-compositions collapse">
<div class="repertoire-composition">
{{composition}}
<span class="fa fa-remove" title="Remove"></span>
</div>
</div>
</div>
</div>
So what I basically want is to have a tree of multiple .repertoire-composer divs, each of which with one or many child .repertoire-composition inside its .repertoire-compositions div. So in the second repeat, angular should create one or more .repertoire-composition divs. However, what it seems to do is create more divs of the one the directive is on. Hope I've been explicit enough, here's the unwanted result:
So basically, why is my .repertoire-compositions div getting duplicated?
EDIT:
I was misunderstanding ng-repeat. This is the intended behaviour of it: to repeat the element the directive is on. Thanks for the clarification.
.repertoire-compositions is not being duplicated it's being actually ng-repeated by this part of your template:
<div id="compositions{{$index}}" ng-repeat="composition in item.compositions" class="repertoire-compositions collapse">
I guess it's because of the second ng-repeat on item.compositions, can you provide a set of data ?
I'm not sure but you can try this in the inner repeater:
<div id="compositions{{$index}}" class="repertoire-compositions collapse">
<div class="repertoire-composition" ng-repeat="composition in item.compositions">
{{composition}}
<span class="fa fa-remove" title="Remove"></span>
</div>
</div>

Selecting nested elements

I have a page hierarchy like this:
<div class="panel" attribute-id="1">
<button class="delete">
<div class="panel" attribute-id="2" association-id="20">
<button class="delete">
</div>
</div>
....
So I have a bunch of these panels with nested panels inside, and I'm trying to create on on click handler for the delete buttons of the top level panels only (so the ones immediately inside panels that do not have an association id). The only different between the parent and child panels is that the child ones have the extra attribute "association-id".
So I can select the top level panels only like so:
$('.panel[attribute-id]:not([association-id]')
But if I try to get the delete buttons from from these like:
$('.panel[attribute-id]:not([association-id] .delete')
Obviously I'm still going to get the child buttons.
I can't modify the html in anyway, how could I go about doing this?
$(':not(.panel[attribute-id][association-id]) > .delete')
seems to do the trick.
jsfiddle
I've changed .panel-group to .panel to get it to work with the HTML provided.
Wrap them all in a div and assign that div a unique class. Then you can use jquery selector ".panel-group > .panel" to get only direct children of top level.
<div class="panel-group">
<div class="panel" attribute-id="1">
<button class="delete">
<div class="panel" attribute-id="2" association-id="20">
<button class="delete">
</div>
</div>
<div class="panel" attribute-id="11">
<button class="delete">
<div class="panel" attribute-id="12" association-id="120">
<button class="delete">
</div>
</div>
</div>
You can use the children method:
$('.panel-group[attribute-id]').children('button').first()

Using eq() and find() to add a class

I have a few divs within a containing div, eg:
<div id="container">
<div class="itmeholder">
<div class="item">
</div>
</div>
<div class="itmeholder">
<div class="item">
</div>
</div>
<div class="itmeholder">
<div class="item">
</div>
</div>
<div class="itmeholder">
<div class="item">
</div>
</div>
</div>
I want to add a class to the 2nd 'item' div, so I created:
$('#container:eq(1)').find('.item').addClass('newclass');
This isnt working. I have also tried using nth-child() as well, also to no avail.
Can anyone suggest to me a better way of going about this?
May be this is what you want:
$('#container').find('.item').eq(1).addClass('newClass')
Your are missing # for id selector, also need to modify the selector.
Live Demo,
$('#container .itmeholder:eq(1)').find('.item').addClass('newclass');
try this
$('#container').find('.item').eq(1).addClass('newclass');​
First, you target the container separately:
$('#container')
Then fetch its children, limiting it to only the 2nd child:
.children(':eq(1)')
The perform the rest of your search and action:
.find('.item')
.addClass('newclass');
Complete code:
$('#container')
.children(':eq(1)')
.find('.item')
.addClass('newclass');
$('#container .itmeholder:eq(1)').find('.item').addClass('newclass');
First find the inner element childs and use eq to find the required item and add class to it

Categories