Skip to content

DillonGray/jquery.shapeshift

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Shapeshift v2.0

Check out a demo here.

April 16th, 2013: Version 2.0 released. There may be bugs and we are still browser testing. Please report any bugs you find through issues.

Column Grid System + Drag and Drop

Inspired heavily by the jQuery Masonry plugin, Shapeshift is a plugin which will dynamically arrange a collection of elements into a column grid system similar to Pinterest. What sets it apart is the ability to drag and drop items within the grid while still maintaining a logical index position for each item. This allows for the grid to be rendered exactly the same every time Shapeshift is used, as long as the child elements are in the correct order.

Features

  • Drag and Drop Rearrange items within a container or even drag items between multiple Shapeshift enabled containers. Dragging elements around will physically change their index position within their parent container. When a page reloads, as long as the child elements are placed in the correct order then the grid will look exactly the same.

  • Works on Touch Devices Shapeshift uses jQuery UI Draggable/Droppable for help with the drag and drop system. Luckily there is already a plugin called jQuery Touch Punch which provides touch support for jQuery UI D/D. It can be found in the vendor folder.

  • Multiwidth Elements A new feature in 2.0 is the ability to add elements that can span across multiple columns as long as their width is correctly set through CSS.

  • Responsive Grid Enabled by default, Shapeshift will listen for window resize events and arrange the elements within it according to the space provided by their parent container.

Credits

A big thanks to all of our contributors!

we the media

Shapeshift is maintained by We The Media, inc.

Sites Using Shapeshift

Got a project that you are using shapeshift on? Let us know and we will happily throw a link to your page here!

Index

  1. Getting Started
  1. Shapeshift Options
  1. Detecting Changes
  1. Triggering a Rearrange
  2. Destroying Shapeshift
  3. For Contributors

Getting Started

Dependencies

Shapeshift requires the latest version of jQuery, and drag and drop feature (enabled by default) requires jQuery UI Draggable/Droppable libraries. It also requires jQuery Touch Punch to work on touch devices.

Setting Up the Parent Container

Shapeshift arranges child elements by absolutely positioning them in their parent container which must be set to "position: relative". The container does not have to be a div and can be substituted for any element that can have child elements, such as an unordered list. The container also must have a width specified.

HTML:
<div class="container"></div>
CSS:
.container {
  position: relative;
  width: 100%;
}

Setting up the Child Elements

By default all child elements within the parent container will be Shapeshifted. Just make sure that they are set to "position: absolute" in your CSS file. The children also must have a height/width specified.

HTML:
<div class="container">
  <div>Child Element 1</div>
  <div>Child Element 2</div>
  <div>Child Element 3</div>
  <div>Child Element 4</div>
  ...
</div>
CSS:
.container {
  position: relative;
  width: 100%;
}

.container div {
  height: 50px;
  position: absolute;
  width: 50px;
}

Multiwidth Children

Shapeshift relies on a column grid system, this means that every time Shapeshift is initialized on a container it will determine the column width based on the width of the first child in that container. If no column width is specified on a child element then Shapeshift will assume it will use it to set the single column width for the grid.

To make a child element multiwidth, simply add the data attribute "data-ss-colspan=X", where X is the amount of columns it should span. Shapeshift does not automatically set their width though so the childs width must already be set to the correct width. The calculated width must be set to: "single column width * columns to span + the gutter space in between".

For example, assuming the default gutter value of 10px, multiwidth elements can be created as such:

HTML:
<div class="container">
  <div>Spans 1 Column</div>
  <div data-ss-colspan="2">Spans 2 Columns</div>
  <div data-ss-colspan="3">Spans 3 Columns</div>
  <div data-ss-colspan="4">Spans 4 Columns</div>
  ...
</div>
CSS:
.container {
  position: relative;
  width: 100%;
}

.container div {
  height: 120px; 
  position: absolute; 
  width: 80px;
}
.container div[data-ss-colspan="2"] { width: 170px; }
.container div[data-ss-colspan="3"] { width: 260px; }
.container div[data-ss-colspan="4"] { width: 350px; }

Shapeshift Everything!

