Directives Demo - Tags

Original Authors: Mike Hills, James Sadler From Meetup Discussion:- http://www.meetup.com/AngularJS-Sydney/events/94759382/ Note use of all 3 main isolate methods!

by michaeldausmann

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<h1>Demo 3 - Tag input form</h1>
<div ng-app='tags-demo' ng-controller="TagsController">
  <h2>Existing tags: click to remove</h2>
  <div ps-tag-cloud="existingTags"
       ps-tag-class="add"
       ps-tag-action='onExistingTagClicked(tag)'></div>
  <h2>Suggested tags: click to add</h2>
  <div ps-tag-cloud="suggestedTags"
       ps-tag-class="remove"
       ps-tag-action='onSuggestedTagClicked(tag)'></div>
  <h2>Enter new tags</h2>
  <div ps-tag-input="existingTags"></div>
</div>

CSS

h1 {
    font-weight: bold;
    font-size: 18px;
    margin-bottom: 10px;
}

h2 {
    margin: 10px 0 5px;
}

.tag + .tag {
    margin-left: 10px;
}
.tag {
    display: inline-block;
    border-radius: 5px;
    padding: 2px 5px;
    cursor: pointer;
}

.add {
    border: solid 1px #88f;
    background: #ddf;
}
.add:hover {
    background: #bbf;
}
.remove {
    border: solid 1px #8f8;
    background: #dfd;
}
.remove:hover {
    background: #bfb;
}

input {
    width: 250px;
}

JavaScript

var app = angular.module('tags-demo', []);

app.controller('TagsController', ['$scope', function(scope) {
	scope.suggestedTags = ['Good Atmosphere', 'Friendly Staff', 'Steak'];
    scope.existingTags = ['Bread', 'Toast', 'Crumpets'];
    
    scope.onExistingTagClicked = function(tag) {
    	scope.existingTags.splice(scope.existingTags.indexOf(tag), 1);
    };
    
    scope.onSuggestedTagClicked = function(tag) {
    	scope.suggestedTags.splice(scope.suggestedTags.indexOf(tag), 1);
        scope.existingTags.push(tag);
    };
}]);

app.directive('psTagCloud', [function() {
    return {
        scope: {
            psTagCloud: '=',
            psTagAction: '&',
            psTagClass: '@'
        },
        template: '<div class="tagCloud"> \
                    <div class="tag default {{ psTagClass }}" \
                         ng-repeat="dTag in psTagCloud" \
						 ng-click="psTagAction({tag:dTag})"> \
                      <span class="tagCap"><span class="icon"></span></span> \
					  <span class="content">{{ dTag }}</span> \
                    </div> \
                  </div>'
	};
}]);

app.directive('psTagInput', [function() {
  return {
    scope: { psTagInput: '=' },
    template: '<form class="tagInputForm" ng-submit="addTag(tag)"> \
                <input class="tagField" type="text" \
                       placeholder="type and press enter to add" \
                       ng-model="tag" maxlength="127" \
                       ng-change="highlightTag(tag)"/> \
               </form>',
    link: function(scope, element, attrs) {
        scope.addTag = function(tag) {
      		scope.psTagInput.push(tag);
            scope.tag = null;
        };
        scope.$on('tagsChanged', function(){
           setTimeout(function() {
              $('input', element).focus();
           }, 0);
        });
    }
  };
}]);