I wonder if it is possible to open DOM element during first cycle of ng-repeat and close it during the second. Let's talk about some list of element, and I want to output it by 2 (or may be 3, 4... it does not matter) in a row. So result html will be like this:
<div class="row"> <!-- add this line during 1sr cycle -->
<div class="element">...element1...</div>
<div class="element">...element2...</div>
</div> <!-- add this line during 2nd cycle -->
<div class="row"> <!-- add this line during 3rd cycle -->
<div class="element">...element3...</div>
<div class="element">...element4...</div>
</div><!-- add this line during 4th cycle -->
The main problem that ng-repeat does not allows me to put line <div class="row"> on first cycle and put closing </div> on second cycle. ng-repeat add both of them during every cycle. Is it possible to find some workaround for this case?
It's not possible with ng-repeat. You have to either prepare the data structure in your controller (multi-dimensional array) or write a custom directive that would take and additional parameter of how many elements of the array take for the current iteration.
UPD: You can use lodash' chunk function to split the array into smaller arrays https://lodash.com/docs#chunk
As you said, you can't output only half an element (e.g. the opening tag without the closing tag) in one repeat cycle.
You can however do different things in one cycle based on the $index property, like showing or hiding a specific element in the first cycle ($index: 0).
Alternatively, have a look at ng-repeat-start and ng-repeat-end to output more than one element in a cycle. More info: https://docs.angularjs.org/api/ng/directive/ngRepeat
I have found simple solution out of the box in angularJs:
<div class="row" ng-repeat="element in elements" ng-if="$index%2==0">
<div class="element" ng-repeat="element in elements|limitTo:2:$index">...</div>
</div>
It will output 2 elements in a row, if you need more, you should adjust ng-if and limitTo argument.
Related
How do I add different classes for the inner elements in an ngFor loop in Angular 4? Say, I have a snippet:
<div *ngFor="let article of articles">
<div>
<h3>{{article.name}}</h3>
<p>{{article.body}}</p>
</div>
</div>
So I have 2 questions: how do I add different classes to the h3 elements in every generated article based on their order (first, second, third) and how do I add classes to the h3 elements based on odd-even order?
You can get the index, odd, and even of the current iteration in the ngForOf, combine that with ngClass and you can set the class.
<div *ngFor="let article of articles; index as i; even as isEven; odd as isOdd">
<div id="article">
<h3 [ngClass]="{'odd': isOdd, 'even': isEven}">{{article.name}}</h3>
<p>{{article.body}}</p>
</div>
</div>
You do not mention how you want to use the index/position so there is no code for that. I am sure you can figure that part out though based on the sample code above and documentation.
As #Paco0 also pointed out maybe you meant id="article" to be id="{{article.id}}" or something similar?
I'm dynamically creating jQuery UI sliders, using the following code in a forEach loop:
// Sets an id for the slider handles, gives them a custom class (makes them appear as circles, centers them)
$("#slideRange" + i).find(".ui-slider-handle").attr("id","slideHandle" + i).addClass("customSliderHandle");
// These two lines set the times below the slider handles.
$("#timeSlider" + i).find(".slideStartLabel").text(startTime);
$("#timeSlider" + i).find(".slideEndLabel").text(endTime);
This successfully makes the following slider, with variable times, for every iteration:
What I'd like to do, instead of showing the times below the circular handles, is have the times appear in the middle of the handles. The end result would look like this (photoshopped):
The times will then update, according to the slider values, within the "slide" event callback.
My question is: how do I assign unique id's to the two slider handles, so that I can then set their text independently in the "slide" callback? The code I wrote above gives both handles the same id. Using this id to set text to a handle will only apply to the first handle, leaving me no way to change the text of the second. Using find(), get(), or just $(".ui-slider-handle") are all ways of getting an array of the slider handles, but when I try attr("id","uniqueId") on one of the elements of that array, I get "(...).method(...) is not a method".
Or is assigning unique id's the wrong approach, here? Is there a jQuery or vanilla Js way of setting attributes of one element at a time, when searching by class and getting potentially multiple results?
Also, for context: I'm using find() because I'm using clone() on a markup shell, then appending it to a central div. Here's the shell:
<!-- This hidden div will be cloned, customized, and appended onto .modal-body -->
<div id="timeslotShell" class="timeslot row" style="display:none">
<div class="container-fluid slotContents" id="slotContents">
<span class="col-md-4"> Listing <div class="slotNumber listNum">*Listing No.*</div>: From <div class="slotNumber startNumber slotStartShell"> *Start Time* </div> until
<div class="slotNumber endNumber slotEndShell"> *End Time* </div> </span>
<div class="col-md-8">
<button type="button" class="btn btn-md btn-info slotButton">
Choose A Time From Within These Hours
</button>
</div>
<div id="timeSliderShell" class="collapse timeSlider">
<br><br>
<div id="slider-range" class="slideRange row"></div>
<div id="slideLabels" class="slideLabels slideRange row">
<div class="slideStartLabel"></div><div class="slideEndLabel"></div>
</div>
</div>
</div>
<br><br>
</div>
Cool -- as luck with have it, I found the answer shortly after posting this. Check this post if you're dealing with a similar issue:
Slider Value Display with jQuery UI - 2 handles
All that's needed, in the .find() calls, is
.find(".ui-slider-handle:first").text(value1);
for the first handle and then
.find(".ui-slider-handle:last").text(value2);
for the second.
I have an array a=[1,2,3,4,5,6].
Using ng-repeat on this array, I am creating 6 divs.
Please refer to this plunker
Is there any way to add one more div after each row. So after 3 divs I want to add one extra div.
I looked into this example. but they are creating a child div. is it possible to create a sibling div in ng-repeat
Let's try ng-repeat-start & ng-repeat-end.
<div class="example-animate-container">
<div class="square" ng-repeat-start="friend in a">
{{$index}}
</div>
<div ng-if="$index % 3 == 2" ng-repeat-end>
extra div
</div>
</div>
Please note that ng-repeat-start directive is included since angular 1.2.1.
plnkr demo
ng-repeat: repeat a series of elements of "one" parent element
<!--====repeater range=====-->
<Any ng-repeat="friend in friends">
</Any>
<!--====end of repeater range=====-->
ng-repeat-start & ng-repeat-end: using ng-repeat-start and ng-repeat-end to define the start point and end point of extended repeater range
<!--====repeater range start from here=====-->
<Any ng-repeat="friend in friends" ng-repeat-start>
{{friend.name}}
</Any><!-- ng-repeat element is not the end point of repeating range anymore-->
<!--Still in the repeater range-->
<h1>{{friend.name}}</h1>
<!--HTML tag with "ng-repeat-end" directive define the end point of range -->
<footer ng-repeat-end>
</footer>
<!--====end of repeater range=====-->
The ng-repeat-start and ng-repeat-end syntax was introduced for this exact purpose. See the documentation http://docs.angularjs.org/api/ng/directive/ngRepeat
So you'll do something like:
<div ng-init="a = [1,2,3,4,5,6]">
<div class="example-animate-container">
<div class="square" ng-repeat-start="friend in a">
{{$index}}
</div>
<div ng-repeat-end>Footer</div>
</div>
You can use a empty div as a container for your repeat. And then only render the child element's as squares (or what ever you want). This way, your extra div will be a sibling and not a child.
See my example: http://plnkr.co/edit/xnPHbwIuSQ3TOKFgrMLS?p=preview
take a look at this plunker here, could it be your solution? i don't understand really well your problem because i think it's better if instance your array in an external js file, but other than that take a look here plunker
I'm trying to expand a DIV element on my angular layout. I'm using angular-masonry to give a mason-style to my layout, but now I need to expand those boxes on click. I've tried a lot of stuff, but it kept overlapping my others elements. Soon figured out that I'll have to write it the "angular way" so I don't run into DOM manipulation conflicts.
Here's my code:
<div class="row" masonry>
<div
class="masonry-brick item-component col-sm-4 col-md-4"
ng-repeat="component in components.components | filter : components.filterByFilter | filter : searchText"
ng-click=" // expand #expandable // "
>
<div class="component-wrapper">
<div class="component">
<img ng-src="#{{ component.thumb }}"/>
</div>
<div class="component">
#{{ component.name_en }}
</div>
</div>
<div id="expandable" class="expand-me codes-wrapper">
<p>XXX</p>
<p>YYY</p>
<p>ZZZ</p>
</div>
</div>
</div>
Here's what I want to accomplish in the "angular way": http://codepen.io/desandro/pen/daKBo
In your example (http://codepen.io/desandro/pen/daKBo) if you click on an element there are two things that will be done:
(1) the style of the clicked item is changed
(2) the function masonry is called on the container element that keeps the divs.
I can't see such a function in angular-masonry pre builded. So i'll guess you have to do this by your self. Here are some hints how to solve this (i havn't try it in real)
Bind a function to ng-click. In this function set a state to the current component. This state shoud be used to toggle the css-class of the element. you can use ng-class for this.
The second part is little bit more complex. I would suggest write a direcive 'masonry-change-listener' and bind it to the element that is bound to the same element with the directive masonry. If you click on a component $emit an event, that something has changed. In the directive 'masonry-change-listener' listen to this event. if this event fires you have to call $element.masonry.apply($element) in the link function.
I have a positioning issue with my in expression engine. click Here On the following link I am looping elements with <div id="services-container"> I have noticed it loops fine on the first row however begins to misalign on the second row. I have made attempts to use the switch="" tag to create an individual class for each loop, see below:
{exp:channel:entries channel="services" dynamic="no" sort="asc|desc"}
<div id="services-container" class="{switch='1|2|3|4|5|6'}">
<div class="service-content">
<img src="{service_image}" alt="banner" alt="{alt}" class="service-banner">
<p>{service_head_line}</p>
{service_listed_items}
<ul class="service-credentials">
<li>{service_list_1}</li>
<li>{service_list_2}</li>
<li>{service_list_3}</li>
</ul>
<ul class="service-credentials">
<li>{service_list_4}</li>
<li>{service_list_5}</li>
<li>{service_list_6}</li>
</ul>
View related projects ยป
{/service_listed_items}
</div><!--service-content-->
</div><!--SERVICES CONTAINER-->
{/exp:channel:entries}
When i try to class these classes out in my style sheet nothing is happening. Does anyone know what i am doing wrong?
This involves ExpressionEngine but also css. Basically you are trying to create a grid with 3 items in each row, correct ?
Each of these "row" has to adopt a float containment strategy, since it only contains 3 floated items. The way I would go about it using the switch parameter:
{exp:channel:entries channel="services" dynamic="no" orderby="date" sort="asc"}
{if "{switch='one|two|three'}" == "one"}<div class="row">{/if}
<div class="item">
...code...
</div>
{if "{switch='one|two|three'}" == "three" || count == total_results}</div>{/if}
{/exp:channel:entries}
That code would include a div with a class of row every three items in that loop.
Then, if your items are floated, your rows must have some sort of float clearing strategy to contain them like overflow:hidden; or a clearfix method.