0

I have Isotope running smoothly but it seems to reset variable-sizes class values in an unpredictable way - at least as far as I understand how it works.
My basic structure: A row of buttons at page top, A-Z class=letter. Each button loads a new set of divs.

$(".letter").click(function() {
    if ($('.'+letX+'').length > 0 ) { // divs already loaded
    var newItems = $('.'+letX+''); // letX grabbed from div ID, a, b, etc.
    $(this).find('#container').after(newItems); // loads fine, should hold width2 height2 set on very first load
    }
    else {
    var stringData = $.ajax({ url: 'digz/index/'+$(this).attr("id")+'.txt', async: false }).responseText;
        var $newItems = $(stringData);
            $('#container').isotope( 'insert', $newItems );
    $('.element').each(function(index) {
        $(this).find('.titlePE').before('<p class="number">' + index + '</p>'); // add numbers for variable-sizes
    });
    variableSizes(); // new divs so set random width2 height2
    }
});

I set a function for variableSizes to help me be a little more clear. Declared befor the above..

function variableSizes() {
$container.find('.element').each(function(){ // add randomish size classes
    var $this = $(this), number = parseInt( $this.find('.number').text(), 10 );
//$this.removeClass('width2').removeClass('height2');
//$('.element').removeClass('width2').removeClass('height2');
// if ( !($this).hasClass('sized') ) {
    if ( number % 7 % 2 === 1 ) {  $this.addClass('width2'); } // $('div .nameP').html('wide');
    if ( number % 3 === 0 ) {  $this.addClass('height2'); }
//  $this.addClass('sized'); // }
    });
}

This is the standard Isotope routine.
My rems are attempted fixes. Oh, I see I left out the code for if($(this).hasClass('sized')) test
But what happens is that I click the variable-sizes button (which adds a pre-class to the already set (random) width2 height2. I then click g = nice layout. Then h = nice, then d, nice, then g again = crap. It mostly sets at width2 height2 or some at just height2.

I am missing a piece of the process here. How to get the repeat click g - or d or... to maintain the randomly set width2 height2's? It doesn't even have to be predictable as, lets face it this is just bling, but it should hold some kind of 'nice.'
Any suggests?

Arfa
  • 105
  • 9

1 Answers1

0

The way you have the above logic written, it will run through all elements and adjust their sized after adding the items to Isotope.

When you change sizes of things that Isotope is using, you have to rerun one of the layout routines.

You can use either layout:

.isotope( 'layout', $items, callback )

Positions specified item elements in layout.

layout will only position specified elements, and those elements will be positioned at the end of layout. Whereas reLayout will position all elements in the Isotope widget.

or reLayout

.isotope( 'reLayout', callback )

Resets layout properties and lays-out every item element.

Depending on the behavior you want you could:

  1. Call variableSizes() passing your new list of elements prior to calling insert on Isotope.
  2. Run one of the above layout routines after calling variableSizes()

The advantage of variableSized() in the following example is that you don't have to have any conditional logic in your variableSizes() function. It'll just resize what is passed in.

Here is a simplified Demo Fiddle using #1 above (click on 'Rnd' to randomize everything):

Code:

var fakeResults = { '.a': [], '.b': [], '.c': [] };

for (var key in fakeResults) {
    for (var i = 0; i < 20; ++i) {
        fakeResults[key].push(key + i);
    }
}


$(".letter").click(function () {
    var $this = $(this);
    var filter = $this.data('filter');

    /* Click on Rnd to randomize sizes */
    if($this.text() === "Rnd") {
        variableSizes($('.element'));
        $container.isotope('reLayout');
        return;
    }

    if ($('#container ' + filter).length === 0) {
        var newItems = $.map(fakeResults[filter], function (ele, idx) {
            return $('<div/>').addClass('element')
                              .addClass(filter.split('.').slice(-1).join(''))
                              .text(ele)[0];
        });

        /* Call variableSizes before 'insert' or see below comment */
        variableSizes($(newItems));
        $container.isotope('insert', $(newItems));

        /* This will work as well */
        //variableSizes($(newItems));
        //$container.isotope('reLayout');
    }
});

function variableSizes($newItems) {
    $newItems.removeClass('width2').removeClass('height2');
    $newItems.each(function(idx, ele) {
        var $this = $(this),
            number = Math.floor(Math.random() * (20))+ 1; 

        if (number % 7 % 2 === 1) {
            $this.addClass('width2');
        }
        if (number % 3 === 0) {
            $this.addClass('height2');
        }
    });
}

If using #2 above and you want to avoid randomizing already sized elements you can either pass in only the new elements, or, if for some reason you can't track the new elements, add a marker class to the already sized elements.

This version of variableSizes() will do that. It finds all elements in the container that do not have the sized class:

Demo Fiddle

function variableSizes2() {
    $items = $container.find('.element:not(.sized)');
    $items.addClass('sized');

    $items.each(function(idx, ele) {
        var $this = $(this),
            number = Math.floor(Math.random() * (20))+ 1; 

        if (number % 7 % 2 === 1) {
            $this.addClass('width2');
        }
        if (number % 3 === 0) {
            $this.addClass('height2');
        }
    });
}
dc5
  • 12,341
  • 2
  • 35
  • 47
  • *after*, yes. I will work on *prior* and see how that goes. Yes, I have the 'reLayout' call a bit further down. I think it is the order of treatment that I need to examine. I only have internet for an hour or so a day and will play with this later and follow up tomorrow. thank you. – Arfa Sep 15 '13 at 23:45
  • way cool edits. This really is an extended effort on your part. Many thanks. As I mentioned I have only limited www time so will take time and test these later. As regards the basic question it is indeed a matter of sequence. My code looks very sweet and smug on the page now but there were masses of rem'd trials and alerts getting the order correct. This is my first real project with jq and I am learing heaps - with help :) – Arfa Sep 16 '13 at 21:49
  • finally got to play with the fiddles and get some perspective on what and how you were doing that. Very sweet. I have yet to try implementing this in my project but will get to that. Am I ever slow :) thx agin – Arfa Sep 18 '13 at 21:09