jQuery: snap a box to a grid

jQuery: snap a box to a grid

How to snap an HTML element to a grid by using the draggable and droppable objects of jQuery UI.

jQuery UI provides us with the draggable and droppable objects. The former handles the dragging of an element, while the latter defines the behavior of the dragged object once it has been dropped on an element. We can use these objects to create the effect of a box which snaps to a grid made up by several HTML elements. The implementation is pretty simple. Let's see the details.

First we need to create our HTML structure:

<div id="box"></div>

<div id="grid">
    <div id="a"></div>
    <div id="b"></div>
    <div id="c"></div>
    <div id="d"></div>
</div>​

Then we create our grid with CSS floating and positioning:

#box {
    width: 100px;
    height: 100px;
    background: green;
    position: absolute;
    top: 0;
    left: 0;
    cursor: move;
}

#grid {
    width: 200px;
    height: 200px;
    position: relative;
    border: 1px solid #999;
    margin: 120px auto 0 auto;
}

#grid div {
    width: 100px;
    height: 100px;
    float: left;
}

#grid #a {
    border-right: 1px solid #ccc;
    width: 99px;
}


#grid #c {
    border-right: 1px solid #ccc;
    width: 99px;
    height: 99px;
    border-top: 1px solid #ccc;
}

#grid #d {
    border-top: 1px solid #ccc;
    height: 99px;
}

/* CSS classes added dynamically */

div#box.dropped {
    background: silver;
}

div#grid.focus {
    border: 1px solid red;
}

Now we have to declare our external box as draggable:

$('#box').draggable();

The box can de dragged towards the grid. Each box in the grid must be handled as a droppable object, namely as the target of the dragging action:

$('div', '#grid').each(function() {
    var $div = $(this);
    $div.droppable({
        drop: function() {
            $('#box').addClass('dropped').
            css({
                top: $div.offset().top,
                left: $div.offset().left
            });
            $('#grid').addClass('focus');
        }
    });
});​

Our box now is absolutely positioned on the grid by using the top and left offsets of each droppable element contained within the grid. The drop event takes place only when a box is released on a droppable object.

You can see the demo below.

Demo

Live demo