Free Angular Provider Templates

featured

 

The wait is over for those of you longing for the scripts I used in the Angular Providers webinar on May 1. I apologize for the delay, although I do have excuses:

  1. I was completely consumed over the last two weeks with debuting our brand new Haiku Theory service portal accelerator at K18. Stay tuned for more info on that!
  2. While at K18, the SN dev instance I used for the webinar was ‘reclaimed’, as if it was going to make a nice coffee table or something.

Here’s the link to the webinar, in case you haven’t seen it, or want to watch it over and over.
SN Ask the Experts: Understanding Angular Providers

Without further ado, the scripts:

SERVICE

A service can be used to share scripts and data across the client side of widgets. Multiple widgets can all create references to objects initialized by the service, therefore many widgets can share the same data and functions.

module: Angular Providers

For your copy/paste pleasure:

//Inject whatever services you want to use
function($location) {

  //Initialize some properties if you like
  var myData = {};
 
  return {
    //These functions, can be accessed by any widget that injects this service into its controller script

    getMyData: function() {
      return myData;
    },

    someFunction: function(input) {
      //Do some stuff. Really go crazy man.
      var someStuff = !input;
      $location.get('stuff', someStuff);

      return someStuff;
    }
  };

}

 

WIDGET CONTROLLER

To include the above service in a widget, simply inject it into the controller function by name. Then remember to add this service to the widget’s Angular Providers related list.

module: Widgets

See how I make use of the service’s functions and make local references to them? Very handy.

Copypasta:

function(myMenuService) {
  var c = this;

  //Map a local property to your service
  c.myMenu = myMenuService;
  
  //Call the service's functions to reference objects and do stuff
  c.myData = c.myMenu.getMyData();
  c.someValue = c.myMenu.someFunction(someInput);
}

 

DIRECTIVE

Now say that you wanted to enhance your widget’s HTML with powerful mini templates. This example directive will create an HTML element with a link that calls a function provided by the directive’s own link function.

Just like the service, be sure to add this to your widget’s Angular Providers related list.

module: Angular Providers

C/P:

function myMenuItem() {
  return {
    restrict: 'E',
      /*
      controls how you intend to reference (call) the directive
      A: by attribute: <div your-directive></div>
      E: by element name: <your-directive></your-directive>
      C: by class name: <div class="your-directive"></div>
      M: by comment <!-- directive: your-directive -->
      */
    scope: true,
      /*
      false: Use the parent's scope. Making changes to the scope in the directive will update the scope of the widget.
      true: Clone the parent's scope. The directive gets a copy of the parent's scope, but making changes to the scope in the directive will not be reflected in the parent's scope.
      {}: By providing an object you isolate the scope, meaning this directive has it's own empty scope, not related to the parent's scope. You can define the directive's scope via attribute:
        Example - scope: { =someProperty }
          In this case, someProperty gets passed through to this directive via the directive's attribute:
          <my-menu-item some-property="someValue"></my-menu-item>
        There are many ways to do this. Google it for more examples and info.
      */
    replace: true,
      /*
      true: the entire HTML element that references this directive will be replaced by this template
      */
    link: function(scope) {
      /*
      Provide your own client controller for this directive.
      Inject the parent's scope and get access to everything the widget does.
      */
      scope.toggleSomething = function(item) {
        scope.server.get({'action': 'toggle', 'item': item}).then(function(response){
          item.property = !item.property; 
        });
      };
    },
    template: '<div>' +
      '<a href="javascript:void(0)" ng-click="toggleSomething(item)">{{item.label}}</a>' +
    '</div>',
      /*
      Write your HTML in string form.
      Be sure to use \ to escape apostrophes inside your strings.
      Directives can have only one parent HTML element.
      */
    templateURL: 'someTemplateURL.html'
      /*
      Or provide a template in the sp_ng_template table. That's much easier than writing the HTML in script form, but remember to attach them to your widget via the Templates related list.
      */
 };
}

This directive is used in your widget’s HTML just like this:

<my-menu-item ng-repeat="item in c.Items"></my-menu-item>

FILTER MODULE

I also showed you an example of how to use a filter module. The filter I showed would remove duplicate entries from an array when using ng-repeat.

module: UI Scripts

Copypasta:

(function() {
  angular.module('myFilter', []).filter('myUniqueFilter', function() {
    //This filter will remove any duplicates from the input array based on the provided filterBy property
     // *input* is the array of objects being iterated.
     // *filterBy* is the name of the property you want to filter by

    //Use this in your HTML template like this:
     //<div ng-repeat=" item in c.Items | uniqueFilter : 'label' " >{{ item.label }}</div>
    
    //This is a UI Script included in the portal via portal dependencies

    return function(input, filterBy) {
      if(input) {
        if (filterBy) {
          var output = [];
          //start with an empty output array
          for (var i = 0; i < input.length; i++) {
            //for each item in the input array, see if there's a matching item in the output
            var unique = true;
            for (var o = 0; o < output.length; o++) {
              //Look for an existing item in the output array.
              if(output[o][filterBy] === input[i][filterBy]) {
                unique = false;
              }
            }
            if(unique) {
              //If item doesn't already exist in the output array, put it there
              output.push(input[i]);
            }
          }
          return output;
        } else {
          //If no filterBy property has been provided, return the entire input array
          return input;
        }
      } else {
        console.log('there is no input');
        input = [];
        return input;
      }
    };
  });
})();

To use this, first add this script as a dependency to your widget via the Dependencies related list.

module: Dependencies

Now you can reference the filter in an ng-repeat expression:

<div ng-repeat=" item in c.Items | myUniqueFilter : 'label' " >{{ item.label }}</div>

 

BONUS

For sticking around until the end, here’s a bonus. This is me debuting Haiku Theory at K18 last week in Las Vegas. Can’t wait to share more info about that in the coming weeks.

Aloha,
Jeff

Knowledge18, Las Vegas