diff --git a/LICENSE.md b/LICENSE.md
index 6271e30..6cef29c 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,3 +1,5 @@
+The MIT License (MIT)
+
Copyright © 2014 Umbrella Inc, Our Umbraco and other contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/README.md b/README.md
index b2a3050..5cadb88 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Nested Content
-[![Build status](https://img.shields.io/appveyor/ci/leekelleher/umbraco-nested-content.svg)](https://ci.appveyor.com/project/leekelleher/umbraco-nested-content)
+[![Build status](https://img.shields.io/appveyor/ci/UMCO/umbraco-nested-content.svg)](https://ci.appveyor.com/project/UMCO/umbraco-nested-content)
[![NuGet release](https://img.shields.io/nuget/v/Our.Umbraco.NestedContent.svg)](https://www.nuget.org/packages/Our.Umbraco.NestedContent)
[![Our Umbraco project page](https://img.shields.io/badge/our-umbraco-orange.svg)](https://our.umbraco.org/projects/backoffice-extensions/nested-content)
[![Chat on Gitter](https://img.shields.io/badge/gitter-join_chat-green.svg)](https://gitter.im/leekelleher/umbraco-nested-content)
@@ -21,7 +21,7 @@ Nested Content can be installed from either Our Umbraco or NuGet package reposit
To install from Our Umbraco, please download the package from:
-> [https://our.umbraco.org/projects/backoffice-extensions/nested-content](https://our.umbraco.org/projects/backoffice-extensions/nested-content)
+>
#### NuGet package repository
@@ -39,7 +39,7 @@ If you prefer, you can compile Nested Content yourself, you'll need:
To clone it locally click the "Clone in Windows" button above or run the following git commands.
- git clone https://github.com/leekelleher/umbraco-nested-content.git umbraco-nested-content
+ git clone https://github.com/umco/umbraco-nested-content.git umbraco-nested-content
cd umbraco-nested-content
.\build.cmd
@@ -55,14 +55,16 @@ A PDF download is also available: [Nested Content - Developers Guide v1.0.pdf](d
## Known Issues
-Please be aware that not all property-editors will work within Nested Content. The following property-editors are known to have compatibility issues:
+Please be aware that not all property-editors will work within Nested Content. The following Umbraco core property-editors are known to have compatibility issues:
-* Checkbox List (default Umbraco core)
-* Image Cropper (default Umbraco core)
-* Macro Container (default Umbraco core)
-* Radiobutton List (default Umbraco core)
-* Repeatable Textstring (default Umbraco core) - this works in the back-office, but due to a bug in the value-converter it will produce additional blank entries
-* Upload (default Umbraco core)
+* Checkbox List
+* Dropdown List Multiple
+* Image Cropper
+* Macro Container
+* Radiobutton List
+* Repeatable Textstring - _this works in the back-office, but due to a bug in the value-converter it will produce additional blank entries_
+* Tags - _this appears to work, but by design it is intended to work once per page_
+* Upload
---
@@ -80,7 +82,7 @@ Anyone and everyone is welcome to contribute. Please take a moment to review the
Have a question?
* [Nested Content Forum](https://our.umbraco.org/projects/backoffice-extensions/nested-content/nested-content-feedback) on Our Umbraco
-* [Raise an issue](https://github.com/leekelleher/umbraco-nested-content/issues) on GitHub
+* [Raise an issue](https://github.com/umco/umbraco-nested-content/issues) on GitHub
## Dev Team
@@ -95,6 +97,6 @@ Have a question?
## License
-Copyright © 2015 Umbrella Inc, Our Umbraco and [other contributors](https://github.com/leekelleher/umbraco-nested-content/graphs/contributors)
+Copyright © 2015 Umbrella Inc, Our Umbraco and [other contributors](https://github.com/umco/umbraco-nested-content/graphs/contributors)
Licensed under the [MIT License](LICENSE.md)
diff --git a/appveyor.yml b/appveyor.yml
index 6cfa984..57d07e6 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,5 +1,5 @@
# version format
-version: 0.3.0.{build}
+version: 0.4.0.{build}
# UMBRACO_PACKAGE_PRERELEASE_SUFFIX if a rtm release build this should be blank, otherwise if empty will default to alpha
# example UMBRACO_PACKAGE_PRERELEASE_SUFFIX=beta
@@ -17,22 +17,12 @@ artifacts:
- path: artifacts\*.zip
deploy:
- # MyGet (Nested Content feed) Deployment for builds & releases
- - provider: NuGet
- server: https://www.myget.org/F/umbraco-nested-content/
- symbol_server: https://nuget.symbolsource.org/MyGet/umbraco-nested-content
- api_key:
- secure: Q1/4K8VSwr7BjwmKDTef8y5lOc7S+jK9ELuWy67y6OVRpjxmnF9M3Gfs1kT+ir8x
- artifact: /.*\.nupkg/
- on:
- branch: develop
-
- # MyGet (Umbraco Community feed) Deployment for builds & releases
+ # MyGet Deployment for builds & releases
- provider: NuGet
server: https://www.myget.org/F/umbraco-packages/
symbol_server: https://nuget.symbolsource.org/MyGet/umbraco-packages
api_key:
- secure: Q1/4K8VSwr7BjwmKDTef8y5lOc7S+jK9ELuWy67y6OVRpjxmnF9M3Gfs1kT+ir8x
+ secure: 36/Ax5O+e6wENlhoTwgvoEBZV3FG4XjF429SNTej2qsGTAL+cdfA1kT/tm1St8vx
artifact: /.*\.nupkg/
on:
branch: develop
@@ -40,7 +30,7 @@ deploy:
# GitHub Deployment for releases
- provider: GitHub
auth_token:
- secure: pEozEGTqJutQwOidJU6BTB+Ix0NV4vrUnomhfeqheVz4RNwfxjEYLoqR4XabhlPz
+ secure: yDxrRTveSScJA35MQTOaLYVjoPKFKl2bHBkG+JMZjiN0r7AfuUCxVU3CgW8Imu4h
artifact: /.*\.zip/ # upload all Zip packages to release assets
draft: false
prerelease: false
@@ -52,7 +42,7 @@ deploy:
- provider: NuGet
server:
api_key:
- secure: CGzDKxw4QI/z2VSe9ceiYlIabqGXHolgBgVNWWZjVAJ2V5WLF11IFdlp9r5Qp+Sw
+ secure: eSLiOXbGVrxSG+X7PV6qTTUZ5VzS9EFj5+EufaWPfd+QXkF6gc8rZ4mGoHIVp/fL
artifact: /.*\.nupkg/
on:
branch: master
diff --git a/build/package.proj b/build/package.proj
index e30d6d4..c2de2cc 100644
--- a/build/package.proj
+++ b/build/package.proj
@@ -21,17 +21,17 @@
7.1.4
Nested Content is a list editing property editor for Umbraco 7.1+
Matt Brailsford, Lee Kelleher
- https://github.com/leekelleher/umbraco-nested-content/graphs/contributors
+ https://github.com/umco/umbraco-nested-content/graphs/contributors
MIT license
http://opensource.org/licenses/MIT
- https://github.com/leekelleher/umbraco-nested-content
+ https://github.com/umco/umbraco-nested-content
Our.Umbraco.NestedContent
- Umbraco Nested Content
- Copyright © 2015 Matt Brailsford, Lee Kelleher, Our Umbraco and other contributors
+ Nested Content for Umbraco
+ Copyright © 2015 Umbrella Inc, Our Umbraco and other contributors
Matt Brailsford, Lee Kelleher
https://our.umbraco.org/media/wiki/145710/635623752021571595_ncpng.png
umbraco list editor
diff --git a/docs/developers-guide.md b/docs/developers-guide.md
index 9b4ca94..1b6d4f8 100644
--- a/docs/developers-guide.md
+++ b/docs/developers-guide.md
@@ -46,10 +46,10 @@ The prevalue editor allows you to configure the following properties.
| Member | Type | Description |
|-----------------|---------|-------------|
-| Doc Types | List | Defines a list of doc types to use as data blue prints for this **Nested Content** instance. For each doc type you can provide the alias of the tab you wish to render (first tab is used by default if not set) as well as a template for generating list item labels using the syntax `{{propertyAlias}}`. |
-| Min Items | Int | Sets the minimum number of items that should be allowed in the list. If greater than 0, **Nested Content** will pre-populate your list with the minimum amount of allowed items and prevent deleting items below this level. Defaults to 0.
-| Max Itemd | Int | Sets the maximum number of items that should be allowed in the list. If greater than 0, **Nested Content** will prevent new items being added to the list above this threshold. Defaults to 0. |
-| Confirm Deletes | Boolean | Enabling this will require item deletions to require a confirmation before being deleted. Defaults to TRUE |
+| Doc Types | List | Defines a list of doc types to use as data blue prints for this **Nested Content** instance. For each doc type you can provide the alias of the tab you wish to render (first tab is used by default if not set) as well as a template for generating list item labels using the syntax `{{propertyAlias}}`. If you would like to include the index position in the label, you can use `{{$index}}`. |
+| Min Items | Integer | Sets the minimum number of items that should be allowed in the list. If greater than `0`, **Nested Content** will pre-populate your list with the minimum amount of allowed items and prevent deleting items below this level. Defaults to `0`.
+| Max Items | Integer | Sets the maximum number of items that should be allowed in the list. If greater than `0`, **Nested Content** will prevent new items being added to the list above this threshold. Defaults to `0`. |
+| Confirm Deletes | Boolean | Enabling this will require item deletions to require a confirmation before being deleted. Defaults to `true`. |
| Show Icons | Boolean | Enabling this will display the items doc type icon next to the name in the **Nested Content** list. |
| Hide Label | Boolean | Enabling this will hide the property editors label and expand the **Nested Content** property editor to the full with of the editor window. |
diff --git a/src/Our.Umbraco.NestedContent.sln b/src/Our.Umbraco.NestedContent.sln
index b00a091..013aa2f 100644
--- a/src/Our.Umbraco.NestedContent.sln
+++ b/src/Our.Umbraco.NestedContent.sln
@@ -1,7 +1,6 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.31101.0
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{CEE9961C-D747-40CD-B0B2-868D6B46833E}"
ProjectSection(SolutionItems) = preProject
diff --git a/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs b/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs
index 853781c..da536da 100644
--- a/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs
+++ b/src/Our.Umbraco.NestedContent/Converters/NestedContentValueConverter.cs
@@ -21,7 +21,7 @@ public override object ConvertDataToSource(PublishedPropertyType propertyType, o
{
try
{
- return propertyType.ConvertPropertyToNestedContent(source);
+ return propertyType.ConvertPropertyToNestedContent(source, preview);
}
catch (Exception e)
{
diff --git a/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs b/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs
index 7dd66ee..9da1bd8 100644
--- a/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs
+++ b/src/Our.Umbraco.NestedContent/Converters/SingleNestedContentValueConverter.cs
@@ -20,7 +20,7 @@ public override object ConvertDataToSource(PublishedPropertyType propertyType, o
{
try
{
- return propertyType.ConvertPropertyToNestedContent(source);
+ return propertyType.ConvertPropertyToNestedContent(source, preview);
}
catch (Exception e)
{
diff --git a/src/Our.Umbraco.NestedContent/Extensions/PublishedPropertyTypeExtensions.cs b/src/Our.Umbraco.NestedContent/Extensions/PublishedPropertyTypeExtensions.cs
index 88694dd..3315eb0 100644
--- a/src/Our.Umbraco.NestedContent/Extensions/PublishedPropertyTypeExtensions.cs
+++ b/src/Our.Umbraco.NestedContent/Extensions/PublishedPropertyTypeExtensions.cs
@@ -36,7 +36,7 @@ public static bool IsSingleNestedContentProperty(this PublishedPropertyType publ
int.TryParse(preValueDictionary["maxItems"], out maxItems) && maxItems == 1;
}
- public static object ConvertPropertyToNestedContent(this PublishedPropertyType propertyType, object source)
+ public static object ConvertPropertyToNestedContent(this PublishedPropertyType propertyType, object source, bool preview)
{
using (DisposableTimer.DebugDuration(string.Format("ConvertPropertyToNestedContent ({0})", propertyType.DataTypeId)))
{
@@ -78,7 +78,7 @@ public static object ConvertPropertyToNestedContent(this PublishedPropertyType p
var propType = publishedContentType.GetPropertyType(jProp.Key);
if (propType != null)
{
- properties.Add(new DetachedPublishedProperty(propType, jProp.Value));
+ properties.Add(new DetachedPublishedProperty(propType, jProp.Value, preview));
}
}
@@ -98,7 +98,8 @@ public static object ConvertPropertyToNestedContent(this PublishedPropertyType p
publishedContentType,
properties.ToArray(),
containerNode,
- i));
+ i,
+ preview));
}
if (propertyType.IsSingleNestedContentProperty())
diff --git a/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj b/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj
index 1f75b5e..3006c60 100644
--- a/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj
+++ b/src/Our.Umbraco.NestedContent/Our.Umbraco.NestedContent.csproj
@@ -243,6 +243,7 @@
+
diff --git a/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs b/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs
index e1d33fa..160a380 100644
--- a/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs
+++ b/src/Our.Umbraco.NestedContent/PropertyEditors/NestedContentPropertyEditor.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text.RegularExpressions;
@@ -46,7 +47,7 @@ public NestedContentPropertyEditor()
protected override PreValueEditor CreatePreValueEditor()
{
- return new NestedContentPreValueEditor();
+ return new NestedContentPreValueEditor();
}
internal class NestedContentPreValueEditor : PreValueEditor
@@ -160,15 +161,26 @@ public override string ConvertDbToString(Property property, PropertyType propert
}
else
{
- // Create a fake property using the property abd stored value
- var prop = new Property(propType, propValues[propKey] == null ? null : propValues[propKey].ToString());
+ try
+ {
+ // Create a fake property using the property abd stored value
+ var prop = new Property(propType, propValues[propKey] == null ? null : propValues[propKey].ToString());
- // Lookup the property editor
- var propEditor = PropertyEditorResolver.Current.GetByAlias(propType.PropertyEditorAlias);
+ // Lookup the property editor
+ var propEditor = PropertyEditorResolver.Current.GetByAlias(propType.PropertyEditorAlias);
- // Get the editor to do it's conversion, and store it back
- propValues[propKey] = propEditor.ValueEditor.ConvertDbToString(prop, propType,
- ApplicationContext.Current.Services.DataTypeService);
+ // Get the editor to do it's conversion, and store it back
+ propValues[propKey] = propEditor.ValueEditor.ConvertDbToString(prop, propType,
+ ApplicationContext.Current.Services.DataTypeService);
+ }
+ catch (InvalidOperationException)
+ {
+ // https://github.com/umco/umbraco-nested-content/issues/111
+ // Catch any invalid cast operations as likely means courier failed due to missing
+ // or trashed item so couldn't convert a guid back to an int
+
+ propValues[propKey] = null;
+ }
}
}
@@ -225,18 +237,29 @@ public override object ConvertDbToEditor(Property property, PropertyType propert
}
else
{
- // Create a fake property using the property abd stored value
- var prop = new Property(propType, propValues[propKey] == null ? null : propValues[propKey].ToString());
+ try
+ {
+ // Create a fake property using the property abd stored value
+ var prop = new Property(propType, propValues[propKey] == null ? null : propValues[propKey].ToString());
- // Lookup the property editor
- var propEditor = PropertyEditorResolver.Current.GetByAlias(propType.PropertyEditorAlias);
+ // Lookup the property editor
+ var propEditor = PropertyEditorResolver.Current.GetByAlias(propType.PropertyEditorAlias);
- // Get the editor to do it's conversion
- var newValue = propEditor.ValueEditor.ConvertDbToEditor(prop, propType,
- ApplicationContext.Current.Services.DataTypeService);
+ // Get the editor to do it's conversion
+ var newValue = propEditor.ValueEditor.ConvertDbToEditor(prop, propType,
+ ApplicationContext.Current.Services.DataTypeService);
- // Store the value back
- propValues[propKey] = (newValue == null) ? null : JToken.FromObject(newValue);
+ // Store the value back
+ propValues[propKey] = (newValue == null) ? null : JToken.FromObject(newValue);
+ }
+ catch (InvalidOperationException)
+ {
+ // https://github.com/umco/umbraco-nested-content/issues/111
+ // Catch any invalid cast operations as likely means courier failed due to missing
+ // or trashed item so couldn't convert a guid back to an int
+
+ propValues[propKey] = null;
+ }
}
}
diff --git a/src/Our.Umbraco.NestedContent/Web/Controllers/NestedContentApiController.cs b/src/Our.Umbraco.NestedContent/Web/Controllers/NestedContentApiController.cs
index dc7f109..3c234c6 100644
--- a/src/Our.Umbraco.NestedContent/Web/Controllers/NestedContentApiController.cs
+++ b/src/Our.Umbraco.NestedContent/Web/Controllers/NestedContentApiController.cs
@@ -1,10 +1,7 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
-using Our.Umbraco.NestedContent.Extensions;
using Umbraco.Web.Editors;
using Umbraco.Web.Mvc;
-using System.Web.Http.ModelBinding;
namespace Our.Umbraco.NestedContent.Web.Controllers
{
diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js
index c5dad75..05a07b1 100644
--- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js
+++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.controllers.js
@@ -5,19 +5,19 @@
function ($scope, ncResources) {
- $scope.add = function() {
+ $scope.add = function () {
$scope.model.value.push({
- // As per PR #4, all stored content type aliases must be prefixed "nc" for easier recognition.
- // For good measure we'll also prefix the tab alias "nc"
- ncAlias: "",
- ncTabAlias: "",
- nameTemplate: ""
- }
+ // As per PR #4, all stored content type aliases must be prefixed "nc" for easier recognition.
+ // For good measure we'll also prefix the tab alias "nc"
+ ncAlias: "",
+ ncTabAlias: "",
+ nameTemplate: ""
+ }
);
}
- $scope.selectedDocTypeTabs = function(cfg) {
- var dt = _.find($scope.model.docTypes, function(itm) {
+ $scope.selectedDocTypeTabs = function (cfg) {
+ var dt = _.find($scope.model.docTypes, function (itm) {
return itm.alias.toLowerCase() == cfg.ncAlias.toLowerCase();
});
var tabs = dt ? dt.tabs : [];
@@ -53,11 +53,12 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest
"$scope",
"$interpolate",
"$filter",
+ "$timeout",
"contentResource",
"localizationService",
"Our.Umbraco.NestedContent.Resources.NestedContentResources",
- function ($scope, $interpolate, $filter, contentResource, localizationService, ncResources) {
+ function ($scope, $interpolate, $filter, $timeout, contentResource, localizationService, ncResources) {
//$scope.model.config.contentTypes;
//$scope.model.config.minItems;
@@ -152,17 +153,24 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest
return;
}
- // calculate overlay position
- // - yeah... it's jQuery (ungh!) but that's how the Grid does it.
- var offset = $(event.target).offset();
- var scrollTop = $(event.target).closest(".umb-panel-body").scrollTop();
- if (offset.top < 400) {
- $scope.overlayMenu.style.top = 300 + scrollTop;
- }
- else {
- $scope.overlayMenu.style.top = offset.top - 150 + scrollTop;
- }
+ // Position off screen till we are visible and can calculate offset
+ $scope.overlayMenu.style.top = -1000;
+ $scope.overlayMenu.style.left = -1000;
+
$scope.overlayMenu.show = true;
+
+ $timeout(function () {
+
+ var wrapper = $("#contentwrapper");
+ var el = $("#nested-content--" + $scope.model.id + " .nested-content__node-type-picker .cell-tools-menu");
+
+ var offset = el.offsetRelative("#contentwrapper");
+
+ $scope.overlayMenu.style.top = (Math.round(wrapper.height() / 2) + offset.top) - Math.round(el.height() / 2);
+ $scope.overlayMenu.style.left = (Math.round(wrapper.width() / 2) + offset.left) - Math.round(el.width() / 2);
+
+ });
+
};
$scope.closeNodeTypePicker = function () {
@@ -200,10 +208,19 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest
var contentType = $scope.getContentTypeConfig($scope.model.value[idx].ncContentTypeAlias);
if (contentType != null && contentType.nameExp) {
- var newName = contentType.nameExp($scope.model.value[idx]); // Run it against the stored dictionary value, NOT the node object
+ // Run the expression against the stored dictionary value, NOT the node object
+ var item = $scope.model.value[idx];
+
+ // Add a temporary index property
+ item['$index'] = (idx + 1);
+
+ var newName = contentType.nameExp(item);
if (newName && (newName = $.trim(newName))) {
name = newName;
}
+
+ // Delete the index property as we don't want to persist it
+ delete item['$index'];
}
}
@@ -264,9 +281,9 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest
var scaffoldsLoaded = 0;
$scope.scaffolds = [];
_.each($scope.model.config.contentTypes, function (contentType) {
- contentResource.getScaffold(-20, contentType.ncAlias).then(function(scaffold) {
+ contentResource.getScaffold(-20, contentType.ncAlias).then(function (scaffold) {
// remove all tabs except the specified tab
- var tab = _.find(scaffold.tabs, function(tab) {
+ var tab = _.find(scaffold.tabs, function (tab) {
return tab.id != 0 && (tab.alias.toLowerCase() == contentType.ncTabAlias.toLowerCase() || contentType.ncTabAlias == "");
});
scaffold.tabs = [];
@@ -279,19 +296,19 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest
scaffoldsLoaded++;
initIfAllScaffoldsHaveLoaded();
- }, function(error) {
+ }, function (error) {
scaffoldsLoaded++;
initIfAllScaffoldsHaveLoaded();
});
});
- var initIfAllScaffoldsHaveLoaded = function() {
+ var initIfAllScaffoldsHaveLoaded = function () {
// Initialize when all scaffolds have loaded
if ($scope.model.config.contentTypes.length == scaffoldsLoaded) {
// Because we're loading the scaffolds async one at a time, we need to
// sort them explicitly according to the sort order defined by the data type.
var contentTypeAliases = [];
- _.each($scope.model.config.contentTypes, function(contentType) {
+ _.each($scope.model.config.contentTypes, function (contentType) {
contentTypeAliases.push(contentType.ncAlias);
});
$scope.scaffolds = $filter('orderBy')($scope.scaffolds, function (s) {
@@ -319,7 +336,7 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest
}
// If there is only one item, set it as current node
- if ($scope.singleMode) {
+ if ($scope.singleMode || ($scope.nodes.length == 1 && $scope.maxItems == 1)) {
$scope.currentNode = $scope.nodes[0];
}
@@ -408,4 +425,48 @@ angular.module("umbraco").controller("Our.Umbraco.NestedContent.Controllers.Nest
};
}
-]);
\ No newline at end of file
+]);
+
+// offsetRelative (or, if you prefer, positionRelative)
+(function ($) {
+
+ $.fn.offsetRelative = function (ancestor) {
+ var positionedAncestor = $(ancestor);
+ var object = $(this);
+
+ var relativeOffset = { left: 0, top: 0 };
+
+ var leftSpacing = parseInt(object.css("margin-left"));
+ leftSpacing += parseInt(object.css("border-left-width"));
+
+ var topSpacing = parseInt(object.css("margin-top"));
+ topSpacing += parseInt(object.css("border-top-width"));
+
+ relativeOffset.left -= leftSpacing;
+ relativeOffset.top -= topSpacing;
+
+ var offsetParent = object.offsetParent();
+
+ while (offsetParent[0] !== positionedAncestor[0] && !offsetParent.is('html')) {
+ var offsetParentPosition = offsetParent.position();
+
+ var offsetParentPositionLeft = offsetParentPosition.left;
+ var offsetParentPositionTop = offsetParentPosition.top;
+
+ relativeOffset.top -= offsetParentPositionTop;
+ relativeOffset.left -= offsetParentPositionLeft;
+
+ leftSpacing = parseInt(offsetParent.css("margin-left"));
+ leftSpacing += parseInt(offsetParent.css("border-left-width"));
+ topSpacing = parseInt(offsetParent.css("margin-top"));
+ topSpacing += parseInt(offsetParent.css("border-top-width"));
+
+ relativeOffset.left -= leftSpacing;
+ relativeOffset.top -= topSpacing;
+
+ offsetParent = offsetParent.offsetParent();
+ }
+ return relativeOffset;
+ };
+
+}(jQuery));
\ No newline at end of file
diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js
index e70d238..01e3794 100644
--- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js
+++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.directives.js
@@ -2,25 +2,53 @@
function () {
- var link = function ($scope, element, attrs, ctrl) {
- $scope.nodeContext = $scope.model = $scope.ngModel;
+ var link = function ($scope) {
- var tab = $scope.ngModel.tabs[0];
+ // Clone the model because some property editors
+ // do weird things like updating and config values
+ // so we want to ensure we start from a fresh every
+ // time, we'll just sync the value back when we need to
+ $scope.model = angular.copy($scope.ngModel);
+ $scope.nodeContext = $scope.model;
+
+ // Find the selected tab
+ var selectedTab = $scope.model.tabs[0];
if ($scope.tabAlias) {
- angular.forEach($scope.ngModel.tabs, function (value, key) {
- if (value.alias.toLowerCase() == $scope.tabAlias.toLowerCase()) {
- tab = value;
+ angular.forEach($scope.model.tabs, function (tab) {
+ if (tab.alias.toLowerCase() == $scope.tabAlias.toLowerCase()) {
+ selectedTab = tab;
return;
}
});
}
- $scope.tab = tab;
+ $scope.tab = selectedTab;
+ // Listen for sync request
var unsubscribe = $scope.$on("ncSyncVal", function (ev, args) {
if (args.id === $scope.model.id) {
+
+ // Tell inner controls we are submitting
$scope.$broadcast("formSubmitting", { scope: $scope });
+
+ // Sync the values back
+ angular.forEach($scope.ngModel.tabs, function (tab) {
+ if (tab.alias.toLowerCase() == selectedTab.alias.toLowerCase()) {
+
+ var localPropsMap = selectedTab.properties.reduce(function (map, obj) {
+ map[obj.alias] = obj;
+ return map;
+ }, {});
+
+ angular.forEach(tab.properties, function (prop) {
+ if (localPropsMap.hasOwnProperty(prop.alias)) {
+ prop.value = localPropsMap[prop.alias].value;
+ }
+ });
+
+ }
+ });
}
});
@@ -32,7 +60,7 @@
return {
restrict: "E",
replace: true,
- templateUrl: "/App_Plugins/NestedContent/Views/nestedcontent.editor.html",
+ templateUrl: Umbraco.Sys.ServerVariables.umbracoSettings.appPluginsPath + "/NestedContent/Views/nestedcontent.editor.html",
scope: {
ngModel: '=',
tabAlias: '='
@@ -54,7 +82,7 @@
// }
// });
// }
-
+
// return {
// restrict: "E",
// replace: true,
diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.filters.js b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.filters.js
new file mode 100644
index 0000000..cecd1fa
--- /dev/null
+++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.filters.js
@@ -0,0 +1,46 @@
+// Filter to take a node id and grab it's name instead
+// Usage: {{ pickerAlias | ncNodeName }}
+
+// Cache for node names so we don't make a ton of requests
+var ncNodeNameCache = {
+ id: "",
+ keys: {}
+}
+
+angular.module("umbraco.filters").filter("ncNodeName", function (editorState, entityResource) {
+
+ return function (input) {
+
+ // Check we have a value at all
+ if (input == "" || input.toString() == "0")
+ return "";
+
+ var currentNode = editorState.getCurrent();
+
+ // Ensure a unique cache per editor instance
+ var key = "ncNodeName_" + currentNode.key;
+ if (ncNodeNameCache.id != key) {
+ ncNodeNameCache.id = key;
+ ncNodeNameCache.keys = {};
+ }
+
+ // See if there is a value in the cache and use that
+ if (ncNodeNameCache.keys[input]) {
+ return ncNodeNameCache.keys[input];
+ }
+
+ // No value, so go fetch one
+ // We'll put a temp value in the cache though so we don't
+ // make a load of requests while we wait for a response
+ ncNodeNameCache.keys[input] = "Loading...";
+
+ entityResource.getById(input, "Document")
+ .then(function (ent) {
+ ncNodeNameCache.keys[input] = ent.name;
+ });
+
+ // Return the current value for now
+ return ncNodeNameCache.keys[input];
+ }
+
+});
\ No newline at end of file
diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.resources.js b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.resources.js
index 192a501..d9a4edb 100644
--- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.resources.js
+++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Js/nestedcontent.resources.js
@@ -2,7 +2,7 @@
function ($q, $http, umbRequestHelper) {
return {
getContentTypes: function () {
- var url = "/umbraco/backoffice/NestedContent/NestedContentApi/GetContentTypes";
+ var url = Umbraco.Sys.ServerVariables.umbracoSettings.umbracoPath + "/backoffice/NestedContent/NestedContentApi/GetContentTypes";
return umbRequestHelper.resourcePromise(
$http.get(url),
'Failed to retrieve content types'
diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.doctypepicker.html b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.doctypepicker.html
index 5a42748..3572a5e 100644
--- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.doctypepicker.html
+++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.doctypepicker.html
@@ -52,7 +52,7 @@
Name template:
- Enter an angular expression to evaluate against each item for its name.
+ Enter an angular expression to evaluate against each item for its name. Use {{$index}}
to display the item index
-
\ No newline at end of file
+
diff --git a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html
index 0943780..0a98742 100644
--- a/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html
+++ b/src/Our.Umbraco.NestedContent/Web/UI/App_Plugins/NestedContent/Views/nestedcontent.html
@@ -12,10 +12,10 @@
-
+
@@ -42,8 +42,8 @@
-
-