Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular.js using bootstrap and dynamically creating rows

I am trying to figure out how to dynamically create bootstrap row divs with a class of row-fluid with angular.js using the ng-repeat directive.

Here is the angular:

 <div ng-repeat="task in tasks" class="row-fluid">
     <div class="span6 well">{{task.name}}</div>
 </div>

This does not work though. The bootstrap html I wish to generate is:

http://jsfiddle.net/YKkXA/2/

Basically I need to do mod 2 of the index inside of the ng-repeat, and if its 0, close out the </div> and create a new <div class="row-fluid">. How is this possible?

like image 441
Justin Avatar asked Feb 07 '13 10:02

Justin


2 Answers

The idea is to filter your items in order to group them, and make a second ngRepeat to iterate on sub-items.

First, add that filter to your module :

module.filter('groupBy', function() {
    return function(items, groupedBy) {
        if (items) {
            var finalItems = [],
                thisGroup;
            for (var i = 0; i < items.length; i++) {
                if (!thisGroup) {
                    thisGroup = [];
                }
                thisGroup.push(items[i]);
                if (((i+1) % groupedBy) === 0) {
                    finalItems.push(thisGroup);
                    thisGroup = null;
                }
            }
            if (thisGroup) {
                finalItems.push(thisGroup);
            }
            return finalItems;
        }
    };
});

In your controler (because if you filter directly in your template, then you will have a $digest loop):

function TaskCtrl() {
    $scope.tasksGroupBy2 = $filter('groupBy')(taskGroup, 2);
}

And in your .html :

<div ng-repeat="taskGroup in tasksGroupBy2" class="row-fluid">
    <div ng-repeat="task in taskGroup" class="span6 well">{{task.name}}</div>
</div>
like image 127
Anthony O. Avatar answered Sep 27 '22 20:09

Anthony O.


As an improvement to the answer Anthony gave, I would say that you could save yourself a lot of trouble using the slice method instead of going through all those conditions.

Try defining your filter as it follows:

module.filter('group', function() {
    return function(items, groupItems) {
        if (items) {
            var newArray = [];

            for (var i = 0; i < items.length; i+=groupItems) {
                if (i + groupItems > items.length) {
                    newArray.push(items.slice(i));
                } else {
                    newArray.push(items.slice(i, i + groupItems));
                }
            }

            return newArray;
        }
    };
});

After that you can call the filter on your controller as Anthony pointed out in his response:

function Controller ($scope) {
    $scope.itemsGrouped = $filter('group')(itemsArray, 5);
}
like image 35
alex952 Avatar answered Sep 27 '22 20:09

alex952