diff --git a/src/Umbraco.Web.UI/umbraco/Views/content/edit.html b/src/Umbraco.Web.UI/umbraco/Views/content/edit.html
new file mode 100644
index 0000000000..a6899fa675
--- /dev/null
+++ b/src/Umbraco.Web.UI/umbraco/Views/content/edit.html
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Umbraco.Web.UI/umbraco/Views/directives/umb-header.html b/src/Umbraco.Web.UI/umbraco/Views/directives/umb-header.html
new file mode 100644
index 0000000000..799cf2312b
--- /dev/null
+++ b/src/Umbraco.Web.UI/umbraco/Views/directives/umb-header.html
@@ -0,0 +1,13 @@
+
\ No newline at end of file
diff --git a/src/Umbraco.Web.UI/umbraco/js/umbraco.controllers.js b/src/Umbraco.Web.UI/umbraco/js/umbraco.controllers.js
index 3b3bc93521..fbee16c84f 100644
--- a/src/Umbraco.Web.UI/umbraco/js/umbraco.controllers.js
+++ b/src/Umbraco.Web.UI/umbraco/js/umbraco.controllers.js
@@ -165,13 +165,16 @@ angular.module('umbraco').controller("Umbraco.Editors.ContentCreateController",
return;
});
});
-angular.module("umbraco").controller("Umbraco.Editors.ContentEditController", function ($scope, $routeParams, contentResource, notifications) {
+angular.module("umbraco").controller("Umbraco.Editors.ContentEditController", function ($scope, $routeParams, contentResource, notifications, $q) {
if($routeParams.create)
- $scope.content = contentResource.getContentScaffold($routeParams.parentId, $routeParams.doctype);
- else
- $scope.content = contentResource.getContent($routeParams.id);
-
+ $scope.content = contentResource.getContentScaffold($routeParams.parentId, $routeParams.doctype);
+ else {
+ $q.when(contentResource.getContent($routeParams.id))
+ .then(function (data) {
+ $scope.content = data;
+ });
+ }
$scope.saveAndPublish = function (cnt) {
cnt.publishDate = new Date();
diff --git a/src/Umbraco.Web.UI/umbraco/js/umbraco.directives.js b/src/Umbraco.Web.UI/umbraco/js/umbraco.directives.js
index cda7d4e49c..1a14405226 100644
--- a/src/Umbraco.Web.UI/umbraco/js/umbraco.directives.js
+++ b/src/Umbraco.Web.UI/umbraco/js/umbraco.directives.js
@@ -4,7 +4,7 @@
* Licensed MIT
*/
'use strict';
-define(['app', 'angular'], function (app, angular) {
+define(['app', 'angular', 'underscore'], function (app, angular, _) {
/**
* @ngdoc directive
@@ -231,41 +231,52 @@ angular.module('umbraco.directives', [])
replace: true,
transclude: 'true',
templateUrl: 'views/directives/umb-header.html',
+ //create a new isolated scope assigning a tabs property from the attribute 'tabs'
+ //which is bound to the parent scope property passed in
+ scope: {
+ tabs: "="
+ },
+ link: function (scope, iElement, iAttrs) {
- compile: function compile(tElement, tAttrs, transclude) {
- return function postLink(scope, iElement, iAttrs, controller) {
+ if (!iAttrs.tabs)
+ throw "a 'tabs' attribute must be set for umbHeader which represents the collection of tabs";
- scope.panes = [];
- var $panes = $('div.tab-content');
+ var hasProcessed = false;
- var activeTab = 0, _id, _title, _active;
- $timeout(function() {
+ //when the tabs change, we need to hack the planet a bit and force the first tab content to be active,
+ //unfortunately twitter bootstrap tabs is not playing perfectly with angular.
+ scope.$watch("tabs", function (newValue, oldValue) {
- $panes.find('.tab-pane').each(function(index) {
- var $this = angular.element(this);
- var _scope = $this.scope();
+ //don't process if we cannot or have already done so
+ if (!newValue) return;
+ if (hasProcessed || !newValue.length || newValue.length == 0) return;
+
+ //set the flag
+ hasProcessed = true;
- _id = $this.attr("id");
- _title = $this.attr('title');
- _active = !_active && $this.hasClass('active');
+ var $panes = $('div.tab-content');
+ var activeTab = _.find(newValue, function (item) {
+ return item.active;
+ });
+ //we need to do a timeout here so that the current sync operation can complete
+ // and update the UI, then this will fire and the UI elements will be available.
+ $timeout(function () {
+ $panes.find('.tab-pane').each(function (index) {
+ var $this = angular.element(this);
+ var _scope = $this.scope();
+ if (_scope.id == activeTab.id) {
+ $this.addClass('active' + (iAttrs.fade ? ' in' : ''));
+ }
+ else {
+ $this.removeClass('active');
+ }
- if(iAttrs.fade){$this.addClass('fade');}
-
- scope.panes.push({
- id: _id,
- title: _title,
- active: _active
- });
+ if (iAttrs.fade) { $this.addClass('fade'); }
});
-
- if(scope.panes.length && !_active) {
- $panes.find('.tab-pane:first-child').addClass('active' + (iAttrs.fade ? ' in' : ''));
- scope.panes[0].active = true;
- }
-
- }); //end timeout
- }; //end postlink
+ });
+
+ });
}
};
})
@@ -284,13 +295,18 @@ angular.module('umbraco.directives', [])
restrict: 'E',
replace: true,
transclude: 'true',
-
+ //assign isolated scope from the attributes
+ //NOTE: we use @rel because angular has a bug where
+ // it cannot assign based on hyphenated attributes like
+ // data-tab-id (which should be dataTabId but it doesn't work)
scope: {
- title: '@',
- id: '@'
+ label: '@title',
+ id: '@rel'
},
-
- templateUrl: 'views/directives/umb-tab.html'
+ templateUrl: 'views/directives/umb-tab.html',
+ link: function (scope, element, attrs) {
+ scope.elementId = "tab" + scope.id;
+ }
};
})
@@ -298,9 +314,9 @@ angular.module('umbraco.directives', [])
.directive('umbProperty', function(){
return {
+ scope: true,
restrict: 'E',
- replace: true,
- transclude: 'true',
+ replace: true,
templateUrl: 'views/directives/umb-property.html',
link: function (scope, element, attrs) {
//let's make a requireJs call to try and retrieve the associated js
diff --git a/src/Umbraco.Web.UI/umbraco/js/umbraco.filters.js b/src/Umbraco.Web.UI/umbraco/js/umbraco.filters.js
index 75bcd48c9c..1fc18f3740 100644
--- a/src/Umbraco.Web.UI/umbraco/js/umbraco.filters.js
+++ b/src/Umbraco.Web.UI/umbraco/js/umbraco.filters.js
@@ -53,7 +53,7 @@ define(['app', 'angular'], function (app, angular) {
//if its not defined then return undefined
if (!input) return input;
- $log.info("Filtering property editor view: " + input);
+ //$log.info("Filtering property editor view: " + input);
var path = String(input);
if (path.startsWith('/')) {
diff --git a/src/Umbraco.Web.UI/umbraco/js/umbraco.resources.js b/src/Umbraco.Web.UI/umbraco/js/umbraco.resources.js
index 57b41e7f2a..a9afa5dd81 100644
--- a/src/Umbraco.Web.UI/umbraco/js/umbraco.resources.js
+++ b/src/Umbraco.Web.UI/umbraco/js/umbraco.resources.js
@@ -131,7 +131,7 @@ define(['app', 'angular'], function (app, angular) {
* @name umbraco.resources.contentResource
* @description Loads in data for content
**/
- function contentTypeResource($q, $http) {
+ function contentResource($q, $http) {
/** internal method to get the api url */
function getContentUrl(contentId) {
@@ -143,9 +143,16 @@ define(['app', 'angular'], function (app, angular) {
var deferred = $q.defer();
- //go and get the tree data
+ //go and get the data
$http.get(getContentUrl(id)).
success(function (data, status, headers, config) {
+ //set the first tab to active
+ _.each(data.tabs, function (item) {
+ item.active = false;
+ });
+ if (data.tabs.length > 0)
+ data.tabs[0].active = true;
+
deferred.resolve(data);
}).
error(function (data, status, headers, config) {
@@ -275,7 +282,7 @@ define(['app', 'angular'], function (app, angular) {
};
}
- angular.module('umbraco.resources.content', []).factory('contentResource', contentTypeResource);
+ angular.module('umbraco.resources.content', []).factory('contentResource', contentResource);
// angular.module('umbraco.resources.content', [])
//.factory('contentFactory', function () {
diff --git a/src/Umbraco.Web/Models/ContentEditing/Tab.cs b/src/Umbraco.Web/Models/ContentEditing/Tab.cs
index 5f3d7bb6f2..899f81230a 100644
--- a/src/Umbraco.Web/Models/ContentEditing/Tab.cs
+++ b/src/Umbraco.Web/Models/ContentEditing/Tab.cs
@@ -9,6 +9,9 @@ namespace Umbraco.Web.Models.ContentEditing
[DataContract(Name = "tab", Namespace = "")]
public class Tab
{
+ [DataMember(Name = "id")]
+ public int Id { get; set; }
+
[DataMember(Name = "label")]
public string Label { get; set; }
diff --git a/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs
index 42e39cf375..8ee9512d63 100644
--- a/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs
+++ b/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs
@@ -49,6 +49,7 @@ namespace Umbraco.Web.Models.Mapping
//return the tab with the tab properties
return new Tab
{
+ Id = propertyGroup.Id,
Alias = propertyGroup.Name,
Label = propertyGroup.Name,
Properties = displayProperties
@@ -61,6 +62,7 @@ namespace Umbraco.Web.Models.Mapping
//now add the generic properties tab
tabs.Add(new Tab
{
+ Id = 0,
Label = "Generic properties",
Alias = "Generic properties",
Properties = orphanProperties.Select(ToContentPropertyDisplay)