-3

I've been sending this emails: I'm about to release an application for web application security which requires the use of a grid like Masonry. I've tried all, and every single angular module, directives, and different approaches, including CSS based techniques, pure Vanilla JS, and your solution is, one of the best options available online. I found, however a main issue, that affects not only your approach, but every single Angular module or addon.

Issue #1:

Your solution, as any other solution, is based on an array of information that is already handled by angular. In your example case, it would be source="photos". Now, the problem comes when there's 2 different groups of elements. Let's assume, that I have a group of elements that where previously defined in the DOM. In other words:

<div angular-grid>
    <p class="angular-grid-elem">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
    <div class="angular-grid-elem" style="height:500px">Same happens with this content.</div>
    <!-- and here comes more content, which is loaded from an array of information -->
    <div class="angular-grid-elem" ng-repeat="data in data_array">
        <p>{{data.header}}</p>
        <p>{{data.details}}</p>
    </div>
</div>

Now, as you can see in the example, the content inside the main div, , should be all, affected by the masonry layout. Of course, this is pseudo code and I'm aware that the sintaxis of your approach is different. However what I'm trying to represent here, is that your module, would be way better, if you would be able to apply the masonry like grid, including elements which are already present in the DOM/HTML in first place, with elements that are coming from an array.

Issue #2:

There's a second issue I found in multiple angular modules and approaches. What happens if I have 2, 3 or let's say even 16 divs which all of them, present the same masonry like behaviour? I have to admit, I didn't try it with your module, as I couldn't solve the initial problem, that requires the proper handling of the combination of elements that are (1) pre-defined in the HTML, and (2) coming from and ng-repeat function.

A possible approach:

In order to solve the second problem and the first one, at the same time, I have thought that the best approach might be to make use of element classes and elements ids to handle the situation? Why? Because it can easily applied into elements that are already there in the DOM in first place, as well, to elements that are joining or leaving dynamically by the use of a ng-repeat or any other of the angular functions.

Here's an example of what I'm saying:

<div class="angular-grid-dad-one" ng-grid="{'dad': 'angular-grid-dad-one', 'childs': 'angular-grid-elem'}" >
    <p class="angular-grid-elem">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
    <div class="angular-grid-elem" style="height:500px">Same happens with this content.</div>
    <!-- and here comes more content, which is loaded from an array of information -->
    <div class="angular-grid-elem" ng-repeat="data in data_array">
        <p>{{data.header}}</p>
        <p>{{data.details}}</p>
    </div>
</div>

In this case, the main div defines itself as id="angular-grid-dad-one", And also tells the Angular module, that the element angular-grid-dad-one is a container div of a masonry like structure, And that it's childs are marked as angular-grid-elem. As we could see on this line. ng-grid="{'dad': 'angular-grid-dad-one', 'childs': 'angular-grid-elem'}"

This way, it allow us to make use of the Angular module in multiple instances. For example.

<div class="seccion_01" ng-grid="{'dad': 'seccion_01', 'childs': 'seccion_01_child'}" ng-show="seccion == '1'">
    <p class="seccion_01_child">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
    <div class="seccion_01_child" style="height:500px">Same happens with this content.</div>
    <!-- and here comes more content, which is loaded from an array of information -->
    <div class="seccion_01_child" ng-repeat="data in data_array">
        <p>{{data.header}}</p>
        <p>{{data.details}}</p>
    </div>
</div>

<div class="another_container" ng-grid="{'dad': 'another_container', 'childs': 'child_of_container'}" ng-show="seccion == '2'">
    <p class="child_of_container">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
    <div class="child_of_container" style="height:500px">Same happens with this content.</div>
    <!-- and here comes more content, which is loaded from an array of information -->
    <div class="child_of_container" ng-repeat="data in data_array">
        <p>{{data.header}}</p>
        <p>{{data.details}}</p>
    </div>
</div>

<div class="redundant_example" ng-grid="{'dad': 'redundant_example', 'childs': 'childs_of_redundancy'}" ng-show="seccion == '3'">
    <p class="childs_of_redundancy">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
    <div class="childs_of_redundancy" style="height:500px">Same happens with this content.</div>
    <!-- and here comes more content, which is loaded from an array of information -->
    <div class="childs_of_redundancy" ng-repeat="data in data_array">
        <p>{{data.header}}</p>
        <p>{{data.details}}</p>
    </div>
</div>

I have used a Json styled instruction in the ng-grid value in order to explain my point, but it doesn't really have to be Json. It even could be 2 different paramenters:

<div class="dad" ng-grid-dad="dad" ng-grid-childs="childs" ng-show="seccion == '3'">
    <p class="childs">This content is already here from the beginning, in the DOM, directly in the HTML, and I want to apply a Masonry like style on it.</p>
    <div class="childs" style="height:500px">Same happens with this content.</div>
    <!-- and here comes more content, which is loaded from an array of information -->
    <div class="childs" ng-repeat="data in data_array">
        <p>{{data.header}}</p>
        <p>{{data.details}}</p>
    </div>
</div>

As well, regarding the infinite scroll that you have created, you would be able to load more elements, triggering the infinite scroll, and loading only elements from one specific array, of course. Please let me know if I can help further, I would like to integrate your module into my application.

And let's hope that by the next implementation of HTML and CSS we have this situation fully under control by the next generation of browsers, I'm aware of the work it takes to make this grids in Javascript.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Chris Russo
  • 450
  • 1
  • 7
  • 21
  • You will probably need `flex-wrap: wrap;` but it is hard to say without your code, please add an html and css example – Adam Buchanan Smith Aug 31 '16 at 22:36
  • Is pure Angular generated code... :S I'm about to make a public release the application however... I guess I'll use if even float left, if odd float right approach. But I'll let you know once I'll have it online. Also for people in the same situation, this approach works: http://passy.github.io/angular-masonry/ but implies loading another lib which increases the loading time... not desired. – Chris Russo Aug 31 '16 at 23:30
  • This is not what flexbox was made to do. It simply *doesn't* do this – Zach Saucier Sep 01 '16 at 02:00
  • Here, where's my answer and where's my question duplicate? – Chris Russo Sep 06 '16 at 13:52

1 Answers1

0

Actually, I am gonna go out on a limb and say that flex-wrap: wrap will fix the issue.

.holder {
flex-wrap: wrap
-moz-columns: 2 auto;
box-sizing: border-box;
display: flex;
padding: 0 40px;
width: 100%;
}
Adam Buchanan Smith
  • 9,422
  • 5
  • 19
  • 39
  • Mr Adam, Thanks. It hits the problem of the overflow-x somehow, but it creates a huge white space between the boxes, which is the original problem that I'm trying to sort out. I've updated the main question with an screenshot to show you the behaviour and the expected behaviour. – Chris Russo Aug 31 '16 at 23:09
  • @ChrisRusso Oh so do you want it all to go underneath? like in one column? – Adam Buchanan Smith Aug 31 '16 at 23:27
  • well, somehow, yes. I want these boxes to have a maximum of 700px of width. Then, if the screen has enough space to show the #2 box at the right of the #1 box (in other words, if the screen if bigger than 1400px) then, I do want the second box to be at the right of the first one. When the 3rd one comes, if there's still space in the right, I want it to float right as well, otherwise, I want it to fall directly at the bottom of the first one. When the box #4 comes in, it would naturally float at the bottom of #2 – Chris Russo Aug 31 '16 at 23:37
  • All this, happening, while Angular ng-bind keeps adding more elements into the DOM... – Chris Russo Aug 31 '16 at 23:38