views:

245

answers:

4

I'm using the masonry jquery plugin on a project: (http://desandro.com/resources/jquery-masonry)

Basically I have a set of boxes (thumbnails) in a grid. When one is clicked, I want it to expand to a larger size to show more content (additional images and text). I'm struggling with how to make the thumbnail dissappear and then have new content appear in the expanded box. I don't know how to make the new content appear or where to store it on my page--and it needs to have a close button? The creator of the plugin gave me a quick tip for the expanding part, but the code I'm using has a set height and width and I want them to be variable depending on how much content is in the expanded state.

Here's my jquery code so far: http://pastie.org/1002101

This is a similar example of the behaviour I want to achieve (except my boxes will have have varying expanded sizes): (http://www.learnsomethingeveryday.co.uk)

You'll also notice from that example that it only allows 1 box to be expanded at a time--I would also like to have that functionality.

Sorry for all the questions--I'm pretty new to jquery, any help would be amazing!

+1  A: 

Try this (demo here):

$(document).ready(function(){

 $('#grid').masonry({
    singleMode: false,
    itemSelector: '.box',
    animate: true
 });

 $('.box').click(function(){
  if ($(this).is('.expanded')){
   restoreBoxes();
  } else {
   restoreBoxes();
   $(this)
    // save original box size
    .data('size', [ $(this).width(), $(this).height() ])
    .animate({
      width: 335,
      height: 335
     }, function(){
      $('#grid').masonry();
    })
    .addClass('expanded');
  }

  function restoreBoxes(){
   var len = $('.expanded').length - 1;
   $('.expanded').each(function(i){
    var box = $(this).data('size');
    $(this).animate({
      width: ( box[0] || 100 ),
      height: ( box[1] || 'auto' )
     }, function(){
        if (i >= len) {
       $('#grid').masonry();
      }
    })
    .removeClass('expanded');
   })
  }
 });
});

Update: Hi Jam, I didn't know you left a comment for me, next time please add comments under the answer or update your question. Also you can put "@" in front of the person's name and they will get a message flag.

In response to your question about set size and hidden content, I modified the demo (pretty much all of the HTML and CSS included) to show varying width boxes. Having the clicked box to expand to contain all of the hidden content has a slight problem. Normally, hidden content has a height and width of zero. But jQuery is able to determine the hidden content size, but it still has some problems because you might need to limit the width or height of the hidden content. So what I ended up doing was adding the hidden content in a inside of the box and adding a data-size attribute to the box which contains the width and height of the expanded hidden content, for example:

<div class="box" data-size="380,380">
    <p>This is the visible content.</p>
    <div class="expandable">
        This is the hidden content which shows when the box is clicked.
    </div>
</div>

I've also included a way to hide the visible content when the box is expanded, by adding a hideable class to the content, since the image you provided seems to have the original content hidden:

<div class="box" data-size="380,380">
    <p class="hideable">This is the visible content.</p>
    <div class="expandable">
        This is the hidden content which shows when the box is clicked.
    </div>
</div>

If the data-size attribute is not set, then the script will default to the defaultSize setting:

Note the demo is using $(document).ready(function(){...}) instead of $(window).load(function(){...}) as recommended by the author of masonry because jFiddle just doesn't want to work with window load.

$(window).load(function () {

    var defaultSize = [180, 180]; // expanded box size: [width , height]
    $('#grid').masonry({
        singleMode: false,
        columnWidth: 100,
        resizeable: true,
        itemSelector: '.box',
        animate: true
    });

    $('.box').click(function () {
        if ($(this).is('.expanded')) {
            restoreBoxes();
        } else {
            var size = ($(this).attr('data-size')) ? $(this).attr('data-size').split(',') : defaultSize;
            $(this)
            // save original box size
            .data('size', [$(this).width(), $(this).height()]).animate({
                width: size[0],
                height: size[1]
            }, function () {
                // show hidden content when box has expanded completely
                $(this).find('.expandable').show('slow');
                $(this).find('.hideable').hide('slow');
                $('#grid').masonry();
            });
            restoreBoxes();
            $(this).addClass('expanded');
        }

        function restoreBoxes() {
            var len = $('.expanded').length - 1;
            $('.expanded').each(function (i) {
                var box = $(this).data('size');
                $(this).find('.expandable').hide('slow');
                $(this).find('.hideable').show('slow');
                $(this).animate({
                    width: (box[0] || 100),
                    height: (box[1] || 'auto')
                }, function () {
                    if (i >= len) {
                        $('#grid').masonry();
                    }
                }).removeClass('expanded');
            })
        }
    });
});
fudgey
I've updated my answer.
fudgey
A: 

Thank you! That works great! There are just a few things I'm not sure of...

Right now, that example expands only 1 box at a time, which is great. But it passes in a set size for the width and height of the expanded state. I want to make this variable so that some boxes will be larger when expanded and some will be smaller (based on how much content I want to put in them).

Also, in that demo, the content in the collapsed state is the same content in the expanded state. When clicked, I want the small box content to disappear and then to load in new content (e.g. a layout with text AND images). Here's a link to what I mean: http://i48.tinypic.com/2iuunar.jpg

I'm not sure where to store the expanded content and how to make the collapsed content disappear/reappear, etc...

Jam
A: 
  • sorry, I can't comment on others questions yet (hence the answer box)

@fudgey

I have this working with the jquery filter fudgey helped my with. My issue is that for whatever reason, in google chrome, the masonry items don't seem to finish positioning on page load. After something is clicked, all is fine, just the initial page load is problematic. Where/how would I set a loading time for masonry?

Additionally, is there anyway to get a pointer cursor working on this? Currently, a user would not know to click the elements.

Jason
sorry - see http://jasondaydesign.com/masonry_demo/
Jason
A: 
ebola5114