Best way to loop the angular flex layout with two rows? - javascript

I would like to know how to do the ngFor with two rows in angular flex layout.
<div *ngFor="let item of items">
<div class="container" fxLayout fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap.xs="0">
<div class="item item-1" fxFlex="50%">
<div fxLayoutAlign="center" class="item-label">
{{item.name}}
</div>
<div fxLayoutAlign="center" class="item-value">{{item.value}}</div>
</div>
<div class="item item-2" fxFlex="50%">
<div fxLayoutAlign="center" class="item-label">
{{item.name}}
</div>
<div fxLayoutAlign="center" class="item-value">{{item.value}}</div>
</div>
</div>
<div class="container" fxLayout fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap.xs="0">
<div class="item item-3" fxFlex="100%">
<div fxLayoutAlign="center" class="item-label">
{{item.name}}
</div>
<div fxLayoutAlign="center" class="item-value">{{item.value}}</div>
</div>
</div>
</div>
Here its looping but each time its printing 3 values for every index. I would like to print index 0 value of first column, index 1 on second column and index 2 value on second row.

I've created for you an example on stackblitz, based on your requirements.
The correct way would be :
<div class="container" fxLayout="row wrap" fxLayoutAlign="center" fxLayoutGap.xs="0">
<!-- you can use ngClass to manage 'item-1' or 'item-2' style -->
<div class="item" fxFlex="50%" *ngFor="let item of items">
<div fxLayoutAlign="center" class="item-label">
{{item.name}}
</div>
<div fxLayoutAlign="center" class="item-value">{{item.value}}</div>
</div>
</div>
The wrap/nowrap property on the fxLayout directive does everything, because childs are set with fxFlex="50%".
I put out fxLayout.xs to render it correctly on stackblitz.
Here is #angular/flex-layout documentation
Hope it helps ;-)

The "wrap" parameter in the "fxLayout" is used to wrap the child content with the help of "fxFlex"

Related

how to ADD class in every to div using loop

