How to create a responsive (varying column count) Angular-Material card grid - angularjs

I'm trying to create a grid of Angular-Material cards that behaves somewhat like a Bootstrap grid. Ideally, cards will be full-width for small screen widths and jump to two columns at larger breakpoints.
Demo with 2 cards
The problem is that A-M creates columns for each card. I haven't figured out how to specify the number of columns for each breakpoint.
Demo with 5 cards
Here's the basis of the markup I'm using, which takes the card layout from rows to columns at the first breakpoint:
<div ng-app layout="column" layout-gt-sm="row" class="layout-sm-column layout-row">
<div flex class="flex" ng-repeat="i in [1,2,3,4,5] track by $index">
<md-card>
There's a similar question on SO already, but accepted answer is unsatisfactory as it uses custom CSS and the cards aren't fluid-width. I've found no other similar examples.
I suppose I could loop every two cards with Angular and create stacked sets, but that seems needlessly cumbersome. I have to think that Material provides for a better solution. Also, such solutions would leave whitespace in the page where cards vary in height. Material seems geared toward a Masonry-like flex layout, and I'd like to stick with that.
Thanks.

You can use the material Grid-List, it allows for custom col-spans and animates the changes when the width changes.
I adapted the sample from the site and added md-card in the contents. Make sure to add layout-fill on the md-card.
You can easily adapt the sample for your column count.
http://codepen.io/anon/pen/QypjWY
I also adapted your 5 card sample. You need to know the height of the cards in order to use the Grid-List, but you can easily achieve the 100% height on small screens. You can use ratios or fixed CSS heights for the rows and then it is your cards job to display the content in a flexible way.
<md-grid-list ng-app="app" layout-fill flex
md-cols-sm="1"
md-cols-md="2"
md-cols-gt-md="5"
md-row-height-sm="100%"
md-row-height="600px"
md-gutter="8px">
<md-grid-tile ng-repeat="i in [1,2,3,4,5] track by $index">
<md-card layout-fill>
http://jsfiddle.net/2afaok1n/34/
Edit:
If you are instead looking for some kind of staggered grid, then you have to add a library: angular-deckgrid, it just provides the grid layout, everything in the content is angular-material. Unlike angular-masonry this library doesn't have any dependencies. If you are not worried about adding jQuery and the like then you can also use angular-masonry.
<div ng-app="app" ng-controller="DeckController" flex layout="column">
<deckgrid class="deckgrid" flex source="data">
<md-card>
The important part for the deck layout is the CSS configuration. With this you configure the number of columns and their width. I have used a media query for the angular-material sm breakpoint to switch to single column layout.
.deckgrid::before {
content: '4 .column.column-1-4';
font-size: 0;
visibility: hidden;
}
.deckgrid .column {
float: left;
}
.deckgrid .column-1-4 {
width: 25%;
}
.deckgrid .column-1-1 {
width: 100%;
}
#media screen and (max-width: 960px) {
.deckgrid::before {
content: '1 .column.column-1-1';
}
}
http://jsfiddle.net/2afaok1n/39/
Edit 2:
There is also a masonry version which doesn't require jQuery and a simple directive to use it: angular-masonry-directive. Here is an example, it works similar to the other one.
http://jsfiddle.net/xjnp97ye/1/

if i understood your question right
Then use this code and replace the hello with anything you like
<md-grid-list md-cols-lg="12" md-cols-gt-lg="15" md-cols-xs="3" md-cols-sm="6" md-cols-md="9" md-row-height-gt-md="1:1" md-row-height-md="1:1" md-row-height="1:2" md-gutter-gt-md="16px" md-gutter-md="8px" md-gutter="4px">
<md-grid-tile ng-repeat="contact in contacts" md-colspan="3" md-rowspan-gt-sm="4" style="background:red;">
hello
</md-grid-tile>
</md-grid-list>

If I understood the question right, this works like a charm:
<body ng-app="app" ng-cloak>
<div layout="column" layout-gt-sm="row" layout-wrap>
<div flex="25" flex-gt-sm="50" ng-repeat="i in [1,2, 3, 4, 5] track by $index">
<md-card>
<!-- You code-->
</md-card>
</div>
</div>
</body>
Plunker with multiple breakpoints : (resize the inner window, not the browser window)
http://plnkr.co/edit/8QPYdzLD8qzEbdz5sesE?p=preview
The plunker has been updated to show cards with different height.
2 directives have been made, so the biggest height of all cards is kept in memory and this one is applied to all cards.

