scratch – Blame information for rev 125

Subversion Repositories:
Rev:
Rev Author Line No. Line
125 office 1 /*
2 * bootstrap-tagsinput v0.8.0
3 *
4 */
5  
6 angular.module('bootstrap-tagsinput', [])
7 .directive('bootstrapTagsinput', [function() {
8  
9 function getItemProperty(scope, property) {
10 if (!property)
11 return undefined;
12  
13 if (angular.isFunction(scope.$parent[property]))
14 return scope.$parent[property];
15  
16 return function(item) {
17 return item[property];
18 };
19 }
20  
21 return {
22 restrict: 'EA',
23 scope: {
24 model: '=ngModel'
25 },
26 template: '<select multiple></select>',
27 replace: false,
28 link: function(scope, element, attrs) {
29 $(function() {
30 if (!angular.isArray(scope.model))
31 scope.model = [];
32  
33 var select = $('select', element);
34 var typeaheadSourceArray = attrs.typeaheadSource ? attrs.typeaheadSource.split('.') : null;
35 var typeaheadSource = typeaheadSourceArray ?
36 (typeaheadSourceArray.length > 1 ?
37 scope.$parent[typeaheadSourceArray[0]][typeaheadSourceArray[1]]
38 : scope.$parent[typeaheadSourceArray[0]])
39 : null;
40  
41 select.tagsinput(scope.$parent[attrs.options || ''] || {
42 typeahead : {
43 source : angular.isFunction(typeaheadSource) ? typeaheadSource : null
44 },
45 itemValue: getItemProperty(scope, attrs.itemvalue),
46 itemText : getItemProperty(scope, attrs.itemtext),
47 confirmKeys : getItemProperty(scope, attrs.confirmkeys) ? JSON.parse(attrs.confirmkeys) : [13],
48 tagClass : angular.isFunction(scope.$parent[attrs.tagclass]) ? scope.$parent[attrs.tagclass] : function(item) { return attrs.tagclass; }
49 });
50  
51 for (var i = 0; i < scope.model.length; i++) {
52 select.tagsinput('add', scope.model[i]);
53 }
54  
55 select.on('itemAdded', function(event) {
56 if (scope.model.indexOf(event.item) === -1)
57 scope.model.push(event.item);
58 });
59  
60 select.on('itemRemoved', function(event) {
61 var idx = scope.model.indexOf(event.item);
62 if (idx !== -1)
63 scope.model.splice(idx, 1);
64 });
65  
66 // create a shallow copy of model's current state, needed to determine
67 // diff when model changes
68 var prev = scope.model.slice();
69 scope.$watch("model", function() {
70 var added = scope.model.filter(function(i) {return prev.indexOf(i) === -1;}),
71 removed = prev.filter(function(i) {return scope.model.indexOf(i) === -1;}),
72 i;
73  
74 prev = scope.model.slice();
75  
76 // Remove tags no longer in binded model
77 for (i = 0; i < removed.length; i++) {
78 select.tagsinput('remove', removed[i]);
79 }
80  
81 // Refresh remaining tags
82 select.tagsinput('refresh');
83  
84 // Add new items in model as tags
85 for (i = 0; i < added.length; i++) {
86 select.tagsinput('add', added[i]);
87 }
88 }, true);
89 });
90 }
91 };
92 }]);