Como o proprio site do plugin explica:
Masonry is a JavaScript grid layout library. It works by placing elements in optimal position based on available vertical space, sort of like a mason fitting stones in a wall. You’ve probably seen it in use all over the Internet.
O objetivo no final deste post é ter um layout organizado pelo plugin, com registros paginados e requisições via ajax para obter os registros das páginas seguintes, utilizando uma Class Based View no Django.
Requisitos:
- Django==1.11.1+
- Masonry
- ImagesLoaded
Bom, primeiramente faremos a View:
class PostListView(View): def get(self, request, *args, **kwargs): posts = Post.objects.all() RPP = 18 PAGINA = 1 TOTAL = posts.count() if request.GET.get('page'): PAGINA = int(request.GET.get('page')) page_template = 'blog/paginacao.html' template = 'blog/list.html' if request.is_ajax(): template = page_template tem_mais = posts[PAGINA*RPP+1:] tem_mais = tem_mais.count() posts = posts[(PAGINA-1)*RPP:PAGINA*RPP] if posts.count() == 0: return HttpResponse('') VARS = { 'posts':posts, 'pag':PAGINA, 'tem_mais': tem_mais, 'total': TOTAL, } return render(request, template, VARS)
Serão necessários dois templates:
blog/list.html
{% extends "base.html" %} {% block scripts %} <script src="{% static "site/vendor/masonry/jquery.masonry.pkgd.min.js" %}" type="text/javascript"></script> <script src="{% static "site/vendor/masonry/imagesloaded.pkgd.min.js" %}" type="text/javascript"></script> <script src="{% static "site/src/js/layout.js" %}" type="text/javascript"></script> <script src="{% static "site/src/js/blog.list.js" %}" type="text/javascript"></script> {% endblock scripts %} {% block conteudo %} <!-- Masonry Grid --> <div class="masonry-grid"> <div class="masonry-grid-sizer col-xs-6 col-sm-4 col-md-3 col-lg-2"></div> {% for p in posts %} <!-- Post Item --> <div class="masonry-grid-item col-xs-6 col-sm-4 col-md-3 col-lg-2"> </div> <!-- End Post Item --> {% endfor %} </div> <!-- End Masonry Grid --> <div class='loading-bg'> <div class='loading'></div> </div> {% endblock conteudo %}
blog/paginacao.html
<!-- Masonry Grid --> <div class="masonry-grid"> <div class="masonry-grid-sizer col-xs-6 col-sm-4 col-md-3 col-lg-2"></div> {% for p in posts %} <!-- Post Item --> <div class="masonry-grid-item col-xs-6 col-sm-4 col-md-3 col-lg-2"> </div> <!-- End Post Item --> {% endfor %} </div> <!-- End Masonry Grid --> <div class='loading-bg'> <div class='loading'></div> </div>
layout.js:
var Layout = function () { 'use strict'; var mobile = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase())); // handle on page scroll var handleHeaderOnScroll = function() { if ($(window).scrollTop() > 60) { $('body').addClass('page-on-scroll'); } else { $('body').removeClass('page-on-scroll'); } } // handle carousel var handleCarousel = function() { var $item = $('.carousel .item'); var $wHeight = $(window).height(); $item.eq(0).addClass('active'); $item.height($wHeight); $item.addClass('full-screen'); $('.carousel img').each(function() { var $src = $(this).attr('src'); var $color = $(this).attr('data-color'); $(this).parent().css({ 'background-image' : 'url(' + $src + ')', 'background-color' : $color }); $(this).remove(); }); $(window).on('resize', function (){ $wHeight = $(window).height(); $item.height($wHeight); }); } if($(window).width() > 992) { $('.screen__height').height($(window).height()/1.3); $(window).resize(function(){ $('.screen__height').height($(window).height()/1.3); }); } // handle group element heights var handleHeight = function() { $('[data-auto-height]').each(function() { var parent = $(this); var items = $('[data-height]', parent); var height = 0; var mode = parent.attr('data-mode'); var offset = parseInt(parent.attr('data-offset') ? parent.attr('data-offset') : 0); items.each(function() { if ($(this).attr('data-height') == "height") { $(this).css('height', ''); } else { $(this).css('min-height', ''); } var height_ = (mode == 'base-height' ? $(this).outerHeight() : $(this).outerHeight(true)); if (height_ > height) { height = height_; } }); height = height + offset; items.each(function() { if ($(this).attr('data-height') == "height") { $(this).css('height', height); } else { $(this).css('min-height', height); } }); if(parent.attr('data-related')) { $(parent.attr('data-related')).css('height', parent.height()); } }); } return { init: function () { handleHeaderOnScroll(); // initial setup for fixed header handleCarousel(); // initial setup for carousel handleHeight(); // initial setup for group element height // handle minimized header on page scroll $(window).scroll(function() { handleHeaderOnScroll(); }); } }; }(); $(document).ready(function() { Layout.init(); });
blog.list.js
jQuery(document).ready(function($) { var carregando = false; $(window).on('scroll', function(event) { event.preventDefault(); /* Act on the event */ if($(window).scrollTop() + $(window).height() > $(document).height() - 100 && carregando == false && parseInt($('#tem_mais').val()) > 0) { // console.log("near bottom!"); carregando = true retrive_posts(); } }); $('body').on('click', '.next', function(event) { event.preventDefault(); carregando = true; /* Act on the event */ retrive_posts(); }); function retrive_posts(){ var pag = parseInt($('#pag').val())+1; $('.loading-bg').show(); $.get('?page='+pag, function(data) { /*optional stuff to do after success */ // console.log(data); // console.log(data == ''); // console.log($('#tem_mais').length); console.log($('#tem_mais').val()); if(data){ $('#pag').val(parseInt(pag)); // console.log(data); var aux = $('<div/>'); $(aux).html(data); var tem_mais = $(aux).find('.tem_mais')[0]; $('#tem_mais').val($(tem_mais).val()); if (parseInt($('#tem_mais').val()) == 0) { $('button.next').hide(); } var $container = $('.masonry-grid'); $container.imagesLoaded( function() { $container.masonry({ itemSelector: '.masonry-grid-item', // use a separate class for itemSelector, other than .col- columnWidth: '.masonry-grid-sizer', percentPosition: true, transitionDuration: 0, }); }); // console.log($(aux).find('.masonry-grid-item.appended')); $(aux).find('.masonry-grid-item.appended').each(function(index, el) { $(el).css({ opacity: 0 }); // console.log($(el)); $(el).imagesLoaded(function(){ // show elems now they're ready $(el).css({ opacity: 1 }); $container.append( $(el) ); $container.masonry( 'appended', $(el), true ); $(el).removeClass('.appended') }); }); carregando = false; $('.loading-bg').hide(); }else{ $('button.next').hide(); } }); } });
Nenhum comentário:
Postar um comentário