Maxim V. Pavlov
Maxim V. Pavlov

Reputation: 10509

A jQuery/javascript auto-sizable grid control

I am implementing a jquery file upload page. While a user is adding files, I want them to be getting listed in a form of an icons in an auto-sizable grid.

Auto-sizable means it provides maximum space for containing elements. When there is two objects - it woud look like (I know i will have to handle image resizing myself):

two items js grid

When several are added:

several items js grid

Is there a "grid control" (jquery perhaps) that does at least close to what I need sizing wise?

Upvotes: 1

Views: 541

Answers (1)

Francesco Frassinelli
Francesco Frassinelli

Reputation: 3375

First of all, please keep in mind that I'm a jQuery newbie and this is my first post on Stackoverflow :)

I've the same problem and I've try to fix it using jQuery and CSS. This is my body tag content:

<div id="controls">
Controls:
    <button id="add">+</button>
    <button id="del">-</button>
Current ratio:
    <span id="value"></span>
    <button id="increase">+</button>
    <button id="decrease">-</button>
Referred to:
    <form style="display: inline;">
        width<input type="radio" name="maximize" value="width">
        height<input type="radio" name="maximize" value="height">
    </form>
</div>
<div id="elements" style="width: 500px; height: 300px; background: black;">
</div>
<script>
ratio      = 1;
ratioWidth = true;
function autoresize() {
    boxes   = $('#elements').children().size(); 
    rows    = Math.ceil(Math.sqrt(boxes/ratio));
    columns = Math.ceil(boxes/rows);
    if (!ratioWidth) {
        tmp     = rows;
        rows    = columns;
        columns = tmp;
    }
    $('#elements').children().css('width',  100/rows+'%');
    $('#elements').children().css('height', 100/columns+'%');
}
function add() {
    red   = Math.floor(Math.random()*256);
    green = Math.floor(Math.random()*256);
    blue  = Math.floor(Math.random()*256);
    color = 'rgb('+red+','+green+','+blue+')';
    $('#elements').append("<div style=\"background: "+color+"; float: left;\"></div>");
    autoresize();
}
function update() {
    $('#value').text(ratio);
    autoresize();
}
function remove() {
    $('#elements').children().last().remove();
    update();
}
function increase() {
    ratio++;
    update();
}
function decrease() {
    if (ratio > 1) {
        ratio--;
        update();
    }
}
$(document).ready(function() {
    $('#add').click(add);
    $('#del').click(remove);
    $('#increase').click(increase);
    $('#decrease').click(decrease);
    if (ratioWidth) value = 'width'
    else value = 'height'
    $('input[type=radio]').filter('[value='+value+']').attr('checked', true);
    $('input[type=radio]').live('change', function() {
        if ($(this).val() == 'width') ratioWidth = true
        else ratioWidth = false;
        autoresize();
    });
    update();
    //$(window).bind("resize", autoresize);
});
</script>

You could remove the background color stuff and put your icons centered in those boxes. If you find a better way of if you improve this code, please let me know :)

Edit 1 - I've added some Math.floor(...) to remove a bug when boxes side has repeating decilmals: very size is a simple integer. Now dimensions are fetched from the container div, I use black as background color for the main container and I've noticed a little issue: sometimes I see a black border near the little boxes, even if I don't set any background color. Could it be a Firefox rendering glitch?

Edit 2 - Now it's possible to set if you prefer to auto-expand horizontally, vertically, or none of them. I've tried to write a better code, and I've commented autoresize when the window is resized (use it only if your container box hasn't a fixed height/width). I think that now it needs an ratio option, in order to specify if width have to be twice longer for example. Live example: http://experimental.frafra.eu/maxarea2.html

Edit 3 - New code! Better graphical representation and a new parameter: ratio. Ratio is a coefficient between the ratio between main container width/height and the elements one. Live example: http://experimental.frafra.eu/maxarea3.html

Upvotes: 2

Related Questions