This is my structure I want to add odd even class in every two divs so how can I achieve this structure using JavaScript loop i tried everything but i got nothing I am learning JavaScript loop so anyone please help me with this
var i = 0;
$('.CollectionInner__Products .Grid__Cell .ProductItem').each(function(i) {
var index = 0;
if (index % 3 == 0) {
$(this).addClass("odd");
}
});
<div class="custompsps">
<div class="ProductItem">
</div>
<div class="ProductItem">
</div>
<div class="ProductItem">
</div>
<div class="ProductItem">
</div>
</div>
<div class="custompsps">
<div class="ProductItem">
</div>
<div class="ProductItem">
</div>
<div class="ProductItem">
</div>
<div class="ProductItem">
</div>
</div>
I want this structure:
i want this stucture
<div class="custompsps">
<div class="ProductItem even">
</div>
<div class="ProductItem even">
</div>
<div class="ProductItem odd">
</div>
<div class="ProductItem odd">
</div>
</div>
<div class="custompsps">
<div class="ProductItem even">
</div>
<div class="ProductItem even">
</div>
<div class="ProductItem odd">
</div>
<div class="ProductItem odd">
</div>
</div>
$('.CollectionInner__Products .Grid__Cell .ProductItem').each(function(index, element) {
$(element).addClass(index & 2 ? "even" : "odd");
});
& is a bitwise "and". index & 2 would be 0 for index 0 and 1, and 2 for index 2 and 3, alternating like this. 0 is falsy and non-0 is truthy. (Your use of "even" and "odd" seem backwards, but I've followed your use.)
jQuery's .each accepts a callback that can take both an index and an element argument.

V-for iteration ruins the styles

I have a slider which consists of products.
Right now I'm getting a list of products from the server and populating that slider with the result returned from the server. For this I have the following
<div class="most_buy_slider container special_proposal">
<div v-for="product in mostBoughtProducts">
<div>
<div class="goods_item">
<img :src="product.ProductPreviewImages[0]">
<div class="name">
{{product.Name}}
<span>{{product.Manufacturer}}</span>
</div>
<div class="price">{{product.Price}} грн</div>
<div class="economy">економія складає 57% від роздрібної вартості</div>
<div class="to_cart">
<button type="button" class="btn but_blue">в кошик</button>
</div>
</div>
</div>
</div>
</div>
But this result in the following:
however, when I render simple html without v-for it loads correctly.
<div class="most_buy_slider container bigger_width special_proposal">
<div>
<div v-for="index in 10" class="goods_item">
<img src="images/samples/whiskyjackdan.png">
<div class="name">
Вологі серветки Вологі серветки Вологі серветки Вологі серветки
<span>Ruta Selecta Ruta SelectaRuta SelectaRuta Selecta</span>
</div>
<div class="price">
45,55 грн
</div>
<div class="economy">
економія складає 57% від роздрібної вартості
</div>
<div class="to_cart">
<button type="button" class="btn but_blue">в кошик</button>
</div>
</div>
</div>
<div>
<div class="goods_item">
<img src="images/samples/ruta1.png">
<div class="name">
Вологі серветки
<span>Ruta Selecta</span>
</div>
<div class="price">
45,55 грн
</div>
<div class="economy">
економія складає 57% від роздрібної вартості
</div>
<div class="to_cart">
<button type="button" class="btn but_blue">в кошик</button>
</div>
</div>
</div>
I don't know your CSS, but in first code snippet you included you use additional div for v-for directive, that can break your styles.
Try this code instead:
<div class="most_buy_slider container special_proposal">
<div v-for="product in mostBoughtProducts">
<div class="goods_item">
<img :src="product.ProductPreviewImages[0]" />
<div class="name">
{{ product.Name }}
<span>{{ product.Manufacturer }}</span>
</div>
<div class="price">{{ product.Price }} грн</div>
<div class="economy">економія складає 57% від роздрібної вартості</div>
<div class="to_cart">
<button type="button" class="btn but_blue">в кошик</button>
</div>
</div>
</div>
</div>
I finally solved the problem
I was using Slick slider to display items. While data is being loaded from the server, the slick slider already gets initialized with 0 item in it. And when items has been loaded from the server, vue.js inserts data into the slider, but the slider still assumes that it has 0 item.
So the solution is to reinitialize the slick slider when data loaded from the server.
I called the following after the data load:
reInit() {
$('.most_buy_slider').slick('unslick');
$(".most_buy_slider").slick(this.sliderSettings())
}
sliderSettings() {
return {
infinite: true,
slidesToShow: 4,
slidesToScroll: 1
}
}

How to dynamically highlight text in ngFor

I have a series of rows inside a ngFor.
<div *ngFor="let block of data;">
<div class="class-row">
<div class="left">A Label:</div>
<div class="right">{{block.key1}}</div>
</div>
<div class="class-row">
<div class="left">Another Label:</div>
<div class="right">{{block.key2}}</div>
</div>
</div>
It turns out that for some rows I would like to highlight {{block.key1}} or {{block.key2}} based on some logic.
Is there a way of doing this in angular 4+?
I thought of calling a component function and passing it the {{block.key1}} or {{block.key2}}, something like
<div *ngFor="let block of data;">
<div class="class-row">
<div class="left">A Label:</div>
<div [innerHTML]=highlight({{block.key1}}) class="right"></div>
</div>
<div class="class-row">
<div class="left">Another Label:</div>
<div [innerHTML]=highlight({{block.key2}}" class="right"></div>
</div>
</div>
but this is probably not possible.
Is there some way of changing the property of the text in the div dynamically?
Here is how you can do it. I assume when you talk about hightlight you mean CSS. If so you better use ngClass. Here is an example of how you can do it.
<div *ngFor="let block of data;">
<div class="class-row">
<div class="left">A Label:</div>
<div [ngClass]="[shouldHighlight(block.key2) ? 'highlight' : '']" class="right">{{block.key1}}</div>
</div>
<div class="class-row">
<div class="left">Another Label:</div>
<div [ngClass]="[shouldHighlight(block.key2) ? 'highlight' : '']" class="right">{{block.key2}}</div>
</div>
</div>
<!--You can also do it by this way -->
<div *ngFor="let block of data;">
<div class="class-row">
<div class="left">A Label:</div>
<div [class.highlight]="shouldHighlight(block.key1)" class="right">{{block.key1}}</div>
</div>
<div class="class-row">
<div class="left">Another Label:</div>
<div [class.highlight]="shouldHighlight(block.key2)" class="right">{{block.key2}}</div>
</div>
</div>
<style>
.highlight{
/* Your CSS Here*/
}
</style>
The answer by #Ulrich is correct, but I would like to expand on an alternative, that is easily missed.
That is: you are assuming you must call a function inside the ngFor. Well, this is true if you choose not to preprocess the data.
What I would try to do is preprocess data when loading it:
this.data.forEach(block => {
block.highlightKey1 = this.shouldHighlight(block.key1);
block.highlightKey2 = this.shouldHighlight(block.key2);
}
If you can extend the model to include also this extra fields, everything is smoother:
<div *ngFor="let block of data;">
<div class="class-row">
<div class="left">A Label:</div>
<div [ngClass]="[block.highlightKey1 ? 'highlight' : '']" class="right">{{block.key1}}</div>
</div>
<div class="class-row">
<div class="left">Another Label:</div>
<div [ngClass]="[block.highlightKey2 ? 'highlight' : '']" class="right">{{block.key2}}</div>
</div>
</div>
At runtime this solution is going to perform slightly better, because no function call is going to be made during change detection, but only at load.
I find it cleaner too, because no "complex logic" is going to be invoked directly by the template.

nested ng-repeat in angular js

repeat inside ng-repeat.
<li ng-repeat="(key,value) in OauthSwaggerData.paths " >
<div class="col col-100">{{key}}</div>
<div ng-repeat="APIDetails in OauthSwaggerData.paths['/key']">
<div class="col col-100"><h4>Summary</h4> </div>
<div class="col col-100">{{APIDetails.summary}}</div>
<div class="col col-100"><h4>Description</h4> </div>
<div class="col col-100">{{APIDetails.description}}</div>
<div class="col col-100"><h4>Parameters</h4> </div>
</div>
</li>
In the first line i want to display the keys which are available , which is working fine. In the second ng-repeat I want to pass the name of the key which i have selected.
e.g.
<div ng-repeat="APIDetails in OauthSwaggerData.paths['/token']"> .
When i hardcode this value i am getting the desired output. But i want to pass the "key " from the first loop in this second loop.
<div ng-repeat="APIDetails in OauthSwaggerData.paths['/key']">
which i not working fine.
Kindly help me to resolve the issue.
In your third line try:
<div ng-repeat="APIDetails in OauthSwaggerData.paths['/' + key]">
hope this help
<li ng-repeat="(key,value) in OauthSwaggerData.paths " >
<div class="col col-100">{{key}}</div>
<div ng-repeat="APIDetails in value">
<div class="col col-100"><h4>Summary</h4> </div>
<div class="col col-100">{{APIDetails.summary}}</div>
<div class="col col-100"><h4>Description</h4> </div>
<div class="col col-100">{{APIDetails.description}}</div>
<div class="col col-100"><h4>Parameters</h4> </div>
</div>

Use Kendo UI Flip Effects / Combined Effects for multiple items on the same page

I need to use kendo ui to display between 6-60 items. Each using the flip effect here http://demos.telerik.com/kendo-ui/fx/combined
The products will be loaded from the database with the unique id like this:
<div class="row">
<div class="col-md-4 product-container">
<div id="productID1" class="productID">
<div class="product">
<div id="product-back1" class="product-desc">
<p>BACK</p>
</div>
<div id="product-front1" class="product-image">
<p>FRONT</p>
</div>
</div>
</div>
</div>
<div class="col-md-4 product-container">
<div id="productID2" class="productID">
<div class="product">
<div id="product-back2" class="product-desc">
<p>BACK</p>
</div>
<div id="product-front2" class="product-image">
<p>FRONT</p>
</div>
</div>
</div>
</div>
<div class="col-md-4 product-container">
<div id="productID3" class="productID">
<div class="product">
<div id="product-back3" class="product-desc">
<p>BACK</p>
</div>
<div id="product-front3" class="product-image">
<p>FRONT</p>
</div>
</div>
</div>
</div>
The problem is I need multiple panels on the page how can I make each "front" and "back" click unique.
var el = kendo.fx($('div[id^=productID]')),
flip = el.flip("horizontal", $('div[id^=product-front]'), $('div[id^=product-back]')),
zoom = el.zoomIn().startValue(1).endValue(1);
flip.add(zoom).duration(200);
$('div[id^=product-front]').click(function () {
flip.stop().play();
});
$('div[id^=product-back]').click(function () {
flip.stop().reverse();
});
I've tried loading each item into an array but have not found a good way to assure the correct item will be flipped.
Since every div[id^=product-front] is a child of div[id^=productID], you can find the children of that and use it.
replace flip.stop().play(); with
kendo.fx($(this)).flip("horizontal", $(this).children()[0], $(this).children()[1]).stop().play();

Categories