Enhanced simple Pinterest Style Grid Layout jQuery Plugin

By · April 13, 2017 · 3 comments

In response to a request, I have made some improvements to the modified version of Mediademons Simple jQuery Plugin To Create Pinterest Style Grid Layout - Pinterest Grid.

This original script had a few bugs which I provided fixes for. See my previous post, Simple jQuery Plugin To Create Pinterest Style Grid Layout for more details.

Reader Maxim Usik asked to be able to have more than one breakpoint, so that it might have 3 columns on larger screens, 2 columns on a tablet, and 1 column on a mobile phone.

I have made some changes to the script and you can now specify the number of columns at any number of breakpoints.

The new option is called "breakpoints" and you pass it an array of values, for example:
breakpoints: [  [ 767, 1 ], [ 991, 2 ], [ 1199, 3 ] ]

For each breakpoint, the first value is the maximum width, and the second value is the number of columns.

The default value for this option matches Bootstrap 3.x breakpoints.

Also in this update script is small a fix for adjusting the screen as images load.

Here is a demo using Bootstrap 3.x.

And here is the updated script.

/*
Pinterest Grid Plugin
Copyright 2014 Mediademons
@author smm 16/04/2014

Modified by John Avis 13/04/2017

usage:

$(document).ready(function() {
$('#blog-landing').pinterest_grid({
no_columns: 4
});
});
*/
; (function ($, window, document, undefined) {
var pluginName = 'pinterest_grid',
defaults = {
padding_x: 10,
padding_y: 10,
no_columns: 4,
margin_bottom: 50,
breakpoints: [
[ 767, 1 ],
[ 991, 2 ],
[ 1199, 3 ]
]
},
columns,
$article,
article_width;

function Plugin(element, options) {
this.element = element;
this.options = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}

Plugin.prototype.init = function () {
var self = this,
resize_finish;

$(this.element).find("img").load(function () {
$(window).resize();
});

$(window).resize(function () {
clearTimeout(resize_finish);
resize_finish = setTimeout(function () {
self.make_layout_change(self);
}, 11);
});

self.make_layout_change(self);

setTimeout(function () {
$(window).resize();
}, 500);
};

Plugin.prototype.calculate = function (columns) {
var self = this,
tallest = 0,
row = 0,
$container = $(this.element),
container_width = $container.width();
$article = $(this.element).children();

if (columns === 1) {
article_width = $container.width() - self.options.padding_x;
} else {
article_width = ($container.width() - self.options.padding_x * (columns - 1)) / columns;
}

$article.each(function() {
$(this).css('width', article_width);
});

$article.each(function (index) {
var current_column,
left_out = 0,
top = 0,
$this = $(this),
prevAll = $this.prevAll(),
tallest = 0;

if (columns !== 1) {
current_column = (index % columns);
} else {
current_column = 0;
}

for (var t = 0; t < columns; t++) {
$this.removeClass('c' + t);
}

if (index % columns === 0) {
row++;
}

$this.addClass('c' + current_column);
$this.addClass('r' + row);

prevAll.each(function (index) {
if ($(this).hasClass('c' + current_column)) {
top += $(this).outerHeight() + self.options.padding_y;
}
});

if (columns === 1) {
left_out = 0;
} else {
left_out = (index % columns) * (article_width + self.options.padding_x);
}

$this.css({
'left': left_out,
'top': top
});
});

this.tallest($container);
};

Plugin.prototype.tallest = function (_container) {
var column_heights = [],
largest = 0;

var paddingy = this.options.padding_y;

for (var z = 0; z < columns; z++) {
var temp_height = 0;
_container.find('.c' + z).each(function () {
temp_height += $(this).outerHeight() + paddingy;
});
column_heights[z] = temp_height;
}

largest = Math.max.apply(Math, column_heights) - paddingy;
_container.css('height', largest + this.options.margin_bottom);
};

Plugin.prototype.make_layout_change = function (_self) {
columns = _self.options.no_columns;

for (var i = 0; i < _self.options.breakpoints.length; i++) {
if ($(window).width() <= _self.options.breakpoints[i][0]) {
columns = _self.options.breakpoints[i][1];
break;
}
}

_self.calculate(columns);
};

$.fn[pluginName] = function (options) {
return this.each(function () {
if (!$.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName,
new Plugin(this, options));
}
});
}

})(jQuery, window, document);

Get the latest posts delivered to your inbox.

Comments (3)

# Posted by Maxim Usik · April 16, 2017

John, thank you very much for your work and for your help. I really appreciate it.

Fixes you have initiated work perfect. Breakpoints work just as they suppose to work.

BUT. Now, if I have a footer div following after the .pinterest-grid section footer div goes OVER the .pinterest-grid. Because pinterest-grid doest have any height... In the old version of the plugin that issue worked correctly and container element had it's height according to the pins total height.

Is that possible to fix somehow?

Thank you very much for your help.

Maxim

Reply

Maxim Usik
# Posted by John Avis · April 17, 2017

Sorry Maxim. I had an error in one line that was causing this. I have updated the code, but if you find the line "var columns = _self.options.no_columns;" near the end under "Plugin.prototype.make_layout_change = function (_self) {", remove the word "var".

Reply

John Avis
# Posted by Maxim Usik · April 19, 2017

John, Thank you! Now that working correct! Thank you very much!!!

Reply

Maxim Usik
Leave a Comment

All comments are moderated and rel="nofollow" is in use. Avatars are sourced from gravatar.com – a globally recognised avatar.

Type the numbers from the picture above

About me
John Avis ...mostly about web development and programming, with a little bit of anything else related to the Internet, computers and technology.

profile for John at Stack Overflow, Q&A for professional and enthusiast programmers
Subscribe

Get the latest posts delivered to your inbox. *