diff --git a/horizon/static/framework/widgets/contenteditable/contenteditable.directive.js b/horizon/static/framework/widgets/contenteditable/contenteditable.directive.js new file mode 100644 index 0000000000..401a3fbcc0 --- /dev/null +++ b/horizon/static/framework/widgets/contenteditable/contenteditable.directive.js @@ -0,0 +1,59 @@ +/** + * (c) Copyright 2016 Cisco Systems + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use self file except in compliance with the License. You may obtain + * a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +(function() { + 'use strict'; + + /** + * @ngdoc directive + * @name horizon.framework.widgets.contenteditable + * @description + * Allows the use of contenteditable with ng-model. Altered from + * https://docs.angularjs.org/api/ng/type/ngModel.NgModelController + */ + + angular + .module('horizon.framework.widgets.contenteditable') + .directive('contenteditable', contenteditable); + + function contenteditable() { + var directive = { + restrict: 'A', + require: '?ngModel', // get a hold of NgModelController + link: link + }; + return directive; + + function link(scope, element, attrs, ngModel) { + if (!ngModel) { return; } // do nothing if no ng-model + + // Specify how UI should be updated + ngModel.$render = function() { + element.html(ngModel.$viewValue || ''); + }; + + // Listen for change events to enable binding + element.on('blur keyup change', function() { + scope.$evalAsync(read); + }); + read(); + + function read() { + ngModel.$setViewValue(element.html()); + } + } + } +})(); diff --git a/horizon/static/framework/widgets/contenteditable/contenteditable.directive.spec.js b/horizon/static/framework/widgets/contenteditable/contenteditable.directive.spec.js new file mode 100644 index 0000000000..275af4db41 --- /dev/null +++ b/horizon/static/framework/widgets/contenteditable/contenteditable.directive.spec.js @@ -0,0 +1,67 @@ +/** + * Copyright 2016 Cisco Systems + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +(function() { + 'use strict'; + + describe('contenteditable directive', function() { + var $compile, $scope; + + beforeEach(module('horizon.framework.widgets')); + beforeEach(module('horizon.framework.widgets.contenteditable')); + beforeEach(inject(function ($injector) { + $compile = $injector.get('$compile'); + $scope = $injector.get('$rootScope').$new(); + $scope.testData = ''; + })); + + describe('using a model', function() { + var element; + beforeEach(function before() { + element = $compile('
')($scope);
+        $scope.$digest();
+      });
+
+      it('should update the model when content is edited', function () {
+        element.triggerHandler('focus');
+        element.html('foo');
+        $scope.$digest();
+        element.triggerHandler('blur');
+        expect($scope.testData).toBe('foo');
+      });
+
+      it('should update the view when model is changed', function () {
+        element.triggerHandler('focus');
+        $scope.testData = 'spam';
+        $scope.$digest();
+
+        expect(element.html()).toBe('spam');
+      });
+    });
+
+    it('should not do anything without an accompanying ng-model', function() {
+      var element = $compile('
')($scope);
+      $scope.$digest();
+
+      element.triggerHandler('focus');
+      element.html('bar');
+      $scope.$digest();
+      element.triggerHandler('blur');
+
+      expect($scope.testData).toBe('');
+    });
+  });
+})();
diff --git a/horizon/static/framework/widgets/contenteditable/contenteditable.module.js b/horizon/static/framework/widgets/contenteditable/contenteditable.module.js
new file mode 100644
index 0000000000..ea92536b84
--- /dev/null
+++ b/horizon/static/framework/widgets/contenteditable/contenteditable.module.js
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2016 Cisco Systems, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+(function() {
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name horizon.framework.widgets.contenteditable
+   */
+  angular
+    .module('horizon.framework.widgets.contenteditable', []);
+})();
diff --git a/horizon/static/framework/widgets/form/fields/array.html b/horizon/static/framework/widgets/form/fields/array.html
index 0af7b93da3..9d0667ecf8 100644
--- a/horizon/static/framework/widgets/form/fields/array.html
+++ b/horizon/static/framework/widgets/form/fields/array.html
@@ -2,8 +2,8 @@
      sf-field-model="sf-new-array"
      sf-new-array>
   
-  
    -
  1. +
  2. diff --git a/horizon/static/framework/widgets/form/fields/fieldset.html b/horizon/static/framework/widgets/form/fields/fieldset.html index 5c46d8118f..471bc5ba78 100644 --- a/horizon/static/framework/widgets/form/fields/fieldset.html +++ b/horizon/static/framework/widgets/form/fields/fieldset.html @@ -1,4 +1,4 @@
    - {$:: form.title $} + {$:: form.title $}
    diff --git a/horizon/static/framework/widgets/form/fields/tabarray.html b/horizon/static/framework/widgets/form/fields/tabarray.html index 08f20f1bd6..fd65473301 100644 --- a/horizon/static/framework/widgets/form/fields/tabarray.html +++ b/horizon/static/framework/widgets/form/fields/tabarray.html @@ -2,10 +2,10 @@ ng-model="modelArray" schema-validate="form" sf-field-model="sf-new-array" sf-new-array - class="clearfix hz-tabarray schema-form-tabarray-{$form.tabType || 'left'$} {$form.htmlClass$}"> + class="clearfix hz-tabarray schema-form-tabarray-{$form.tabType || 'left'$} {::$form.htmlClass$}">
    -
    -
    +
    + class="btn {$:: form.style.remove || 'btn-danger' $} pull-right"> {$::form.remove || 'Remove'$} @@ -50,7 +50,7 @@
    -