true to disable the button.
@param {string=} addEllipsis Adds an ellipsis character (…) to the button label which means the button will open a dialog or prompt the user for more information.
+@param {string=} showCaret Shows a caret on the right side of the button label
**/
@@ -93,7 +94,8 @@ Use this directive to render an umbraco button. The directive can be used to gen
disabled: "",
size: "@?",
alias: "@?",
- addEllipsis: "@?"
+ addEllipsis: "@?",
+ showCaret: "@?"
}
});
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbbuttongroup.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbbuttongroup.directive.js
index bce81c1ffd..74f0870f1b 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbbuttongroup.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/buttons/umbbuttongroup.directive.js
@@ -89,30 +89,52 @@ Use this directive to render a button with a dropdown of alternative actions.
@param {string=} float Set the float of the dropdown. ("left", "right").
**/
-(function() {
- 'use strict';
+(function () {
+ 'use strict';
- function ButtonGroupDirective() {
+ function ButtonGroupDirective() {
- var directive = {
- restrict: 'E',
- replace: true,
- templateUrl: 'views/components/buttons/umb-button-group.html',
- scope: {
- defaultButton: "=",
- subButtons: "=",
- state: "=?",
- direction: "@?",
- float: "@?",
- buttonStyle: "@?",
- size: "@?",
- icon: "@?"
- }
- };
+ function link(scope) {
- return directive;
- }
+ scope.dropdown = {
+ isOpen: false
+ };
- angular.module('umbraco.directives').directive('umbButtonGroup', ButtonGroupDirective);
+ scope.toggleDropdown = function() {
+ scope.dropdown.isOpen = !scope.dropdown.isOpen;
+ };
+
+ scope.closeDropdown = function() {
+ scope.dropdown.isOpen = false;
+ };
+
+ scope.executeMenuItem = function(subButton) {
+ subButton.handler();
+ scope.closeDropdown();
+ };
+
+ }
+
+ var directive = {
+ restrict: 'E',
+ replace: true,
+ templateUrl: 'views/components/buttons/umb-button-group.html',
+ scope: {
+ defaultButton: "=",
+ subButtons: "=",
+ state: "=?",
+ direction: "@?",
+ float: "@?",
+ buttonStyle: "@?",
+ size: "@?",
+ icon: "@?"
+ },
+ link: link
+ };
+
+ return directive;
+ }
+
+ angular.module('umbraco.directives').directive('umbButtonGroup', ButtonGroupDirective);
})();
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js
index 422c02c87c..407416f2a1 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js
@@ -97,13 +97,6 @@
eventsService.unsubscribe(evts[e]);
}
- evts.push(eventsService.on("editors.documentType.saved", function (name, args) {
- // if this content item uses the updated doc type we need to reload the content item
- if (args && args.documentType && args.documentType.key === $scope.content.documentType.key) {
- loadContent();
- }
- }));
-
evts.push(eventsService.on("editors.content.reload", function (name, args) {
// if this content item uses the updated doc type we need to reload the content item
if(args && args.node && args.node.key === $scope.content.key) {
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js
index 78efc8f789..31e847f0f6 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbcontentnodeinfo.directive.js
@@ -1,7 +1,7 @@
(function () {
'use strict';
- function ContentNodeInfoDirective($timeout, $routeParams, logResource, eventsService, userService, localizationService, dateHelper, editorService, redirectUrlsResource) {
+ function ContentNodeInfoDirective($timeout, logResource, eventsService, userService, localizationService, dateHelper, editorService, redirectUrlsResource, overlayService) {
function link(scope, element, attrs, umbVariantContentCtrl) {
@@ -17,10 +17,13 @@
function onInit() {
+ // if there are any infinite editors open we are in infinite editing
+ scope.isInfiniteMode = editorService.getNumberOfEditors() > 0 ? true : false;
+
userService.getCurrentUser().then(function(user){
// only allow change of media type if user has access to the settings sections
angular.forEach(user.sections, function(section){
- if(section.alias === "settings") {
+ if(section.alias === "settings" && !scope.isInfiniteMode) {
scope.allowChangeDocumentType = true;
scope.allowChangeTemplate = true;
}
@@ -32,7 +35,9 @@
"content_unpublished",
"content_published",
"content_publishedPendingChanges",
- "content_notCreated"
+ "content_notCreated",
+ "prompt_unsavedChanges",
+ "prompt_doctypeChangeWarning"
];
localizationService.localizeMany(keys)
@@ -42,6 +47,8 @@
labels.published = data[2];
labels.publishedPendingChanges = data[3];
labels.notCreated = data[4];
+ labels.unsavedChanges = data[5];
+ labels.doctypeChangeWarning = data[6];
setNodePublishStatus(scope.node);
@@ -84,9 +91,40 @@
};
scope.openDocumentType = function (documentType) {
- var editor = {
+
+ const variantIsDirty = _.some(scope.node.variants, function(variant) {
+ return variant.isDirty;
+ });
+
+ // add confirmation dialog before opening the doc type editor
+ if(variantIsDirty) {
+ const confirm = {
+ title: labels.unsavedChanges,
+ view: "default",
+ content: labels.doctypeChangeWarning,
+ submitButtonLabelKey: "general_continue",
+ closeButtonLabelKey: "general_cancel",
+ submit: function() {
+ openDocTypeEditor(documentType);
+ overlayService.close();
+ },
+ close: function() {
+ overlayService.close();
+ }
+ };
+ overlayService.open(confirm);
+ } else {
+ openDocTypeEditor(documentType);
+ }
+
+ };
+
+ function openDocTypeEditor(documentType) {
+ const editor = {
id: documentType.id,
submit: function(model) {
+ const args = { node: scope.node };
+ eventsService.emit('editors.content.reload', args);
editorService.close();
},
close: function() {
@@ -94,7 +132,7 @@
}
};
editorService.documentTypeEditor(editor);
- };
+ }
scope.openTemplate = function () {
var templateEditor = {
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditormenu.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditormenu.directive.js
index b6af7a4ca6..22939c7f2c 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditormenu.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditormenu.directive.js
@@ -1,50 +1,63 @@
-(function() {
- 'use strict';
+(function () {
+ 'use strict';
- function EditorMenuDirective($injector, treeService, navigationService, umbModelMapper, appState) {
+ function EditorMenuDirective($injector, treeService, navigationService, umbModelMapper, appState) {
- function link(scope, el, attr, ctrl) {
+ function link(scope, el, attr, ctrl) {
- //adds a handler to the context menu item click, we need to handle this differently
- //depending on what the menu item is supposed to do.
- scope.executeMenuItem = function (action) {
- navigationService.executeMenuAction(action, scope.currentNode, scope.currentSection);
- };
+ scope.dropdown = {
+ isOpen: false
+ };
- //callback method to go and get the options async
- scope.getOptions = function () {
+ function onInit() {
- if (!scope.currentNode) {
- return;
- }
+ getOptions();
- //when the options item is selected, we need to set the current menu item in appState (since this is synonymous with a menu)
- appState.setMenuState("currentNode", scope.currentNode);
+ }
- if (!scope.actions) {
- treeService.getMenu({ treeNode: scope.currentNode })
- .then(function (data) {
- scope.actions = data.menuItems;
- });
- }
- };
+ //adds a handler to the context menu item click, we need to handle this differently
+ //depending on what the menu item is supposed to do.
+ scope.executeMenuItem = function (action) {
+ navigationService.executeMenuAction(action, scope.currentNode, scope.currentSection);
+ scope.dropdown.isOpen = false;
+ };
- }
+ //callback method to go and get the options async
+ function getOptions() {
- var directive = {
- restrict: 'E',
- replace: true,
- templateUrl: 'views/components/editor/umb-editor-menu.html',
- link: link,
- scope: {
- currentNode: "=",
- currentSection: "@"
- }
- };
+ if (!scope.currentNode) {
+ return;
+ }
- return directive;
- }
+ //when the options item is selected, we need to set the current menu item in appState (since this is synonymous with a menu)
+ appState.setMenuState("currentNode", scope.currentNode);
- angular.module('umbraco.directives').directive('umbEditorMenu', EditorMenuDirective);
+ if (!scope.actions) {
+ treeService.getMenu({ treeNode: scope.currentNode })
+ .then(function (data) {
+ scope.actions = data.menuItems;
+ });
+ }
+ };
+
+ onInit();
+
+ }
+
+ var directive = {
+ restrict: 'E',
+ replace: true,
+ templateUrl: 'views/components/editor/umb-editor-menu.html',
+ link: link,
+ scope: {
+ currentNode: "=",
+ currentSection: "@"
+ }
+ };
+
+ return directive;
+ }
+
+ angular.module('umbraco.directives').directive('umbEditorMenu', EditorMenuDirective);
})();
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/contenteditable.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/contenteditable.directive.js
index 08eae2f378..219d42a04e 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/contenteditable.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/contenteditable.directive.js
@@ -14,7 +14,7 @@ angular.module("umbraco.directives")
};
- element.bind("focus", function(){
+ element.on("focus", function(){
var range = document.createRange();
range.selectNodeContents(element[0]);
@@ -25,7 +25,7 @@ angular.module("umbraco.directives")
});
- element.bind("blur keyup change", function() {
+ element.on("blur keyup change", function() {
scope.$apply(read);
});
}
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/fixnumber.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/fixnumber.directive.js
index 039c189ac2..3084472332 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/fixnumber.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/fixnumber.directive.js
@@ -46,7 +46,7 @@ function fixNumber($parse) {
return;
}
- elem.bind('input', function (e) {
+ elem.on('input', function (e) {
var validity = elem.prop('validity');
scope.$apply(function () {
ctrl.$setValidity('number', !validity.badInput);
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/focuswhen.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/focuswhen.directive.js
index 5d57b29175..d8dbcc1012 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/focuswhen.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/focuswhen.directive.js
@@ -5,7 +5,7 @@ angular.module("umbraco.directives").directive('focusWhen', function ($timeout)
attrs.$observe("focusWhen", function (newValue) {
if (newValue === "true") {
$timeout(function () {
- elm.focus();
+ elm.trigger("focus");
});
}
});
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/hotkey.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/hotkey.directive.js
index 240f666632..b4040d1c77 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/hotkey.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/hotkey.directive.js
@@ -43,15 +43,15 @@ angular.module("umbraco.directives")
// when keycombo is enter and a link or button has focus - click the link or button instead of using the hotkey
if (keyCombo === "enter" && clickableElements.indexOf(activeElementType) === 0) {
- document.activeElement.click();
+ document.activeElement.trigger( "click" );
} else {
- element.click();
+ element.trigger("click");
}
}
} else {
- element.focus();
+ element.trigger("focus");
}
}, options);
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/preventdefault.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/preventdefault.directive.js
index df665be727..4391e39bef 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/preventdefault.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/preventdefault.directive.js
@@ -25,7 +25,7 @@ angular.module("umbraco.directives")
});
}
- $(element).click(function (event) {
+ $(element).on("click", function (event) {
if (event.metaKey || event.ctrlKey) {
return;
}
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/prevententersubmit.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/prevententersubmit.directive.js
index 42133aa0e1..355b02216f 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/prevententersubmit.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/prevententersubmit.directive.js
@@ -16,7 +16,7 @@ angular.module("umbraco.directives")
});
}
- $(element).keypress(function (event) {
+ $(element).on("keypress", function (event) {
if (event.which === 13) {
event.preventDefault();
}
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/selectonfocus.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/selectonfocus.directive.js
index 1e78b88041..cb30023b29 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/selectonfocus.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/selectonfocus.directive.js
@@ -1,7 +1,7 @@
angular.module("umbraco.directives")
.directive('selectOnFocus', function () {
return function (scope, el, attrs) {
- $(el).bind("click", function () {
+ $(el).on("click", function () {
var editmode = $(el).data("editmode");
//If editmode is true a click is handled like a normal click
if (!editmode) {
@@ -11,7 +11,7 @@ angular.module("umbraco.directives")
$(el).data("editmode", true);
}
}).
- bind("blur", function () {
+ on("blur", function () {
//Reset on focus lost
$(el).data("editmode", false);
});
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/umbautofocus.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/umbautofocus.directive.js
index bb65e94593..6fcdd99001 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/umbautofocus.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/umbautofocus.directive.js
@@ -5,7 +5,7 @@ angular.module("umbraco.directives")
var update = function() {
//if it uses its default naming
if(element.val() === "" || attr.focusOnFilled){
- element.focus();
+ element.trigger("focus");
}
};
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/umbautoresize.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/umbautoresize.directive.js
index 8a456670c3..56dfb6b180 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/umbautoresize.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/forms/umbautoresize.directive.js
@@ -142,8 +142,8 @@ angular.module("umbraco.directives")
});
scope.$on('$destroy', function() {
- element.unbind('keyup keydown keypress change', update);
- element.unbind('blur', update(true));
+ element.off('keyup keydown keypress change', update);
+ element.off('blur', update(true));
unbindModelWatcher();
// clean up IE dom element
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js
index dc2eb75bb2..0dddada8ad 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/grid/grid.rte.directive.js
@@ -67,7 +67,7 @@ angular.module("umbraco.directives")
$timeout(function () {
if (scope.value === null) {
- editor.focus();
+ editor.trigger("focus");
}
}, 400);
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js
index cdcdb7313c..ffa76a57c3 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/imaging/umbimagecrop.directive.js
@@ -266,7 +266,7 @@ angular.module("umbraco.directives")
//ie hack
if(window.navigator.userAgent.indexOf("MSIE ") >= 0){
var ranger = element.find("input");
- ranger.bind("change",function(){
+ ranger.on("change",function(){
scope.$apply(function(){
scope.dimensions.scale.current = ranger.val();
});
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/overlays/umboverlay.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/overlays/umboverlay.directive.js
index 07cfbb9848..9f9f1aa21e 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/overlays/umboverlay.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/overlays/umboverlay.directive.js
@@ -500,7 +500,7 @@ Opens an overlay to show a custom YSOD.
overlayNumber = overlayHelper.registerOverlay();
- $(document).bind("keydown.overlay-" + overlayNumber, function(event) {
+ $(document).on("keydown.overlay-" + overlayNumber, function(event) {
if (event.which === 27) {
@@ -527,7 +527,7 @@ Opens an overlay to show a custom YSOD.
var submitOnEnterValue = submitOnEnter ? document.activeElement.getAttribute("overlay-submit-on-enter") : "";
if(clickableElements.indexOf(activeElementType) === 0) {
- document.activeElement.click();
+ document.activeElement.trigger("click");
event.preventDefault();
} else if(activeElementType === "TEXTAREA" && !submitOnEnter) {
@@ -557,7 +557,7 @@ Opens an overlay to show a custom YSOD.
overlayHelper.unregisterOverlay();
- $(document).unbind("keydown.overlay-" + overlayNumber);
+ $(document).off("keydown.overlay-" + overlayNumber);
isRegistered = false;
}
@@ -582,12 +582,12 @@ Opens an overlay to show a custom YSOD.
var overlayIndex = overlayNumber - 1;
var indentSize = overlayIndex * 20;
- var overlayWidth = el.context.clientWidth;
+ var overlayWidth = el[0].clientWidth;
el.css('width', overlayWidth - indentSize);
if(scope.position === "center" && overlayIndex > 0 || scope.position === "target" && overlayIndex > 0) {
- var overlayTopPosition = el.context.offsetTop;
+ var overlayTopPosition = el[0].offsetTop;
el.css('top', overlayTopPosition + indentSize);
}
@@ -621,8 +621,8 @@ Opens an overlay to show a custom YSOD.
mousePositionClickY = scope.model.event.pageY;
// element size
- elementHeight = el.context.clientHeight;
- elementWidth = el.context.clientWidth;
+ elementHeight = el[0].clientHeight;
+ elementWidth = el[0].clientWidth;
// move element to this position
position.left = mousePositionClickX - (elementWidth / 2);
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tabs/umbtabsnav.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tabs/umbtabsnav.directive.js
index 804bc70f1e..71fa529c84 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tabs/umbtabsnav.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tabs/umbtabsnav.directive.js
@@ -128,12 +128,12 @@ Use this directive to render a tabs navigation.
});
}
- $(window).bind('resize.tabsNav', function () {
+ $(window).on('resize.tabsNav', function () {
calculateWidth();
});
scope.$on('$destroy', function() {
- $(window).unbind('resize.tabsNav');
+ $(window).off('resize.tabsNav');
});
}
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbdatetimepicker.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbdatetimepicker.directive.js
deleted file mode 100644
index 8d2b83d065..0000000000
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbdatetimepicker.directive.js
+++ /dev/null
@@ -1,186 +0,0 @@
-/**
-@ngdoc directive
-@name umbraco.directives.directive:umbDateTimePicker
-@restrict E
-@scope
-
-@description
-Added in Umbraco version 7.6
-This directive is a wrapper of the bootstrap datetime picker version 3.1.3. Use it to render a date time picker.
-For extra details about options and events take a look here: https://eonasdan.github.io/bootstrap-datetimepicker/
-
-Use this directive to render a date time picker
-
--- -- --- - -
- (function () {
- "use strict";
-
- function Controller() {
-
- var vm = this;
-
- vm.date = "";
-
- vm.config = {
- pickDate: true,
- pickTime: true,
- useSeconds: true,
- format: "YYYY-MM-DD HH:mm:ss",
- icons: {
- time: "icon-time",
- date: "icon-calendar",
- up: "icon-chevron-up",
- down: "icon-chevron-down"
- }
- };
-
- vm.datePickerChange = datePickerChange;
- vm.datePickerError = datePickerError;
-
- function datePickerChange(event) {
- // handle change
- if(event.date && event.date.isValid()) {
- var date = event.date.format(vm.datePickerConfig.format);
- }
- }
-
- function datePickerError(event) {
- // handle error
- }
-
- }
-
- angular.module("umbraco").controller("My.Controller", Controller);
-
- })();
-
-
-@param {object} options (binding): Config object for the date picker.
-@param {callback} onHide (callback): Hide callback.
-@param {callback} onShow (callback): Show callback.
-@param {callback} onChange (callback): Change callback.
-@param {callback} onError (callback): Error callback.
-@param {callback} onUpdate (callback): Update callback.
-**/
-
-(function () {
- 'use strict';
-
- function DateTimePickerDirective(assetsService) {
-
- function link(scope, element, attrs, ctrl) {
-
- scope.hasTranscludedContent = false;
-
- function onInit() {
-
- // check for transcluded content so we can hide the defualt markup
- scope.hasTranscludedContent = element.find('.js-datePicker__transcluded-content')[0].children.length > 0;
-
- // load css file for the date picker
- assetsService.loadCss('lib/datetimepicker/bootstrap-datetimepicker.min.css', scope);
-
- // load the js file for the date picker
- assetsService.loadJs('lib/datetimepicker/bootstrap-datetimepicker.js', scope).then(function () {
- // init date picker
- initDatePicker();
- });
- }
-
- function onHide(event) {
- if (scope.onHide) {
- scope.$apply(function(){
- // callback
- scope.onHide({event: event});
- });
- }
- }
-
- function onShow() {
- if (scope.onShow) {
- scope.$apply(function(){
- // callback
- scope.onShow();
- });
- }
- }
-
- function onChange(event) {
- if (scope.onChange && event.date && event.date.isValid()) {
- scope.$apply(function(){
- // callback
- scope.onChange({event: event});
- });
- }
- }
-
- function onError(event) {
- if (scope.onError) {
- scope.$apply(function(){
- // callback
- scope.onError({event:event});
- });
- }
- }
-
- function onUpdate(event) {
- if (scope.onUpdate) {
- scope.$apply(function(){
- // callback
- scope.onUpdate({event: event});
- });
- }
- }
-
- function initDatePicker() {
- // Open the datepicker and add a changeDate eventlistener
- element
- .datetimepicker(scope.options)
- .on("dp.hide", onHide)
- .on("dp.show", onShow)
- .on("dp.change", onChange)
- .on("dp.error", onError)
- .on("dp.update", onUpdate);
- }
-
- onInit();
-
- }
-
- var directive = {
- restrict: 'E',
- replace: true,
- transclude: true,
- templateUrl: 'views/components/umb-date-time-picker.html',
- scope: {
- options: "=",
- onHide: "&",
- onShow: "&",
- onChange: "&",
- onError: "&",
- onUpdate: "&"
- },
- link: link
- };
-
- return directive;
-
- }
-
- angular.module('umbraco.directives').directive('umbDateTimePicker', DateTimePickerDirective);
-
-})();
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbrangeslider.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbrangeslider.directive.js
new file mode 100644
index 0000000000..0003658600
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbrangeslider.directive.js
@@ -0,0 +1,207 @@
+/**
+@ngdoc directive
+@name umbraco.directives.directive:umbRangeSlider
+@restrict E
+@scope
+
+@description
+Added in Umbraco version 8.0
+This directive is a wrapper of the noUiSlider library. Use it to render a slider.
+For extra details about options and events take a look here: https://refreshless.com/nouislider/
+
+++ ++ +++ + +
+ (function () {
+ "use strict";
+
+ function Controller() {
+
+ var vm = this;
+
+ vm.value = [10];
+
+ vm.slideEnd = slideEnd;
+
+ function slideEnd(values) {
+ // handle change
+ }
+
+ }
+
+ angular.module("umbraco").controller("My.Controller", Controller);
+
+ })();
+
+
+@param {object} ngModel (binding): Value for the slider.
+@param {object} options (binding): Config object for the date picker.
+@param {callback} onSetup (callback): onSetup gets triggered when the slider is initialized
+@param {callback} onUpdate (callback): onUpdate fires every time the slider values are changed.
+@param {callback} onSlide (callback): onSlide gets triggered when the handle is being dragged.
+@param {callback} onSet (callback): onSet will trigger every time a slider stops changing.
+@param {callback} onChange (callback): onChange fires when a user stops sliding, or when a slider value is changed by 'tap'.
+@param {callback} onStart (callback): onStart fires when a handle is clicked (mousedown, or the equivalent touch events).
+@param {callback} onEnd (callback): onEnd fires when a handle is released (mouseup etc), or when a slide is canceled due to other reasons.
+**/
+
+
+(function() {
+ 'use strict';
+
+ var umbRangeSlider = {
+ template: '',
+ controller: UmbRangeSliderController,
+ bindings: {
+ ngModel: '<',
+ options: '<',
+ onSetup: '&?',
+ onUpdate: '&?',
+ onSlide: '&?',
+ onSet: '&?',
+ onChange: '&?',
+ onStart: '&?',
+ onEnd: '&?'
+ }
+ };
+
+ function UmbRangeSliderController($element, $timeout, $scope, assetsService) {
+
+ const ctrl = this;
+ let sliderInstance = null;
+
+ ctrl.$onInit = function() {
+
+ // load css file for the date picker
+ assetsService.loadCss('lib/nouislider/nouislider.min.css', $scope);
+
+ // load the js file for the date picker
+ assetsService.loadJs('lib/nouislider/nouislider.min.js', $scope).then(function () {
+ // init date picker
+ grabElementAndRun();
+ });
+
+ };
+
+ function grabElementAndRun() {
+ $timeout(function() {
+ const element = $element.find('.umb-range-slider')[0];
+ setSlider(element);
+ }, 0, true);
+ }
+
+ function setSlider(element) {
+
+ sliderInstance = element;
+
+ const defaultOptions = {
+ "start": [0],
+ "step": 1,
+ "range": {
+ "min": [0],
+ "max": [100]
+ }
+ };
+ const options = ctrl.options ? ctrl.options : defaultOptions;
+
+ // create new slider
+ noUiSlider.create(sliderInstance, options);
+
+ if (ctrl.onSetup) {
+ ctrl.onSetup({
+ slider: sliderInstance
+ });
+ }
+
+ // If has ngModel set the date
+ if (ctrl.ngModel) {
+ sliderInstance.noUiSlider.set(ctrl.ngModel);
+ }
+
+ // destroy the slider instance when the dom element is removed
+ angular.element(element).on('$destroy', function() {
+ sliderInstance.noUiSlider.off();
+ });
+
+ setUpCallbacks();
+
+ // Refresh the scope
+ $scope.$applyAsync();
+ }
+
+ function setUpCallbacks() {
+ if(sliderInstance) {
+
+ // bind hook for update
+ if(ctrl.onUpdate) {
+ sliderInstance.noUiSlider.on('update', function (values, handle, unencoded, tap, positions) {
+ $timeout(function() {
+ ctrl.onUpdate({values: values, handle: handle, unencoded: unencoded, tap: tap, positions: positions});
+ });
+ });
+ }
+
+ // bind hook for slide
+ if(ctrl.onSlide) {
+ sliderInstance.noUiSlider.on('slide', function (values, handle, unencoded, tap, positions) {
+ $timeout(function() {
+ ctrl.onSlide({values: values, handle: handle, unencoded: unencoded, tap: tap, positions: positions});
+ });
+ });
+ }
+
+ // bind hook for set
+ if(ctrl.onSet) {
+ sliderInstance.noUiSlider.on('set', function (values, handle, unencoded, tap, positions) {
+ $timeout(function() {
+ ctrl.onSet({values: values, handle: handle, unencoded: unencoded, tap: tap, positions: positions});
+ });
+ });
+ }
+
+ // bind hook for change
+ if(ctrl.onChange) {
+ sliderInstance.noUiSlider.on('change', function (values, handle, unencoded, tap, positions) {
+ $timeout(function() {
+ ctrl.onChange({values: values, handle: handle, unencoded: unencoded, tap: tap, positions: positions});
+ });
+ });
+ }
+
+ // bind hook for start
+ if(ctrl.onStart) {
+ sliderInstance.noUiSlider.on('start', function (values, handle, unencoded, tap, positions) {
+ $timeout(function() {
+ ctrl.onStart({values: values, handle: handle, unencoded: unencoded, tap: tap, positions: positions});
+ });
+ });
+ }
+
+ // bind hook for end
+ if(ctrl.onEnd) {
+ sliderInstance.noUiSlider.on('end', function (values, handle, unencoded, tap, positions) {
+ $timeout(function() {
+ ctrl.onEnd({values: values, handle: handle, unencoded: unencoded, tap: tap, positions: positions});
+ });
+ });
+ }
+
+ }
+ }
+
+ }
+
+ angular.module('umbraco.directives').component('umbRangeSlider', umbRangeSlider);
+
+})();
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbtooltip.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbtooltip.directive.js
index d3bda41d43..34006a3cec 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbtooltip.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbtooltip.directive.js
@@ -104,8 +104,8 @@ Use this directive to render a tooltip.
};
// element size
- elementHeight = el.context.clientHeight;
- elementWidth = el.context.clientWidth;
+ elementHeight = el[0].clientHeight;
+ elementWidth = el[0].clientWidth;
position.left = event.pageX - (elementWidth / 2);
position.top = event.pageY;
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfileupload.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfileupload.directive.js
index 6d53b20427..f93e41d0c7 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfileupload.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/upload/umbfileupload.directive.js
@@ -12,7 +12,7 @@ function umbFileUpload() {
restrict: "A",
scope: true, //create a new scope
link: function (scope, el, attrs) {
- el.bind('change', function (event) {
+ el.on('change', function (event) {
var files = event.target.files;
//emit event upward
scope.$emit("filesSelected", { files: files });
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/util/umbkeyboardlist.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/util/umbkeyboardlist.directive.js
index 1800d059c6..20572fdf16 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/util/umbkeyboardlist.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/util/umbkeyboardlist.directive.js
@@ -87,7 +87,7 @@ angular.module('umbraco.directives')
if (focusSet) {
currentIndex++;
}
- listItems[currentIndex].focus();
+ listItems[currentIndex].trigger("focus");
focusSet = true;
}
}
@@ -95,7 +95,7 @@ angular.module('umbraco.directives')
function arrowUp() {
if (currentIndex > 0) {
currentIndex--;
- listItems[currentIndex].focus();
+ listItems[currentIndex].trigger("focus");
}
}
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/showvalidationonsubmit.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/showvalidationonsubmit.directive.js
index 3dc48573c7..78dd00e64b 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/showvalidationonsubmit.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/showvalidationonsubmit.directive.js
@@ -32,7 +32,7 @@
}));
//no isolate scope to listen to element destroy
- element.bind('$destroy', function () {
+ element.on('$destroy', function () {
for (var u in unsubscribe) {
unsubscribe[u]();
}
diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtriggerchange.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtriggerchange.directive.js
index 4ca7e439a3..3408a8fbaa 100644
--- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtriggerchange.directive.js
+++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtriggerchange.directive.js
@@ -2,7 +2,7 @@ angular.module('umbraco.directives.validation')
.directive('valTriggerChange', function($sniffer) {
return {
link : function(scope, elem, attrs) {
- elem.bind('click', function(){
+ elem.on('click', function(){
$(attrs.valTriggerChange).trigger($sniffer.hasEvent('input') ? 'input' : 'change');
});
},
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/assets.service.js b/src/Umbraco.Web.UI.Client/src/common/services/assets.service.js
index e7f40f4814..27e055a7d3 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/assets.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/assets.service.js
@@ -96,7 +96,7 @@ angular.module('umbraco.services')
function loadLocales(locales, supportedLocales) {
var localeUrls = getMomentLocales(locales, supportedLocales);
if (localeUrls.length >= 1) {
- return assetsService.load(localeUrls, $rootScope);
+ return service.load(localeUrls, $rootScope);
}
else {
$q.when(true);
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js
index 0ecfa375d4..23f3fb6d58 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js
@@ -45,8 +45,6 @@ function navigationService($routeParams, $location, $q, $timeout, $injector, eve
appState.setMenuState("showMenuDialog", false);
appState.setGlobalState("stickyNavigation", false);
appState.setGlobalState("showTray", false);
-
- //$("#search-form input").focus();
break;
case 'menu':
appState.setGlobalState("navMode", "menu");
@@ -69,12 +67,6 @@ function navigationService($routeParams, $location, $q, $timeout, $injector, eve
appState.setMenuState("showMenu", false);
appState.setSectionState("showSearchResults", true);
appState.setMenuState("showMenuDialog", false);
-
- //TODO: This would be much better off in the search field controller listening to appState changes
- $timeout(function() {
- $("#search-field").focus();
- });
-
break;
default:
appState.setGlobalState("navMode", "default");
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/windowresizelistener.service.js b/src/Umbraco.Web.UI.Client/src/common/services/windowresizelistener.service.js
index 3b86510173..68691b8629 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/windowresizelistener.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/windowresizelistener.service.js
@@ -31,7 +31,7 @@ function windowResizeListener($rootScope) {
register: function (fn) {
registered.push(fn);
if (inited === false) {
- $(window).bind('resize', resize);
+ $(window).on('resize', resize);
inited = true;
}
},
diff --git a/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js
index 6f3f0bff52..30a7e2ac7d 100644
--- a/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js
@@ -13,7 +13,7 @@ function MainController($scope, $location, appState, treeService, notificationsS
//the null is important because we do an explicit bool check on this in the view
$scope.authenticated = null;
$scope.touchDevice = appState.getGlobalState("touchDevice");
- $scope.editors = [];
+ $scope.infiniteMode = false;
$scope.overlay = {};
$scope.drawer = {};
$scope.search = {};
@@ -160,12 +160,12 @@ function MainController($scope, $location, appState, treeService, notificationsS
}));
// event for infinite editors
- evts.push(eventsService.on("appState.editors.add", function (name, args) {
- $scope.editors = args.editors;
+ evts.push(eventsService.on("appState.editors.open", function (name, args) {
+ $scope.infiniteMode = args && args.editors.length > 0 ? true : false;
}));
- evts.push(eventsService.on("appState.editors.remove", function (name, args) {
- $scope.editors = args.editors;
+ evts.push(eventsService.on("appState.editors.close", function (name, args) {
+ $scope.infiniteMode = args && args.editors.length > 0 ? true : false;
}));
//ensure to unregister from all events!
diff --git a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js
index 8c521ca35e..06b82d6eab 100644
--- a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js
@@ -241,6 +241,15 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar
init();
}));
+ // event for infinite editors
+ evts.push(eventsService.on("appState.editors.open", function (name, args) {
+ $scope.infiniteMode = args && args.editors.length > 0 ? true : false;
+ }));
+
+ evts.push(eventsService.on("appState.editors.close", function (name, args) {
+ $scope.infiniteMode = args && args.editors.length > 0 ? true : false;
+ }));
+
/**
* Based on the current state of the application, this configures the scope variables that control the main tree and language drop down
*/
diff --git a/src/Umbraco.Web.UI.Client/src/less/belle.less b/src/Umbraco.Web.UI.Client/src/less/belle.less
index 5218a9b59c..3f39c5c13f 100644
--- a/src/Umbraco.Web.UI.Client/src/less/belle.less
+++ b/src/Umbraco.Web.UI.Client/src/less/belle.less
@@ -152,6 +152,7 @@
@import "components/umb-number-badge.less";
@import "components/umb-progress-circle.less";
@import "components/umb-stylesheet.less";
+@import "components/umb-range-slider.less";
@import "components/buttons/umb-button.less";
@import "components/buttons/umb-button-group.less";
@@ -176,6 +177,7 @@
@import "utilities/theme/_opacity.less";
@import "utilities/typography/_text-decoration.less";
@import "utilities/typography/_white-space.less";
+@import "utilities/typography/_word-break.less";
@import "utilities/_flexbox.less";
@import "utilities/_spacing.less";
@import "utilities/_text-align.less";
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-button.less b/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-button.less
index d3f2fee5d5..7c45801f43 100644
--- a/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-button.less
+++ b/src/Umbraco.Web.UI.Client/src/less/components/buttons/umb-button.less
@@ -29,6 +29,11 @@
opacity: 0;
}
+.umb-button .umb-button__caret {
+ margin-top: 0;
+ margin-left: 5px;
+}
+
.umb-button__progress {
position: absolute;
left: 50%;
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-querybuilder.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-querybuilder.less
index 8ead992625..151415f0db 100644
--- a/src/Umbraco.Web.UI.Client/src/less/components/umb-querybuilder.less
+++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-querybuilder.less
@@ -39,4 +39,8 @@
.umb-querybuilder .query-items > * {
flex: 0 1 auto;
margin: 5px;
-}
\ No newline at end of file
+}
+
+.umb-querybuilder .query-items .btn {
+ min-height: 2rem;
+}
diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-range-slider.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-range-slider.less
new file mode 100644
index 0000000000..1c21c5a148
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-range-slider.less
@@ -0,0 +1,39 @@
+
+
+.umb-range-slider.noUi-target {
+ background: linear-gradient(to bottom, #f5f5f5 0%, #f9f9f9 100%);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+ border-radius: 20px;
+ height: 10px;
+ border: none;
+}
+
+.umb-range-slider .noUi-handle {
+ border-radius: 100px;
+ border: none;
+ box-shadow: none;
+ width: 20px !important;
+ height: 20px !important;
+ background-color: @turquoise;
+}
+
+.umb-range-slider .noUi-handle::before {
+ display: none;
+}
+
+.umb-range-slider .noUi-handle::after {
+ display: none;
+}
+
+.umb-range-slider .noUi-handle {
+ right: -10px !important; // half the handle width
+}
+
+.umb-range-slider .noUi-marker-large.noUi-marker-horizontal {
+ height: 10px;
+}
+
+.umb-range-slider .noUi-marker.noUi-marker-horizontal {
+ width: 1px;
+}
+
diff --git a/src/Umbraco.Web.UI.Client/src/less/utilities/typography/_word-break.less b/src/Umbraco.Web.UI.Client/src/less/utilities/typography/_word-break.less
new file mode 100644
index 0000000000..e9e8017330
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/less/utilities/typography/_word-break.less
@@ -0,0 +1,7 @@
+/*
+ WORD BREAK
+*/
+
+.word-normal { word-break: normal; }
+.word-wrap { word-break: break-all; }
+.word-nowrap { word-break: keep-all; }
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dashboard.html b/src/Umbraco.Web.UI.Client/src/views/common/dashboard.html
index 4cc5eba4a0..6453963670 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/dashboard.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/dashboard.html
@@ -18,18 +18,13 @@
- {{model.result.queryExpression}}
-
+ {{model.result.queryExpression}}
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js
index 6b8462b583..e179e0acb3 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.controller.js
@@ -123,11 +123,14 @@
oldProperty.isObject = true;
}
- // create new property object used in the diff table
+ // diff requires a string
+ property.value = property.value ? property.value : "";
+ oldProperty.value = oldProperty.value ? oldProperty.value : "";
+
var diffProperty = {
"alias": property.alias,
"label": property.label,
- "diff": (property.value || oldProperty.value) ? JsDiff.diffWords(property.value, oldProperty.value) : "",
+ "diff": JsDiff.diffWords(property.value, oldProperty.value),
"isObject": (property.isObject || oldProperty.isObject) ? true : false
};
diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html
index f7ab78b7a0..b5b925b266 100644
--- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html
+++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/rollback/rollback.html
@@ -63,7 +63,7 @@
Could not load control: '" + path +
- "'.
Error message: " +
- ee.ToString() + "