From 9eed04d9a7be998c9491bbdcd67596b7de15174e Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Thu, 25 Feb 2021 10:50:49 -0500 Subject: [PATCH] Afform - move contentEditable directive into crmUI library for reusability --- ang/crmUi.js | 51 +++++++++++++++++- ext/afform/admin/ang/afGuiEditor.css | 1 + .../ang/afGuiEditor/afGuiEditOptions.html | 2 +- .../afGuiEditor/afGuiEditable.directive.js | 53 ------------------- .../ang/afGuiEditor/afGuiEditorPalette.html | 2 +- .../ang/afGuiEditor/elements/afGuiButton.html | 2 +- .../afGuiEditor/elements/afGuiContainer.html | 2 +- .../ang/afGuiEditor/elements/afGuiField.html | 6 +-- .../ang/afGuiEditor/elements/afGuiText.html | 2 +- 9 files changed, 58 insertions(+), 63 deletions(-) delete mode 100644 ext/afform/admin/ang/afGuiEditor/afGuiEditable.directive.js diff --git a/ang/crmUi.js b/ang/crmUi.js index 87d15f7f60..20ee8b1a8f 100644 --- a/ang/crmUi.js +++ b/ang/crmUi.js @@ -1083,13 +1083,60 @@ }; }) + // Editable text using ngModel & html5 contenteditable + // Usage: {{ my.data }} + .directive("crmUiEditable", function() { + return { + restrict: "A", + require: "ngModel", + scope: { + defaultValue: '=' + }, + link: function(scope, element, attrs, ngModel) { + var ts = CRM.ts(); + + function read() { + var htmlVal = element.html(); + if (!htmlVal) { + htmlVal = scope.defaultValue || ''; + element.text(htmlVal); + } + ngModel.$setViewValue(htmlVal); + } + + ngModel.$render = function() { + element.text(ngModel.$viewValue || scope.defaultValue || ''); + }; + + // Special handling for enter and escape keys + element.on('keydown', function(e) { + // Enter: prevent line break and save + if (e.which === 13) { + e.preventDefault(); + element.blur(); + } + // Escape: undo + if (e.which === 27) { + element.text(ngModel.$viewValue || scope.defaultValue || ''); + element.blur(); + } + }); + + element.on("blur change", function() { + scope.$apply(read); + }); + + element.attr('contenteditable', 'true').addClass('crm-editable-enabled'); + } + }; + }) + .run(function($rootScope, $location) { /// Example: $rootScope.goto = function(path) { $location.path(path); }; // useful for debugging: $rootScope.log = console.log || function() {}; - }) - ; + }); })(angular, CRM.$, CRM._); diff --git a/ext/afform/admin/ang/afGuiEditor.css b/ext/afform/admin/ang/afGuiEditor.css index d38dfc3ac5..330b3b4e46 100644 --- a/ext/afform/admin/ang/afGuiEditor.css +++ b/ext/afform/admin/ang/afGuiEditor.css @@ -53,6 +53,7 @@ display: inline-block; padding: 0 4px !important; border: 2px solid transparent !important; + min-width: 21px; } #afGuiEditor .crm-editable-enabled:hover:not(:focus) { border: 2px dashed grey !important; diff --git a/ext/afform/admin/ang/afGuiEditor/afGuiEditOptions.html b/ext/afform/admin/ang/afGuiEditor/afGuiEditOptions.html index cb9677ac12..1553eb90b2 100644 --- a/ext/afform/admin/ang/afGuiEditor/afGuiEditOptions.html +++ b/ext/afform/admin/ang/afGuiEditor/afGuiEditOptions.html @@ -13,7 +13,7 @@