At the xs width I need column two to display on top followed by column one then three. I've tried using push and pull to achieve this but it hasn't worked for me, what happens it the columns are pushed outside the container to the right and left.
Heres my code:
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-4 one"></div>
<div class="col-xs-12 col-sm-4 two"></div>
<div class="col-xs-12 col-sm-4 three"></div>
</div>
</div>
.one{
background-color: red;
height: 50px;
}
.two{
background-color: green;
height: 50px;
}
.three{
background-color: blue;
height: 50px;
}
Use flexbox.
.row {
display: flex;
flex-direction: column;
}
.one {
background-color: red;
height: 50px;
order: 2;
}
.two {
background-color: green;
height: 50px;
order: 1;
}
.three {
background-color: blue;
height: 50px;
order: 3;
}
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-4 one"></div>
<div class="col-xs-12 col-sm-4 two"></div>
<div class="col-xs-12 col-sm-4 three"></div>
</div>
</div>
You can achieve that with .col-xx-pull- and .col-xx-push- built-in grid classes. Think mobile first and place the "2" col first in your html and then use pull-push:
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-4 col-sm-push-4 two">2</div>
<div class="col-xs-12 col-sm-4 col-sm-pull-4 one">1</div>
<div class="col-xs-12 col-sm-4 three">3</div>
</div>
</div>
.one {
background-color: red;
height: 50px;
}
.two {
background-color: green;
height: 50px;
}
.three {
background-color: blue;
height: 50px;
}
jsfiddle
The push and pull classes are not used for ordering.
You can achieve your desired result in a multiple of ways:
Javascript/jQuery. Check out the methods insertBefore and insertAfter.
use flexbox. Using flexbox gives you access to the property "order".
My pick would be Flexbox.
For more info on this check https://css-tricks.com/snippets/css/a-guide-to-flexbox/
I've made the following element swapping function for you which should be used as a jQuery function in case you don't want to use flexbox.
(function ($) {
$.fn.swapElements = function (opties) {
//Variables
var settings = $.extend({
targetResolution: 768, //Trigger swapping of elements on this resolution
changeWith: '', //Which element should be swapped $('#object2')
changeSpeed: 30,
resize: true //Check for resize event
}, opties);
var a = this;
var b = settings.changeWith;
var tmp = $('<span>').hide();
var doSwap = function () {
var windowWidth = $(window).width();
var firstElement = $('#' + a.attr('id') + ', #' + settings.changeWith.attr('id')).first().eq(0).attr('id');
if (windowWidth <= settings.targetResolution && firstElement === a.attr('id')) {
a.before(tmp);
b.before(a);
tmp.replaceWith(b);
} else if (windowWidth > settings.targetResolution && firstElement === b.attr('id')) {
b.before(tmp);
a.before(b);
tmp.replaceWith(a);
}
}
$(document).ready(function () {
doSwap();
});
if (settings.resize) {
//Check on resize
$(window).resize(function () {
clearTimeout($.data(this, 'resizeTimer'));
$.data(this, 'resizeTimer', setTimeout(function () {
doSwap();
}, settings.changeSpeed));
});
}
return this;
};
}(jQuery));
Which can be used like this:
$('#el1').swapElements({
changeWith: $('#el2'),
// changeSpeed: 30,
// targetResolution: 768,
// resize: true
});
Related
when you click on one of the 'cButton' elements, the active style will be applied to it but if you hold the mouse button down and then hover over another cButton while still holding, the style will not be applied to it.
I know a way to do it in Javascript but i am trying to do it using pure css.
body{
display: flex;
justify-content: space-evenly;
}
.cButton{
width: 100px;
aspect-ratio: 1;
background: red;
}
.cButton:active{
background: blue;
}
<div class="cButton">
</div>
<div class="cButton">
</div>
<div class="cButton">
</div>
<div class="cButton">
</div>
<div class="cButton">
</div>
<div class="cButton">
</div>
I am afraid that that is impossible in pure css. Because you will need a mouse down hover which is not available in css to my knowledge.
Unfortunately, you can't do this in pure CSS. However, here is some JavaScript code that works:
window.onload = function() {
document.querySelectorAll(".cButton").forEach(function(ele) {
ele.onmousedown = function() {
ele.classList.add("down")
}
ele.onmouseover = function(e) {
if (e.buttons == 1 && e.button == 0) {
ele.classList.add("down");
}
}
ele.onmouseup = function() {
ele.classList.remove("down")
}
ele.onmouseout = function() {
ele.classList.remove("down")
}
});
}
body {
display: flex;
justify-content: space-evenly;
}
.cButton {
width: 100px;
aspect-ratio: 1;
background: red;
}
.cButton.down {
background: blue;
}
<div class="cButton">
</div>
<div class="cButton">
</div>
<div class="cButton">
</div>
<div class="cButton">
</div>
<div class="cButton">
</div>
<div class="cButton">
</div>
I'm a visual artist with not that many coding skills. I know some HTML and some CSS but that's it. I like to create a webpage that does the following:
On the left, there is an image with lines. When hovering over a line the window on the right shows an image, movie, or plays a sound. Hovering over the next line triggers another image, movie, or sound.
Anyone can point me in the correct direction? I made a gif to show how it should work...
Simple solution:
Select HTML elements which we want to hover over (left, middle, right), and HTML elements which contain our images/videos/audio etc. (img1, sound, img2)
For every element you want to hover over, you need to add event listener (addEventListener), so you can manipulate your HTML/CSS code with JavaScript.
2.2 Inside each event listener you add or remove class: none, which has CSS value of display: none (this means element won't be shown), depending on what your goal is.
To make images disappear when we don't hover our cursor over the element, we need to again add event listener to elements which already have on mouseover event listener. In this case we use mouseover or blur. When cursor isn't on the element, JavaScript will automatically add none class to it.
const left = document.querySelector('.left-line');
const middle = document.querySelector('.middle-line');
const right = document.querySelector('.right-line');
const img1 = document.querySelector('.image-1');
const sound = document.querySelector('.sound');
const img2 = document.querySelector('.image-2');
left.addEventListener('mouseover', () => {
img1.classList.remove('none');
img2.classList.add('none');
sound.classList.add('none');
});
middle.addEventListener('mouseover', () => {
img1.classList.add('none');
img2.classList.remove('none');
sound.classList.add('none');
});
right.addEventListener('mouseover', () => {
img1.classList.add('none');
img2.classList.add('none');
sound.classList.remove('none');
});
left.addEventListener('mouseout',() => addNoneClass());
middle.addEventListener('mouseout', () => addNoneClass());
right.addEventListener('mouseout', () => addNoneClass());
function addNoneClass() {
img1.classList.add('none');
img2.classList.add('none');
sound.classList.add('none');
}
* {
padding: 0;
margin: 0;
width: 100vw;
height: 100vh;
}
main {
display: flex;
width: 100%;
height: 100%;
}
section.left {
width: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.line-container {
width: 150px;
height: 150px;
display: flex;
align-items: center;
border: 2px solid black;
}
.left-line, .middle-line, .right-line {
width: 50px;
height: 90%;
margin: 0 10px;
}
.left-line { background-color: green; }
.middle-line { background-color: red; }
.right-line { background-color: blue; }
section.right {
width: 50%;
display:flex;
align-items: center;
justify-content: center;
}
.box {
width: 200px;
height: 200px;
border: 2px solid black;
}
img {
width: 200px;
height: 200px;
}
.none {
display: none;
}
<main>
<section class="left">
<div class="line-container">
<div class="left-line">
</div>
<div class="middle-line">
</div>
<div class="right-line">
</div>
</div>
</section>
<section class="right">
<div class="box">
<div class="image-1 none">
<img src="https://play-lh.googleusercontent.com/aFWiT2lTa9CYBpyPjfgfNHd0r5puwKRGj2rHpdPTNrz2N9LXgN_MbLjePd1OTc0E8Rl1" alt="image-1">
</div>
<div class="sound none">
<img src="https://sm.pcmag.com/pcmag_uk/review/g/google-pho/google-photos_z68u.jpg" alt="sound">
</div>
<div class="image-2 none">
<img src="https://cdn.vox-cdn.com/thumbor/I2PsqRLIaCB1iYUuSptrrR5M8oQ=/0x0:2040x1360/1200x800/filters:focal(857x517:1183x843)/cdn.vox-cdn.com/uploads/chorus_image/image/68829483/acastro_210104_1777_google_0001.0.jpg" alt="image-2">
</div>
</div>
</section>
</main>
You can do this by the following code example.
HTML:
<div class="lines">
<span id='line-1'>|</span>
<span id='line-2'>|</span>
<span id='line-3'>|</span>
</div>
<div id='output'></div>
JS
const line1 = document.getElementById('line-1')
const line2 = document.getElementById('line-2')
const line3 = document.getElementById('line-3')
const output = document.getElementById('output')
line1.addEventListener('mouseover', () => {
output.innerHTML = 'Content One'
})
line2.addEventListener('mouseover', () => {
output.innerHTML = 'Content Two'
})
line3.addEventListener('mouseover', () => {
output.innerHTML = 'Content Three'
})
Investigating and, putting together my code little by little, I have achieved a carousel with the mouseup function that allows me to move the products by pressing the left button of the mouse without releasing it, so far it goes very well, well sometimes it remains as stalled, that is, without having pressed if I move the pointer moves the products.
What I want to achieve in my code is to be able to integrate two buttons, one right and one left, to also be able to move the products of the carousel in that way. How can I achieve it, can you explain to me?
var direction_slider = "up";
var current_step = 0;
var scroll_product = false;
var scroll = -1;
$(function(){
// vars for clients list carousel
var $product_carousel = $('.slider');
var products = $product_carousel.children().length;
var product_width = (products * 140); // 140px width for each client item
$product_carousel.css('width',product_width);
var rotating = true;
//var product_speed = 1800;
//var see_products = setInterval(rotateClients, product_speed);
$(document).on({
mouseenter: function(){
rotating = false; // turn off rotation when hovering
},
mouseleave: function(){
rotating = true;
}
}, '#carousel');
$product_carousel.on("mousedown", function(e) {
scroll_product = true;
scroll = e.pageX;
event.preventDefault();
}).on("mouseup", function(e) {
scroll_product = false;
var num = Math.floor(Math.abs(scroll - e.pageX) / 140);
var dir = scroll - e.pageX < 0 ? "up" : "down";
for (var x = 0; x < num; x++) {
var $first = $('.slider .item:first');
var $last = $('.slider .item:last');
if (dir == "up") {
$last.prependTo(".slider");
} else {
$first.appendTo(".slider");
}
}
$(".slider").css("transform", "translate(0, 0)")
}).on("mousemove", function(e) {
if (scroll_product) {
$(".slider").css("transform", "translate(" + ( e.pageX - scroll ) +"px, 0)")
}
});
});
.carousel {
margin: 0 auto;
padding: 1em;
width: 100%;
max-width: 1170px;
margin-left: auto;
overflow: hidden;
}
.slider {
width: 100% !important;
display: flex;
}
.item {
display: inline-table;
width: 280px;
height: 325px;
margin: 0.5em;
border: 1px solid #ccc;
}
a {
color: #8563CF;
text-decoration: none;
font-weight: 100;
}
.thumbnail {
height: 150px;
position: relative;
}
.thumbnail img {
height: 100%;
width: 100%;
object-fit: cover;
object-position: 50% 15%;
}
img {
border: 0;
height: auto;
max-width: 100%;
vertical-align: middle;
}
.p1em {
padding: 1em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<div class="carousel">
<div id="carousel">
<div class="slider" style="width: 280px; transform: translate(0px, 0px);">
<div class="item product">
<a href="#">
<div class="thumbnail image">
<img src="https://i.ytimg.com/vi/ZxrUVuOqsy0/maxresdefault.jpg">
</div>
<div class="box p1em">
<div class="heading ellipsis">
<h3>Prueba 1</h3>
</div>
<div class="author">
<span></span>
</div>
<div class="price right">
<p>
<label></label>
<em class="item-price">$40.130,00</em>
</p>
</div>
</div>
</a>
</div> <div class="item product">
<a href="#">
<div class="thumbnail image">
<img src="https://i.ytimg.com/vi/ZxrUVuOqsy0/maxresdefault.jpg">
</div>
<div class="box p1em">
<div class="heading ellipsis">
<h3>Curso de PHP 8 básico, intermedio y, avanzado. </h3>
</div>
<div class="author">
<span>Acaded</span>
</div>
<div class="purchased items-center">
<button>Ir al curso</button>
</div>
</div>
</a>
</div>
</div>
</div>
</div>
The goal here is to shift the order of elements to the left or right. With jQuery this is exceptionally easy.
The logic is as so:
To shift the order to the right, select the last item, delete it, then insert before the first item
To shift the order to the left, select the first item, delete it, then insert after the last item
To achieve this, we attach a click event listener to each respective button. We select all the slider items with the selector $('.item.product'), use last() and first() to get the first and last items, and the remove() function to delete the element. Then, to reorder, we use jQuery's insertBefore() and insertAfter().
This is the result:
$('#right').click(function() {
$('.item.product').last().remove().insertBefore($('.item.product').first());
})
$('#left').click(function() {
$('.item.product').first().remove().insertAfter($('.item.product').last());
})
And the rest is just a matter of styling (note: uses Material Icons for the arrow icons). Define two button elements;
<button id="left" class="nav-btn"><i class="material-icons">chevron_left</i></button>
<button id="right" class="nav-btn"><i class="material-icons">chevron_right</i></button>
The "chevron_right" and "chevron_left" are icon names | List of Icons
Set their position to fixed so that their position isn't lost when the user scrolls. Set the top attribute to calc(50vh - 50px), where 50vh is half the height of the viewport and 50px is the height of the button (to make it exactly in the "center").
A full example (best viewed in full page mode):
var direction_slider = "up";
var current_step = 0;
var scroll_product = false;
var scroll = -1;
$(function() {
$('#right').click(function() {
$('.item.product').last().remove().insertBefore($('.item.product').first());
})
$('#left').click(function() {
$('.item.product').first().remove().insertAfter($('.item.product').last());
})
var $product_carousel = $('.slider');
var products = $product_carousel.children().length;
var product_width = (products * 140);
$product_carousel.css('width', product_width);
var rotating = true;
$(document).on({
mouseenter: function() {
rotating = false;
},
mouseleave: function() {
rotating = true;
}
}, '#carousel');
$product_carousel.on("mousedown", function(e) {
scroll_product = true;
scroll = e.pageX;
event.preventDefault();
}).on("mouseup", function(e) {
scroll_product = false;
var num = Math.floor(Math.abs(scroll - e.pageX) / 140);
var dir = scroll - e.pageX < 0 ? "up" : "down";
for (var x = 0; x < num; x++) {
var $first = $('.slider .item:first');
var $last = $('.slider .item:last');
if (dir == "up") {
$last.prependTo(".slider");
} else {
$first.appendTo(".slider");
}
}
$(".slider").css("transform", "translate(0, 0)")
}).on("mousemove", function(e) {
if (scroll_product) {
$(".slider").css("transform", "translate(" + (e.pageX - scroll) + "px, 0)")
}
});
});
/* button integration styling (start) */
#left {
left: 10px;
}
#right {
right: 10px;
}
.nav-btn {
position: fixed;
top: calc(50vh - 50px);
z-index: 100;
z-index: 100;
height: 50px;
width: 50px;
border-radius: 50%;
cursor: pointer;
background-color: white;
box-shadow: 0 0 1px black;
transition: 0.2s;
}
.nav-btn:hover {
background-color: #d1d1d1;
}
/* button integration styling (end) */
.carousel {
margin: 0 auto;
padding: 1em;
width: 100%;
max-width: 1170px;
margin-left: auto;
overflow: hidden;
}
.slider {
width: 100% !important;
display: flex;
}
.item {
display: inline-table;
width: 280px;
height: 325px;
margin: 0.5em;
border: 1px solid #ccc;
}
a {
color: #8563CF;
text-decoration: none;
font-weight: 100;
}
.thumbnail {
height: 150px;
position: relative;
}
.thumbnail img {
height: 100%;
width: 100%;
object-fit: cover;
object-position: 50% 15%;
}
img {
border: 0;
height: auto;
max-width: 100%;
vertical-align: middle;
}
.p1em {
padding: 1em;
}
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<div class="carousel">
<button id="left" class="nav-btn"><i class="material-icons">chevron_left</i></button>
<button id="right" class="nav-btn"><i class="material-icons">chevron_right</i></button>
<div id="carousel">
<div class="slider" style="width: 280px; transform: translate(0px, 0px);">
<div class="item product">
<a href="#">
<div class="thumbnail image">
<img src="https://i.ytimg.com/vi/ZxrUVuOqsy0/maxresdefault.jpg">
</div>
<div class="box p1em">
<div class="heading ellipsis">
<h3>Prueba 1</h3>
</div>
<div class="author">
<span></span>
</div>
<div class="price right">
<p>
<label></label>
<em class="item-price">$40.130,00</em>
</p>
</div>
</div>
</a>
</div>
<div class="item product">
<a href="#">
<div class="thumbnail image">
<img src="https://i.ytimg.com/vi/ZxrUVuOqsy0/maxresdefault.jpg">
</div>
<div class="box p1em">
<div class="heading ellipsis">
<h3>Curso de PHP 8 básico, intermedio y, avanzado. </h3>
</div>
<div class="author">
<span>Acaded</span>
</div>
<div class="purchased items-center">
<button>Ir al curso</button>
</div>
</div>
</a>
</div>
<div class="item product">
<a href="#">
<div class="thumbnail image">
<img src="https://www.gravatar.com/avatar/0fdacb141bca7fa57c392b5f03872176?s=96&d=identicon&r=PG&f=1">
</div>
<div class="box p1em">
<div class="heading ellipsis">
<h3>Spectric</h3>
</div>
<div class="author">
<span>Spectric</span>
</div>
<div class="purchased items-center">
<button>Check out</button>
</div>
</div>
</a>
</div>
</div>
</div>
</div>
I'd like to add a box containing smileys icons above the comment area which opens using jQuery on click. What I come up with is this:
<div class="emo">
<i href="#" id="showhide_emobox"> </i>
<div id="emobox">
<input class="emoticon" id="icon-smile" type="button" value=":)" />
<input class="emoticon" id="icon-sad" type="button" value=":(" />
<input class="emoticon" id="icon-widesmile" type="button" value=":D" /> <br>
</div>
</div>
css:
.emoticon-smile{
background: url('../smileys/smile.png');
}
#icon-smile {
border: none;
background: url('../images/smile.gif') no-repeat;
}
jQuery:
// =======show hide emoticon div============
$('#showhide_emobox').click(function(){
$('#emobox').toggle();
$(this).toggleClass('active');
});
// ============add emoticons============
$('.emoticon').click(function() {
var textarea_val = jQuery.trim($('.user-comment').val());
var emotion_val = $(this).attr('value');
if (textarea_val =='') {
var sp = '';
} else {
var sp = ' ';
}
$('.user-comment').focus().val(textarea_val + sp + emotion_val + sp);
});
However I have difficulty placing buttons in a nice array and make background image for them (the button values appear before image and the array is not perfectly rectangular. So I'm wondering maybe this is not the best way to render this box.
Any ideas to do this properly?
First show images, on hover hide image and show text. No need for input elements to get text of Dom Node
Something like this:
$(document).ready(function() {
$(".wrapper").click(function() {
var value = $(this).find(".smily-text").text();
console.log(value);
alert("Smily text is '" + value + "'");
});
});
.smily {
background: url(http://www.smiley-lol.com/smiley/manger/grignoter/vil-chewingum.gif) no-repeat center center;
width: 45px;
height: 45px;
}
.smily-text {
display: none;
font-size: 20px;
text-align: center;
line-height: 45px;
height: 45px;
width: 45px;
}
.wrapper {
border: 1px solid red;
float: left;
cursor: pointer;
}
.wrapper:hover .smily {
display: none;
}
.wrapper:hover .smily-text {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="smily"></div>
<div class="smily-text">:)</div>
</div>
<div class="wrapper">
<div class="smily"></div>
<div class="smily-text">:(</div>
</div>
<div class="wrapper">
<div class="smily"></div>
<div class="smily-text">:]</div>
</div>
<div class="wrapper">
<div class="smily"></div>
<div class="smily-text">:[</div>
</div>
I have a container in which I would like to display items as though they were in two columns.
Each item has a different height because the content in it varies.
This is currently what it looks like:
I would like to remove the extra space between items vertically to look closer to this:
so that it looks as though the items are stacking.
A link to my sample code:
http://plnkr.co/edit/oc1XT4ia9GdIc4rzZ41Q?p=preview
As the question is using AngularJS this answer is compatible with that.
You'll need to create a divs wrapping around the repeat, and a repeat for each column you want, and then display or hide elements in there by ng-show="($index)%2==columnIndex".
Then float the two wrapping divs, and add a standard clearfix to the 1px solid black container so it wraps around the floating elements.
'use strict';
var app = angular.module( 'myApp', [] );
app.controller( 'myCtrl', [ '$scope', function ( $scope ){
$scope.value = 'test';
$scope.items = [];
var count = 10;
for(var i=0; i<count; i++){
var item = {
height: Math.round(Math.random()*30) + 20
};
$scope.items.push(item);
}
}] );
.itemContainer {
display: block;
width: 80%;
border: 1px solid black;
padding: 10px;
}
.item {
border: 1px solid blue;
padding: 5px;
margin: 1px;
display: block;
}
.clearfix:after {
content: ".";
display: block;
clear: both;
visibility: hidden;
line-height: 0;
height: 0;
}
.clearfix {
display: inline-block;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<div class='itemContainer clearfix'>
<div style="display:inline-block; float:left; width:40%;">
<div class="item" ng-repeat="item in items" style="height: {{item.height}}px" ng-show="($index)%2==1" >
{{item}}
</div>
</div>
<div style="display:inline-block; float:left; width:40%;">
<div class="item" ng-repeat="item in items" style="height: {{item.height}}px" ng-show="($index)%2==0" >
{{item}}
</div>
</div>
</div>
</body>
</html>
You can do a repeat around the repeat wrapping float:left elelements, and specify how many columns you want, and if you want dynamic resizing of columns youll have to watch for resizes and change the column size with it.
To prevent the double processing issue you'd ideally use a filter, and not ng-show.
In the future hopefully we can use the flexible boxes layout module without breaking it for certain browsers.
Just for the record. This is an HTML and CSS-only version of one approach to achieve this.
HTML:
<div id="LeftColumn">
<div class="left_cell">Just</div>
<div class="left_cell">The</div>
<div class="left_cell"></div>
<div class="left_cell"></div>
</div>
<div id="RightColumn">
<div class="right_cell">For</div>
<div class="right_cell">Record</div>
<div class="right_cell"></div>
<div class="right_cell"></div>
</div>
CSS:
#LeftColumn {
width: 200px;
float: left;
}
#RightColumn {
width: 200px;
float: left;
margin-left:4px;
}
.left_cell {
width:200px;
height:30px;
border: 1px solid blue;
margin-bottom:2px;
}
.right_cell {
width:200px;
height:42px;
border: 1px solid blue;
margin-bottom:2px;
}
Check the fiddle here. As you can see, the thing is just to put the contents of each column on separate div elements, and float the two divs.
You can use the new flex display method to achieve this.
HTML
<div >
<div style="height: 45px;"></div>
<div style="height: 31px;"></div>
<div style="height: 31px;"></div>
<div style="height: 34px;"></div>
<div style="height: 27px;"></div>
<div style="height: 23px;"></div>
<div style="height: 41px;"></div>
<div style="height: 34px;"></div>
<div style="height: 48px;"></div>
<div style="height: 47px;"></div>
</div>
CSS
body > div {
height: 220px;
padding: 1px;
display: flex;
flex-flow: column wrap;
border: 1px solid;
}
body > div > div {
border: 1px solid blue;
margin: 1px;
}
After a bit of research, I see that it is indeed difficult to do with just CSS, so I wrote a small AngularJS directive to do some of the processing.
Demo Here: http://plnkr.co/edit/UyRS0clrCwDpSrYgBsXS?p=preview
var app = angular.module( 'myApp', [] );
app.controller( 'myCtrl', [ '$scope', function ( $scope ){
$scope.value = 'test';
$scope.items = [];
var count = 20;
for(var i=0; i<count; i++){
var item = {
height: Math.round(Math.random()*30) + 20,
value: Math.round(Math.random()*30) + 20
};
$scope.items.push(item);
}
}] );
app.directive('columns', function(){
return {
restrict: 'E',
scope: {
itemList: '=',
colCount: "#"
},
link: function(scope, elm, attrs) {
//console.log(scope.itemList);
var numCols = 3;
var colsArr = [];
for(var i=0; i< numCols; i++){
colsArr.push(angular.element("<div class='column'>Col "+(i+1)+"</div>"));
elm.append(colsArr[i]);
}
angular.forEach(scope.itemList, function(value, key){
var item = angular.element("<div class='item' style='height:"+value.height+"px;'>"+value.value+"</div>");
// find smallest column
var smallestColumn = getSmallestColumn();
angular.element(smallestColumn).append(item);
});
function getSmallestColumn(){
var smallestHeight = colsArr[0][0].offsetHeight;
var smallestColumn = colsArr[0][0];
angular.forEach(colsArr, function(column, key){
if(column[0].offsetHeight < smallestHeight){
smallestHeight = column[0].offsetHeight;
smallestColumn = colsArr[key];
}
});
console.log(smallestColumn);
return smallestColumn;
}
}
};
});
with this being the html:
<columns item-list="items" col-count='3' class='itemContainer'></columns>