Now that we have our setup complete, simply call .shapeshift() on the parent element. It will, by default, select all the children in the parent element to be rearranged.

$('.container').shapeshift();

Options

Shapeshift Options

Customize your grid even further. All of these are the default options and more in depth information can be found further down the page.

$('.container').shapeshift
    # The Basics
    selector: "*"

    # Features
    enableDrag: true
    enableCrossDrop: true
    enableResize: true
    enableTrash: false

    # Grid Properties
    align: "center"
    colWidth: null
    columns: null
    minColumns: 1
    autoHeight: true
    maxHeight: null
    minHeight: 100
    gutterX: 10
    gutterY: 10
    paddingX: 10
    paddingY: 10

    # Animation
    animated: true
    animateOnInit: false
    animationSpeed: 225
    animationThreshold: 100

    # Drag/Drop Options
    dragClone: false
    deleteClone: true
    dragRate: 100
    dragWhitelist: "*"
    crossDropWhitelist: "*"
    cutoffStart: null
    cutoffEnd: null
    handle: false

    # Customize CSS
    cloneClass: "ss-cloned-child"
    activeClass: "ss-active-child"
    draggedClass: "ss-dragged-child"
    placeholderClass: "ss-placeholder-child"
    originalContainerClass: "ss-original-container"
    currentContainerClass: "ss-current-container"
    previousContainerClass: "ss-previous-container"

The Basics

Option Description Type Acceptable Values Default
Selector Use a CSS selector to specify which child elements should be Shapeshifted. String Any CSS selector, such as ".amelia" or "#pond" "*"

Extra Features

Option Description Default
enableDrag Allows for the child items to be dragged in the container and to other containers that have drop enabled. See Drag and Drop options for more customization. true
enableCrossDrop Allows for children to be dropped from *other* containers into this one. true
enableResize Shapeshift will listen for the window resize event and rearrange the child elements if the parent container has also changed. true
enableTrash When an item is dropped into a container that has trash enabled, it will destroy the dropped element. false

Grid Properties

Option Description Acceptable Values Default
align Align / justify the grid. "left", "center", "right" "center"
colWidth Manually set the column width. Column width is automatically determined by Shapeshift, however it is required to be set if the container has no initial children to calculate it from. Any Integer >= 1 1
columns Force the grid to have a specific number of columns. Setting this to null will automatically determine the maximum columns for the width of the container. Any Integer >= 1 null
minColumns This will prevent the grid from ever going below a set number of columns. If using multiwidth then this must be set to the highest colspan child element. Any Integer >= 1 1
autoHeight Automatically sets the height of the container according to the height of the contents within it. If set to false, then the "height" option must also be specified. true, false true
maxHeight If "autoHeight" is turned on, maxHeight will never allow the container height to go above this number. Any Integer >= 1 null
minHeight If "autoHeight" is turned on, minHeight will never allow the container height to go below this number. Any Integer >= 1 100
gutterX The number of pixels horizontally between each column. Any Integer >= 0 10
gutterY The number of pixels vertically between each element. Any Integer >= 0 10
paddingX Sets the horizontal padding of the grid between the left and right sides of the container. Any Integer >= 0 10
paddingY Sets the vertical padding of the grid between the top and bottom sides of the container. Any Integer >= 0 10

Animation Settings

Option Description Acceptable Values Default
animated When children shift around via the resize or drag and drop features, they will animate into place. true, false true
animateOnInit Animates the children into position upon page load. true, false false
animationSpeed The speed at which the children will animate into place. Any Integer >= 0 225
animationThreshold If there are too many elements on a page then it can get very laggy during animation. If the number of children exceed this threshold then they will not animate when changing positions. Any Integer >= 0 100

Drag and Drop Settings