<div ng-repeat="i in [1,2, 3, 4, 5] track by $index" flex-xs="100" flex-sm="50" flex-md="50" flex="33">
<md-card>
<md-card-title >
<md-card-title-text >
<span class="md-headline">Demo Title {{i}}</span>
<span class="md-subhead">Demo Description</span>
</md-card-title-text>
</md-card-title>
</md-card>
</div>
Check this example: http://codepen.io/ktn/pen/jqNBOe

Related

angular material layout conditional include

I am trying to understand Angular Material layout. I have a section of HTML that is always floated to the right and it contains several lines in a column. That section is rendered as expected when using a smaller device. However, when the device is a small hand-held, in addition to adjusting the right-floating section, I don't want to include some of the lines in that column.
For example, on a large screen device the layout would be:
left-panel middle-panel right-panel-line 1
right-panel-line 2
right-panel-line 3
and then on a small screen device the layout would be:
left-panel
middle-panel
right-panel-line 1
where the 2nd and 3rd lines in the right-floating panel is not displayed.
Question: how do I conditional use the Angular Material layout directives to do this?
Thanks,
-Andres
Available Plunker here
As you can see in angular-material layout extra options documentation, you can conditionally show and hide elements depending on the screen size.
Code for reference, see plunker for the complete details:
<div layout="row" layout-xs="column">
<div flex>left-panel</div>
<div flex>middle-panel</div>
<div layout="column" flex>
<div flex>right-panel-line 1</div>
<div flex hide-xs>right-panel-line 2</div>
<div flex hide-xs>right-panel-line 3</div>
</div>
</div>
Hope it helps.
Here you go - CodePen
Markup
<div ng-controller="AppCtrl" ng-cloak="" ng-app="MyApp" layout-fill layout-gt-xs="row" layout-xs="column">
<div style="background:red" flex></div>
<div style="background:green" flex></div>
<div flex layout="column">
<div style="background:purple" flex></div>
<div style="background:yellow" flex hide-xs></div>
<div style="background:cyan" flex hide-xs></div>
</div>
</div>
The trick is to use layout and hide depending on screen size.
https://material.angularjs.org/latest/layout/container
https://material.angularjs.org/latest/layout/options

how to create horizontal text carousel

This question might seem silly question. But I'm really stuck with it.
I am trying to create a carousel with above center title and below centered Description text. There are lot of example on google but I couldn't find anything appropriate.
I am using angular-material and there is no carousel implemented in angular-material till now.
there is awesome carousel in materializecss but when I am adding materialize in project lot of element CSS conflicting because of angular-material and materializecss.
then I decided to use some other directives like JK carousel it is not allowing me create text on image.
there is carousel in ui.bootstrap it also getting conflict with drop downs component.
Could anyone please tell me how can I achieve my requirement?
I have to use angular-material, there's no other choice. So any help using angular-material will be a great support.
I am currently using angular 3d carousel in my angular-material project. It has html slide version. You can build all your angular material classes in that slide html.
<carousel3d-slide ng-repeat="slide in app.slides2 track by $index" ng-style="{'background': slide.bg}">
<div style="padding: 20px; color: #fff">
<md-card md-theme="{{ showDarkTheme ? 'dark-grey' : 'default' }}" md-theme-watch>
<md-card-title>
<md-card-title-text>
<span class="md-headline">Card with image</span>
<span class="md-subhead">Large</span>
</md-card-title-text>
<md-card-title-media>
<div class="md-media-lg card-media"></div>
</md-card-title-media>
</md-card-title>
<md-card-actions layout="row" layout-align="end center">
<md-button>Action 1</md-button>
<md-button>Action 2</md-button>
</md-card-actions>
</md-card>
</div>
</carousel3d-slide>

Dynamic Height Card display in Grid-list

I am using angular material to create my site. I would like to display my products in a grid list with each tile has a dynamic height so that the result should be in like this page https://www.tumblr.com/search/printify.
I tried to do something like
<div class="md-padding" layout="row" layout-xs="column" layout-wrap>
<div flex-xs="50" flex-sm="50" flex-md="33" flex-gt-md="25" ng-repeat="n in [0,1,2,3]">
<md-card md-whiteframe="4" ng-repeat="result in result[n] | limitTo:limit" >
......
</md-card>
</div>
</div>
it works fine in 4-col display. however when resizing the screen to md and display in 3-col, the 4th-column is display under the 1st-column and quite ugly.
I hv tried on Grid-list too but no clue, may anyone can help, please?
I'd recommend using md-grid list. I edited Codepen from the Angular Material site here: http://codepen.io/anon/pen/qZzmpa and added a card to the tiles. With just:
<md-card>
<md-card-content>
Hi I'm a card
<md-card-content>
<md-card>
inside the tiles and it's pretty close.
https://material.angularjs.org/latest/demo/gridList

