AngularJS allows for the creation of floating elements with various heights

An array of images with varying heights but constant width needs to be displayed in a tightly streamlined manner on the page.

Using jQuery, we have 3 columns. The first step involves loading the images and then, after the onLoad event, moving the image to the shortest column.

However, working with angularJs presents challenges as cutting and rearranging items isn't as straightforward with angularJs.

One solution that has been devised is to store an array for each column and an array containing all the images. Each time an image is loaded, an event is sent to the controller which then selects the shortest column and places the image in its array. But I am facing difficulties implementing this in angularJs

 <div class="container" ng-controller="columnCtrl">
     <div class="column" ng-column="column1">
       <div ng-repeat="imageSrc in columns.column1.imagesSrc">
           <img ng-load="$emit('loadImg')" 
                src="{{imageSrc}}" alt="img" />
       </div>
     </div>

     <div class="column" ng-column="column2">
       <div ng-repeat="imageSrc in columns.column2.imagesSrc">
           <img ng-load="$emit('loadImg')" 
                src="{{imageSrc}}" alt="img" />
       </div>
     </div>
 </div>

Check out this Pluker example for a full demonstration of how this problem can be solved.

Answer №1

Hmtl:

<body ng-app="app">
  <div class="container" ng-controller="MainController as main">
    <div class="column" ng-repeat="column in main.columns">
      <div ng-repeat="image in column.images">
        <img load src="{{image}}" alt="img" />
      </div>
    </div>
  </div>
</body>

Javascript:

angular
  .module('app', [])
  .controller('MainController', MainController)
  .service('columnsService', columnsService)
  .directive('load', loadDirective);

function MainController($scope, columnsService) {
  var vm = this;
  vm.columns = columnsService.columns;
  columnsService.init([
   'http://www.myschool21.narod.ru/mountain/images/fr_1041.jpg',
  'http://wallpaperscraft.ru/image/92232/200x300.jpg?orig=3',
  'http://cs10573.vk.me/g24449285/a_e2f12ad0.jpg',
  'http://static2.gooddays.ru/photos/0002/6209/andorra_preview.jpg?1241084584',
  'http://www.comunicom.ru/images/stories/PHOTO-2013/MINI/3.jpg'
  ]);
}

function columnsService() {
  var service = {
    images: [],
    columnsCount: 3,
    columns: [],
    init: init,
    initColumns: initColumns,
    pushNextImage: pushNextImage,
    getLowestColumn: getLowestColumn,
    updateColumn: updateColumn
  };
  return service;

  function init(images) {
    service.images = images;
    service.initColumns();
    service.pushNextImage();
  }

  function initColumns() {
    for (var i = 0; i < service.columnsCount; i++) {
      service.columns[i] = {
        height: 0,
        images: []
      };
    }
  }

  function pushNextImage() {
    var image = service.images.shift();
    if (image) {
      var column = service.getLowestColumn();
      column.images.push(image); 
    }
  }

  function getLowestColumn() {
    var minIndex = null;
    var minHeight = null;
    angular.forEach(service.columns, function(column, index) {
      if (minIndex === null || column.height < minHeight) {
        minIndex = index;
        minHeight = column.height;
      }
    });
    return service.columns[minIndex];
  }

  function updateColumn(index, height) {
    service.columns[index].height += height;
  }
}

function loadDirective(columnsService) {
  var directive = {
    restrict: 'A',
    link: link
  };
  return directive;

  function link($scope, element, attrs) {
    element.on('load', function(event) {
      $scope.$apply(function() {
        columnsService.updateColumn($scope.$parent.$index, element[0].offsetHeight);
        columnsService.pushNextImage();
      });
    });
  }
}

Live: http://jsbin.com/qunih/1/edit

Answer №2

Navix, I want to express my gratitude for solving exactly what we needed.

This code snippet should be incorporated into the service method for loading pictures later on.

var pictureService = {
  images: [],
  columnsCount: 3,
  columns: [],
  initialize: initialize,
  initializeColumns: initializeColumns,
  addImages: addImages,
  addNextImage: addNextImage,
  findShortestColumn: findShortestColumn,
  updateSortableColumn: updateSortableColumn
};
return pictureService;

function addPictures(pictures) {
  pictureService.images = pictureService.images.concat(pictures);
  pictureService.addNextImage();
}

Plunker

This module can also be utilized for placing floating images of varying heights on different pages.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Next JS encountered an error - Error [ERR_HTTP_HEADERS_SENT]: It is not possible to set headers after they have already been sent to the

Having crafted a serverless application using next.js, Vercel, and Google Sheets to store customer contact data, I encountered an issue post-deployment. While my application works flawlessly locally, after deployment, I started receiving the following erro ...

Tips on ending socket connection for GraphQL subscription with Apollo