Option Description Acceptable Values Default
dragClone When an element is dragged it will create a clone instead. true, false false
deleteClone If a cloned item is dropped into its original container, delete the clone that was made. true, false true
dragRate The number of milliseconds that Shapeshift will attempt to find a target pisition for a dragged item. Any Integer >= 0 100
dragRate The number of milliseconds that Shapeshift will attempt to find a target pisition for a dragged item. Any Integer >= 0 100
dragWhitelist A CSS selector specifying the elements which can be dragged. Any CSS selector, such as ".river" or "#song" "*"
crossDropWhitelist A CSS selector specifying the elements which can be dropped into this container from *other* containers. Any CSS selector, such as ".martha" or "#jones" "*"
cutoffStart Items cannot be dragged to an index position below this number. Any Integer >= 0 null
cutoffEnd Items cannot be dragged to an index position past this number. Any Integer >= 0 null
handle If specified, restricts dragging from starting unless the mousedown occurs on the specified element(s). Any CSS selector, such as ".jack" or "#harkness" false

Customize CSS

Certain elements will have CSS classes attached to them for specific events. Customize those CSS classes if needed.

Option Affected Element Description Default
activeClass Child Elements Every active Shapeshift child item will have this class applied to them. ss-active-child
cloneClass Cloned Child Element If the "dragClone" option is used, this is the CSS class applied to the clone that is created. ss-cloned-child
draggedClass Dragged Child Element The class applied to an element while it is being dragged. ss-dragged-child
placeholderClass Placeholder Element When an item is dragged, a placeholder element is created to show the new target position. ss-placeholder-child
originalContainerClass Container Element When an item is dragged, this is the class applied to the container it originated from. ss-original-container
currentContainerClass Container Element When an item is dragged, this is the class applied to the container it currently is in. ss-current-container
previousContainerClass Container Element When an item is dragged between containers, this is the class applied to the container it was previously in. ss-previous-container

Detecting Changes

Changes to the grid will trigger several different events on the container element and important objects will be returned with it. Here are a list of events that can be listened to, with some examples following.

Event Name Triggered When Triggered On Variables Returned
ss-rearranged When an item is dropped into the container it originated from. original container element selected element
ss-removed When an item is dropped into a container it didn't originate from. original container element selected element
ss-added When an item is dropped into a container it didn't originate from. new container element selected element
ss-trashed When an item is dropped into a container that has trash enabled and therefore is removed from the DOM. trash enabled container element selected element
ss-drop-complete When an item is dropped into a container, this gets called when it has stopped moving to its new position. new container element none
ss-arranged When an item is dragged around in a container, arranged is triggered every time items are shifted. current container element none

Event Listening Examples

When an item has begun being dragged, it will trigger the "ss-event-dragged" on the container element. You can then write out some code to be fired off when that event occurs. The object that was just selected is also passed back to you. For example,

  $containers = $(".ss-container")

  $containers.on "ss-rearranged", (e, selected) ->
    console.log "This container:", $(this)
    console.log "Has rearranged this item:", $(selected)
    console.log "Into this position:", $(selected).index()

  $containers.on "ss-removed", (e, selected) ->
    console.log "This item:", $(selected)
    console.log "Has been removed from this container:", $(this)

  $containers.on "ss-added", (e, selected) ->
    console.log "This item:", $(selected)
    console.log "Has been added to this container:", $(this)

  $containers.on "ss-trashed", (e, selected) ->
    console.log "This item:", $(selected)
    console.log "Has been removed from the DOM"

  $containers.on "ss-drop-complete", (e) ->
    console.log "This container:", $(this)
    console.log "Has finished rearrangement after a drop."

  $containers.on "ss-arranged", (e) ->
    console.log "This container:", $(this)
    console.log "Has just rearranged items but no drop has occurred."

Triggering a Rearrange

If you add, remove, hide, or show elements through your own code then you may need to rearrange the items into their new positions. Triggering "ss-rearrange" on the target container will do so.

  $(".ss-container").trigger("ss-rearrange")

Destroying Shapeshift

Simply trigger the event "ss-destroy" on the container.

  $(".ss-container").trigger("ss-destroy")

For Contributors

Feel like you've got an idea on how to optimize the code and want to share it? We are totally open to new changes, however this is one of the first publically available plugins that I am offering and therefore do not have an exact process on pull requests. Feel free to fork the project all you want, but be aware any pull requests that are made may take a while to get implemented (if at all).

About

A dynamic grid system with drag and drop functionality.

Resources

License

Stars

Watchers

Forks

Packages

No packages published