Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bootstrap Responsive Product Grid

I am building a product grid built upon AngularJS data - where there will be images and product details (text)

The text sometimes extends to the 2nd line, causing havoc.

Here is my code:

<div class="row">
    <div data-ng-repeat="s in Results">
        <div class="col-xs-4">
            <a href="#" class="thumbnail">
                <div>
                    <img ng-src="{{s.ProductImage}}" class="img-responsive">
                </div>
                <div>
                    {{s.Store}} {{s.Category}} {{s.ProductName}}
                </div>
            </a>
        </div>
        <div class="clearfix visible-xs-block"></div>
    </div>
</div>

This is what it looks like:

enter image description here

How do I fix it so that <div>s all have the same height? I tried to look online for solutions, but I think I am 50% there. Please help.

Note: I Don't want to hide content.

like image 239
Simcha Khabinsky Avatar asked Jul 09 '14 16:07

Simcha Khabinsky


Video Answer


2 Answers

This is what I ended up doing for anyone who stumbles on this again in the future.

Javascript

function ResizeToLargestElement(element) {
    var maxHeight = -1;
    if ($(element).length > 0) {
        $(element).each(function () {
            maxHeight = maxHeight > $(this).height() ? maxHeight : $(this).height();
        });

        $(element).each(function () {
            $(this).height(maxHeight);
        });
    }
}

Without AngularJS

For those who aren't using AngularJS, just call ResizeToLargestElement() when data changes or the window is resized using

$(window).resize(function() {
       ResizeToLargestElement('.AutoResizeToLargestElement');
});`

With AngularJS

The idea is to call the ResizeToLargestElement() function whenever $scope.Results changes or when the window resizes.

To know when $scope.Results changed is easy, but to know when elements (that are bound to it) finished rendering is not easy. To do that, you need a AngularJS directive.

To know when the window re-sizes, use angular.element($window).on('resize', function () {...});

HTML

<div class="row">
    <div data-ng-repeat="s in Results" data-ng-repeat-finished> <!--ADDED Directive-->
        <div class="col-xs-4">
            <a href="#" class="thumbnail AutoResizeToLargestElement"> <!--ADDED Class-->
                <div>
                    <img ng-src="{{s.ProductImage}}" class="img-responsive">
                </div>
                <div>
                    {{s.Store}} {{s.Category}} {{s.ProductName}}
                </div>
            </a>
        </div>
        <!--REMOVED clearfix-->
    </div>
</div>

MyDirectives.js

angular.module('myApp').directive('ngRepeatFinished', function ($timeout) {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            if (scope.$last === true) {
                $timeout(function () {
                    scope.$emit('ngRepeatFinished');
                });
            }
        }
    }
});

mycontroller.js

$scope.$on('ngRepeatFinished', function (ngRepeatFinishedEvent) {
    ResizeToLargestElement(".AutoResizeToLargestElement");
});

angular.element($window).on('resize', function () {   
    ResizeToLargestElement(".AutoResizeToLargestElement");
});

Note: this requires you to include $window in the AngularJS dependency list. I.E. angular.module('myApp').controller('....', ['...., '$window', ....]);

like image 109
Simcha Khabinsky Avatar answered Sep 17 '22 09:09

Simcha Khabinsky


If you want to keep the height of each product dynamic, you will need to split the results into columns. And then use ng-if to put the right items in the right column. Every 3rd item will go into the same column. To set them to different columns, just reduce the $index by 1 for each extra column.

<div class="row">
    <div class="col-xs-4">
        <div ng-repeat="s in Results"> <a href="#" class="thumbnail" ng-if="$index%3==0">
            <div>
              <img ng-src="{{s.ProductImage}}" class="img-responsive" />
            </div>
            <div>{{s.Store}} {{s.Category}} {{s.ProductName}}</div>
          </a>
            <div class="clearfix visible-xs-block"></div>
        </div>
    </div>
    <div class="col-xs-4">
        <div ng-repeat="s in Results"> <a href="#" class="thumbnail" ng-if="($index-1)%3==0">
            <div>
              <img ng-src="{{s.ProductImage}}" class="img-responsive" />
            </div>
            <div>{{s.Store}} {{s.Category}} {{s.ProductName}}</div>
          </a>
            <div class="clearfix visible-xs-block"></div>
        </div>
    </div>
    <div class="col-xs-4">
        <div ng-repeat="s in Results"> <a href="#" class="thumbnail" ng-if="($index-2)%3==0">
            <div>
              <img ng-src="{{s.ProductImage}}" class="img-responsive" />
            </div>
            <div>{{s.Store}} {{s.Category}} {{s.ProductName}}</div>
          </a>
            <div class="clearfix visible-xs-block"></div>
        </div>
    </div>
</div>
like image 32
Kaizen Programmer Avatar answered Sep 19 '22 09:09

Kaizen Programmer