AngularJS Directive for the excellent ShapeShift.js plugin

For a project I’ve been working on for the past two years (extremely cool and still top secret until its release soon), I use the excellent ShapeShift plugin based on jQuery UI to create a Pintrest-like mosaic layout for a bunch of gauges (also a jQuery plugin) on a page for users to view real-time factory data. The app was originally mostly built with jQuery and Bootstrap, but recently I’ve updated part of it to use AngularJS for more structure and easier to read code.

Since I’ve been building the new pieces of the app with Angular, I had to think the “Angular way” and work any/all jQuery plugins into directives.

The ShapeShift plugin examples and code can be found here http://mcpants.github.io/jquery.shapeshift/

My Github repo for the directive can be found here.

So the directive is restricted to an attribute in this case, you can see its usage on the index.html page. I simply call shapeshift() on the element in the linking function of the directive. It has an example of listening to ShapeShift events (the ss-added event in this case) so you can handle them how you want to.

You can check out all the code in the Github repo. Next up is the TechOctave Gauge directive I created. The only problem with sharing that code is you’ll have to purchase your own gauge.js license.

 

Facebooktwitterlinkedin

3 Comments

  1. Fred

    Hi,

    Your sample was very usefull for start my investigation about integrating ShapeShift in an application.

    But you’re POC is a little bit incomplete because you do not deal with a dynamic collection of “shape shifted items”.

    Try to put a $scope.items as ‘[]’ in your controller and iterare like this on your shapeshift children :

    You will see, shapeshift method be applied as angular match it in the DOM, so, in this basic case (static, but programmatic collection), DOM collection is empty, and items are not correctly shapeshifted.

    After spending a long time to search about this point :
    – ui-router wrapping (what about dynamic view load ?)
    – angular data dispatch
    – or anything else I thought to solve this problem

    I finally had the idea to look about “ng-repeat” and the solution was here :

    You have to wait for the last element in your collection, then apply the shapeshift method.

    – Apply a directive on the div child element, like this :

    Then, declare it in your app, and try out this piece of code :

    .directive(‘shapeItem’, [ function() {
    return {
    restrict: ‘A’,
    link: function(scope, element, attrs) {
    scope.$watch(‘$last’, function(v) {
    console.log(‘iterate’);
    if(v) {
    // console.log(‘$last’);
    element.parent().shapeshift({
    // shapeshift options
    });
    }

    });
    }
    };
    }])

    Please take a look and try it.

    Hope I was usefull 🙂

  2. Dave (Post author)

    @Fred,
    Thanks! That looks pretty good, I might try to work it into the sample.

    In a real-world app I’m working on, I actually do have a collection of items (gauges) which are in a gauge directive and I build them dynamically and add them to the shapeshift container.

    For my app, I need the user to drag a gauge from one container to another shapeshift container and lay them out. They choose a gauge on the left and drag as many as they want to the container on the right.

    There is a bug (and work around) in shapeshift.js where when you clone an item it won’t do a deep copy (no events and handlers) but I have a work around for that too. So my gauge directive items all layout properly as they are, but I might try to work in your code here with a dynamic sample on Github to see how it goes. Next post will likely be the gauge directive, so stay tuned.

  3. Fred

    @Dave,

    In an other app’, I tried to do like you (drag & drop item to shapeshift container) and the only advice I can give you to deal with this, is to do not think about copy, but just leave user believe he drag a new item : then, you inject a chid into your shaped container, instead of realy drop item copy he dragged.

    To finish my thought about shapeshift :
    – you have to listen for “ss-arranged” event (or other event) after you put the last shaped item
    – For a better style, you need to declare 2 directives :
    * ShapeShiftContainer to apply basic CSS (like default width or height) (on the parent container)
    * ShapeItem : as I mentioned earlier

    Sorry for the first post, which be “sanitized” of HTML instructions by your CMS…

Comments are closed.