Jacksonkr
Jacksonkr

Reputation: 32227

How can I build this layout with AngularJS?

I'm using a ng-repeater to list items on my page. The issue is that sometimes I need special html containers around two items and sometimes I don't. Here's the result I need for a 6 item repeater (pseudo output):

<section class="AB">
    <group class="A">
        <item>item 1</item>
    </group>
    <group class="B">
        <item>item 2</item>
        <item>item 3</item>
    </group>
</section>
<section class="BA">
    <group class="B">
        <item>item 4</item>
        <item>item 5</item>
    </group>
    <group class="A">
        <item>item 6</item>
    </group>
</section>

Here are the rules I'm having to follow:

From the research of I've done on the web I think I need a custom directive. How can I get my current setup by using a repeater? Or do I need something else?

EDIT

Here's what the actual finished product will need to look like. Again, this is an example for 6 items, but it's dynamic so there could be 100+.

<div class="coupon-grid">
    <div class="ls">
        <div class="row">
            <div class="large col col-50">
                <div class="coupon">
                    <div class="bg" style="background:url(../img/img1.png) no-repeat; background-size:cover; background-position: center center;"></div>
                    <div class="mask purple"></div>
                    <div class="content">
                        <div class="logo">
                            <img src="../img/brand1.png" alt="" />
                        </div>
                        <p class="miles">2.1 Miles</p>
                        <p class="num-coupons">3 Coupons</p>
                    </div>
                </div>
            </div>
            <div class="col col-50">
                <div class="small row">
                    <div class="coupon">
                        <div class="bg" style="background:url(../img/img2.png) no-repeat; background-size:cover; background-position:center center;"></div>
                        <div class="mask green"></div>
                        <div class="content">
                            <div class="logo">
                                <img src="../img/brand1.png" alt="" />
                            </div>
                            <p class="miles">2.1 Miles</p>
                            <p class="num-coupons">3 Coupons</p>
                        </div>
                    </div>
                </div>
                <div class="small row">
                    <div class="coupon">
                        <div class="bg" style="background:url(../img/img3.png) no-repeat; background-size:cover; background-position:center center;"></div>
                        <div class="mask orange"></div>
                        <div class="content">
                            <div class="logo">
                                <img src="../img/brand1.png" alt="" />
                            </div>
                            <p class="miles">2.1 Miles</p>
                            <p class="num-coupons">3 Coupons</p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="sl">
        <div class="row">
            <div class="col col-50">
                <div class="small row">
                    <div class="coupon">
                        <div class="bg" style="background:url(../img/img2.png) no-repeat; background-size:cover; background-position:center center;"></div>
                        <div class="mask green"></div>
                        <div class="content">
                            <div class="logo">
                                <img src="../img/brand1.png" alt="" />
                            </div>
                            <p class="miles">2.1 Miles</p>
                            <p class="num-coupons">3 Coupons</p>
                        </div>
                    </div>
                </div>
                <div class="small row">
                    <div class="coupon">
                        <div class="bg" style="background:url(../img/img3.png) no-repeat; background-size:cover; background-position:center center;"></div>
                        <div class="mask orange"></div>
                        <div class="content">
                            <div class="logo">
                                <img src="../img/brand1.png" alt="" />
                            </div>
                            <p class="miles">2.1 Miles</p>
                            <p class="num-coupons">3 Coupons</p>
                        </div>
                    </div>
                </div>
            </div>
            <div class="large col col-50">
                <div class="coupon">
                    <div class="bg" style="background:url(../img/img1.png) no-repeat; background-size:cover; background-position: center center;"></div>
                    <div class="mask purple"></div>
                    <div class="content">
                        <div class="logo">
                            <img src="../img/brand1.png" alt="" />
                        </div>
                        <p class="miles">2.1 Miles</p>
                        <p class="num-coupons">3 Coupons</p>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Upvotes: 0

Views: 64

Answers (2)

Jacksonkr
Jacksonkr

Reputation: 32227

I ended up using a complicated directive. Code is as follows

html

<div class="coupon-grid" coupons-repeater="locations"></div>

directive

.directive("couponsRepeater", function($compile) {
    return {
        restrict: 'A',
        scope: {
            locations: '=couponsRepeater'
        },
        link:function ($scope, $element, $attr) {
            $scope.$watch(function() {
          return $scope.$parent[$attr.couponsRepeater];
        }, function() {
          var locations = $scope.$parent[$attr.couponsRepeater];
          var html = '';

          for(var i in locations) {
            var o = locations[i];

            if(i%6==0) { 
              var arrange = 'ls';
              if(i%6==3) {
                arrange = 'sl';
              }
              html += '<div class="'+arrange+'">';
              html += '<div class="row">';
            }
            if(i%6==0 
            || i%6==1 
            || i%6==3
            || i%6==5)
              if(i%6==0
              || i%6==5)
              html += '<div class="large col col-50">';
              else html += '<div class="col col-50">';
            if(i%6==1 
            || i%6==2 
            || i%6==3 
            || i%6==4)
              html+= '<div class="small row">'
            html += '<div class="coupon">';
            html += '<a href="#/singles/'+o['ID']+'">';
            html += '<div class="bg" style="background:url(../img/img1.png) no-repeat; background-size:cover; background-position: center center;"></div>';
            var color = 'purple';
            if(i%6==1||i%6==3) color = 'green';
            if(i%6==2||i%6==4) color = 'orange';
            html += '<div class="mask '+color+'"></div>';
            html += '<div class="content">';
            html += '<div class="logo">';
            html += '<img src="../img/brand1.png" alt="" />';
            html += '</div>'; // logo
            html += '<p class="miles">x.x Miles</p>';
            html += '<p class="num-coupons">'+ o.coupon_relationship.length +' Coupon' + (o.coupon_relationship.length==1?"":"s") + '</p>';
            html += '</div>'; // content
            html += '</a>';
            html += '</div>'; // coupon
            if(i%6==1 
            || i%6==2 
            || i%6==3 
            || i%6==4)
            html += '</div>'; // small row
            if(i%6==0 
            || i%6==2 
            || i%6==4 
            || i%6==5)
            html += '</div>'; // col
            if(i%6==2
            || i%6==5) {
              html += '</div>'; // row
              html += '</div>'; // ls|sl
            }
          }

          // write out the coupons
          $element.html(html);
          $compile($element.contents())($scope);
        });
        }
    }
})

Upvotes: 0

D. Visser
D. Visser

Reputation: 923

You can use Angular's ng-if directive.

So you can do something like this:

<div ng-if="item.b.length == 1">
   Use this layout
</div>

I hope that makes sense. Perhaps you could post the rest of your code, including the ng-repeater. That way I might be able to fit in the ng-if directive.

Edit:

Here is a simple example of the ng-if directive.

index.html

<html ng-app="bam" ng-controller="bamController">
<head>
</head>
<body>
    <div ng-repeat="member in members">
        <div ng-if="member.name != 'Dennis'">
            Well, hello, {{member.name}}.
        </div>
    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script>
    <script src="js/app.js"></script>
</body>
</html>

App.js

var bam = angular.module('bam', []);

bam.controller('bamController', ['$scope', function($scope){
    $scope.members = [
        {
            name: "Will",
            age: 32
        },
        {
            name: "Dennis",
            age: 30
        }
    ];
}]);

Upvotes: 1

Related Questions