Expanding tiles layout using Angular in responsive layout

I'm developing an Angular single-page app with a responsive layout. The current page I'm working on uses a tile-based layout that auto wraps extra tiles to the next row. The HTML is below and, in the responsive layout, it can show 1, 2, or 3 tiles per row depending on the width of the row (it positions them using floats).
<div class="tiled_panel">
<div class="tile_1">...</div>
<div class="tile_2">...</div>
<div class="tile_3">...</div>
<div class="tile_4">...</div>
<div class="tile_5">...</div>
...
</div>
Now each tile will be given a "Learn More" button. The design calls for a block to expand between the row of the selected tile and the row below. This block will be the full width of the row and will be closed when the user closes it or clicks on a different Learn More button.
My first thought was to arrange the HTML as below using ng-if to hide or display the expander divs but I can't figure out the CSS needed to have it display between the rows.
<div class="tiled_panel">
<div class="tile_1">...</div>
<div class="expander_1">...</div>
<div class="tile_2">...</div>
<div class="expander_2">...</div>
<div class="tile_3">...</div>
<div class="expander_3">...</div>
<div class="tile_4">...</div>
<div class="expander_4">...</div>
<div class="tile_5">...</div>
<div class="expander_5">...</div>
...
</div>
My second thought, since I'm using Angular, was to somehow use transcluding or including to insert the relevant HTML into the appropriate spot. Again, I can't figure out how to identify where I need to insert the HTML?
I've tried searching around for other people's solutions to similar problems since I figured its not that unusual a requirement but I haven't yet been able to find anyone else who is doing this.
Can anyone else suggest what I need to do to identify the where to insert the HTML or how to generate the CSS? Or even suggest another solution that I haven't considered yet?
Although I have 70% understand of what you mean, I think ng-class can simply solve what you've faced. The solution code is like below. And I setup jsfiddle.
Html looks like this.
<div ng-app="" ng-controller="MyCtrl">
<div class="tiled_panel">
<div>Tile 1 <a href ng-click="change_tile(1)">More</a></div>
<div class="expander" ng-class="{'close': opentile===1}">Expander 1<a href ng-click="change_tile(-1)">Close</a></div>
<div>Tile 2 <a href ng-click="change_tile(2)">More</a></div>
<div class="expander" ng-class="{'close': opentile===2}">Expander 2<a href ng-click="change_tile(-2)">Close</a></div>
</div>
</div>
Your controller code looks like this.
$scope.change_tile = function(value){
$scope.opentile = value;
}
$scope.change_tile(0);
Css looks like this.
.expander{
visibility: hidden
}
.close{
visibility: visible
}

Angular Carousel around div with functionality

I'm looking for a Angular Carousel there is working with Bootstrap divs
I want it to shift between Divs, and I get the next div in center when clicking next or previous.
Bootstrap exsampel til wrap with carousel:
<div class="row">
<!-- Carousel start -->
<div class="col-md-1 col-sm-6">
<div class="box box-lg br-black animated">
<div class="box-content box-default">
Functionality 1
</div>
</div>
</div>
<div class="col-md-8 col-sm-6">
<div class="box box-lg br-black animated">
<div class="box-content box-default">
Functionality 2
</div>
</div>
</div>
<div class="col-md-1 col-sm-6">
<div class="box box-lg br-black animated">
<div class="box-content box-default">
Functionality 3
</div>
</div>
</div>
<!-- Carousel end --></div>
What possibilities do I have?
your question is a little confused to me. I understood your question but the code show something different. I will try to answer you the question with several alternatives. If you could be more specific with your problem I will help you quickly.
First, there are several carousel for AngularJS. There are single libraries that creates carousel, and others like ui-bootstrap(angular-ui) and AngularStrap that fit much better with Twitter Bootstrap. If you want to use AngularJS with TB, I recommend you ui-bootstrap. I have worked several times with the library and never let me down.
So, creating the carousel with ui-bootstrap we have several alternatives. First, to place the content of your divs in the center you have not use the grid system obligatory. You can use a single row and center the elements with text-align, margin:0 auto, flex model or others techniques. In this case check the next plunk:
http://plnkr.co/edit/XmzaJx5mXddLQ4S1k7BV
If you want to create each div with columns of the grid system, like your code shown, you have to shift the columns with .col-md-offset-x, leaving the same space at the sides. Check the plunk.
http://plnkr.co/edit/ihpwrWC0p64eO1jiddl2
I hope that my answer help you at least a little, If your question is another please, let me know.

Resources