I need to handle closing GraphQL Subscriptions on my Apollo server when a user logs out. Should I close the socket connections on the client side or in the backend? In my Angular front-end with Apollo Client, I manage GraphQL subscriptions by extending th ...

Creating an event emitter instance

I'm intrigued by the process of objects transitioning into event emitters. The documentation showcases code that resembles the following: var EventEmitter = require('events').EventEmitter; function Job(){ EventEmitter.call(this); } I fi ...

How do I incorporate Spotify into my mobile app to enable seamless background music playback?

Currently engaged in a mobile app project that utilizes react-native for the frontend and nodeJS for the backend. The main objective is to enable users to seamlessly play Spotify songs directly within the app, even in the background. This enhancement will ...

Guide to incorporating trading-vue-js into a Vue CLI project

Recently, I decided to explore the functionality of trading-vue-js and found it quite interesting. I managed to successfully run the test examples for trading-vue-js without any issues. The steps I took were as follows: nmp install trading-vue-js I then ...

The route seems to be downloading the page instead of properly rendering it for display

I'm facing a simple issue with my Express page - when I navigate to the FAQ route, instead of displaying the page it downloads it. The index page loads fine, and the FAQ page is the only other page available at the moment. I am using EJS templating, a ...

React component failing to update after receiving response from server for a specific room using socket.io-client with Python backend

I've developed a server backend in Python with Flask-SocketIO that includes a room feature for private conversations. When a user joins a room, the server triggers a function to inform the frontend where to direct messages to a specific user: socketio ...

PHP Form encountering error due to JSON decoding following an AJAX request

After extensive research and much confusion, I have finally decided to seek help here. I am able to make my AJAX request post successfully in every format except JSON. I am eager to understand JSON so that I can start using it right away instead of learni ...

Leveraging an Angular directive callback to make updates to a bower package on a local

Currently, I am dealing with an issue related to an outdated bower package. There is a pull request available with the necessary code to fix my problem, but unfortunately it has not been approved yet. The solution involves just two lines of code, which I ...

Experience real-time updates on webpages with Node.js and Socket.io

Seeking to integrate real-time push notification updates from a node.js server to the browser client. Explored socket.io at http://socket.io/docs/rooms-and-namespaces/ The business requirement involves users viewing a page with customer information and o ...

Minimize/Maximize Swagger Response Model Class View

After successfully integrating Swagger API documentation with my rest services, I encountered a challenge. The Swagger page appears too lengthy due to the numerous response classes in my project, requiring users to scroll extensively to find information. ...

Scroll-triggered Autoplay for YouTube Videos using JQuery

Issue: I'm trying to implement a feature where a YouTube video starts playing automatically when the user scrolls to it, and stops when the user scrolls past it. Challenges Faced: I am new to JavaScript web development. Solution Attempted: I referre ...

Utilizing a blank object as an argument for a conditional if statement in a loop

I've been attempting something along these lines, const myObject = {}; if(myObject){ //perform an action } My goal is for the condition to be false when the object is null. I attempted using JSON.stringify(myObject) but it still contains curly brac ...

Paste a URL into the input field to view it on the current page

As someone new to HTML, I am in search of a code snippet that will allow users to input a URL in a text box and then be redirected to that URL after clicking on a button. The ideal solution for me would be a straightforward HTML code. I attempted using t ...

Decrease the height of a div element from the top with the use of jQuery

My goal is to manipulate the height of the div #target when a specific event is triggered, either by reducing/increasing its height from the top or by hiding/showing its content. However, I'm struggling to find a solution to achieve this. The current ...

Can someone help me locate the file using the inspect element feature?

Today, I encountered a small issue on my website that I wanted to fix. Although I was able to make the necessary changes using Inspect Element, I couldn't locate the file where it needed to be changed. The website in question is gesher-jds.org/giving. ...

Mastering various mathematical operations in Vue.js

I am attempting to calculate the percentage of a value and then add it back to the original value using Vue.js. Here is an example: 5 / 100 * 900 + 900 = 945.00 (standard calculation) 5 / 100 * 900 + 900 = 90045 (Vue.js calculation) This is the code I ha ...

Issues arise in Ionic 3 when attempting to use scripts or external custom jQuery plugins within inner pages

When I utilize a script tag in my index.HTML file, it functions properly on the initial or root pages of Ionic 3. However, upon navigating to other pages using NavController, the script ceases to work on these inner pages. How can I implement a custom jQ ...

Navigating boolean data extracted from JSON strings with angular expressions

Currently, I'm extracting information from a JSON string with Angular and experimenting with my application. Task Status: {{task.completed}} // output is either true or false I aim to accomplish the following: If task completed == true, display "c ...

Can you explain how to use a toggle switch to make a select dropdown select a random option?

Currently, I am in the process of setting up a page for a character generator. Users will have the option to randomize traits or input their own. The interface includes toggle switches for the "choice vs random" options for each trait category, as well as ...