I am new to Ionic, and AngularJS. Though very familiar with vanilla JS and jQuery.
I am trying to create a two column layout that contains cards of varying height. Using the standard ion-grid element there is the obvious problem of whitespace:
This is a known issue, and a common method is the “Masonry” layout. I have come across Desandro’s library, and an angularjs directive that supposedly implements it. However none of these seem to be for the recent version of Angular, and I get errors when using them (simple things like “angular is not defined”).
I have attempted to use pure CSS to solve the issue:
.masonry-group { /* Masonry container */
column-count: 2;
column-fill: balance;
}
.masonry-item { /* Masonry bricks or child elements */
width: 100%;
}
However, column-fill doesn’t want to work, and so I end up with the elements appearing out of order:
Notice the order is moving down the left column to the bottom, then starting at the right column.
My goal is to create a layout similar to the above, however with the order reading left to right:
I know this is quite simple with external JS libraries, if I were working on a website it would be very straight forward. However after introducing AngularJS into the mix I’m not sure how to even import external libraries, let alone make use of them in my components.
Is there a way to achieve a Masonry style layout with native ionic elements? If not, does anyone have any tips on how to implement a Masonry library to apply it to my manually created layout?
Not helping with your problem, but: If you are using Ionic (vs. Ionic v1) you are actually working with Angular, not AngularJS which is (confusingly) a totally different things.
Thanks for clarifying that. By some fluke I’ve been reading the correct documentation over at angular.io luckily. To any other readers, just assume whenever I say AngularJS I am referring to Angular
One of my general design rules is to write controller code so that writing templates is as easy as possible. To that end, in this case, I would split the backing array into two in the controller: say odds
and evens
. That way you can have two separate ngFor
loops, one for each column, and your items will appear in the desired order.
I had the same idea and developed this, the problem was simply using odd/even led to one column being larger than the other. So the next step was to consider the height of the container when adding elements to always add the card to the “shortest” column.
This couples the view into the model, which I didn’t like. On top of that, new cards are added in batches (lazily loaded), and the view doesn’t update immediately as each item is added to the bound collection. So as each item was added in, the height was not updated immediately, causing all new items to go into one column.
Ultimately my solution was to simply import Desandro’s Masonry library. This gives me the desired layout and flow. With one final minor issue. The Masonry plugin makes use of a secondary plugin called “imagesLoaded”, this allows a card to be added to the view only after it has loaded the image within it. This is a good thing because the view won’t display properly if images are changing the height of the card after being added, but for me it means the cards are now being added out of order. Their order determined by how fast they load.
I’m not quite sure how I’ll solve this last problem.
hi there,
have you finally found a solution to this problem?
I am looking to do the same.
I used the above library with an angular plugin.