Widgets with different dynamic content (angular-gridster)

7.7k views Asked by At

I am trying to create a web dashboard based on angularjs with angular-gridster module. The gridster works fine and I don't have any problems binding content to it (like text or images with ng-bind-html).

But in fact I don't want to add only text or images to these "widgets", I'm trying to create a dashboard with dynamic content in it. So, as a user I want to add a new widget to the dashboard and choose a type (for example a clock-widget or something else) and maybe configure the widget.

The problem is that I don't know how to add dynamic content (javascript, different html elements, ...) to a widget. The widget is created out of a scope object, like:

$scope.standardItems = [
    { name: "Item 1", content: "Text 1", sizeX: 2, sizeY: 1, row: 0, col: 0 },
    { name: "Item 2", content: "Clock widget", sizeX: 2, sizeY: 2, row: 0, col: 2 }
];

I am still a beginner in angular so excuse me if this is a stupid question...

What could be a good solution to add javascript and html elements? Directives? Own Modules? But how?

Thank you for your help!

1

There are 1 answers

6
tjacks3 On BEST ANSWER

In-order to add dynamic content you will have to create custom directives for each widget, then reference them inside your standardItems object that your are going to ng-repeat on your gridster grid.

scope.standardItems = [{
  title: 'Clock Widget',
  settings: {
    sizeX: 3,
    sizeY: 3,
    minSizeX: 3,
    minSizeY: 3,
    template: '<clock-widget></clock-widget>',
    widgetSettings: {
      id: 1
    }
  }
}]

Ok, you should have a directive for your gridster widget definitions that has an object with your custom widgets definitions and maybe some default gridster options.

I recommend creating a custom widgetBody directive that all of your custom widgets will reference. This directive will also handle the custom buttons attached to each widget's header depending on how you style your widgets. You will also need to create an associated template for the directive.

"use strict";
angular.module('myGridsterDashboard').directive('widgetBody', ['$compile',
  function($compile) {
    return {
      templateUrl: 'widgetBodyTemplate.html',
      link: function(scope, element, attrs) {
        // create a new angular element from the resource in the
        // inherited scope object so it can compile the element 
        // the item element represents the custom widgets
        var newEl = angular.element(scope.item.template);
        // using jQuery after new element creation, to append element
        element.append(newEl);
        // returns a function that is looking for scope
        // use angular compile service to instanitate a new widget element
        $compile(newEl)(scope);


      }

    }

  }
]);

After you have created your directive, then you need to reference that directive inside your main template where you are doing your gridster ng-repeat for your custom widgets.

 <!-- reference your default gridster options if you created some -->
<div gridster="gridsterOpts">
<ul>
    <li gridster-item="item" ng-repeat="item in standardItems">
        <!-- created a custom directive to compile the widget body and keep it out of the dashboard object -->
        <widget-body></widget-body>
    </li>
</ul>   

So now by inheritance each custom widget that you create will inherit the widget body and will get compiled and added to the DOM one-by-one inside of your ng-repeat directive.

Hope this helps.... - Pluralsight course by Mark Zamoyta entitled "Building a SPA framework Using AngularJS