diff --git a/app/Umbraco/Umbraco.Archetype/Models/ArchetypePreValue.cs b/app/Umbraco/Umbraco.Archetype/Models/ArchetypePreValue.cs index 1a7e4a2..653af0e 100644 --- a/app/Umbraco/Umbraco.Archetype/Models/ArchetypePreValue.cs +++ b/app/Umbraco/Umbraco.Archetype/Models/ArchetypePreValue.cs @@ -6,7 +6,10 @@ namespace Archetype.Umbraco.Models public class ArchetypePreValue { [JsonProperty("showAdvancedOptions")] - public bool ShowAdvancedOptions { get; set; } + public bool ShowAdvancedOptions { get; set; } + + [JsonProperty("startWithAddButton")] + public bool StartWithAddButton { get; set; } [JsonProperty("hideFieldsetToolbar")] public bool HideFieldsetToolbar { get; set; } diff --git a/app/controllers/config.controller.js b/app/controllers/config.controller.js index 0a3828f..08c02a8 100644 --- a/app/controllers/config.controller.js +++ b/app/controllers/config.controller.js @@ -1,19 +1,19 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", function ($scope, $http, assetsService, dialogService, archetypePropertyEditorResource) { - - //$scope.model.value = ""; - //console.log($scope.model.value); + + //$scope.model.value = ""; + //console.log($scope.model.value); //define empty items var newPropertyModel = '{"alias": "", "remove": false, "collapse": false, "label": "", "helpText": "", "dataTypeId": "-88", "value": ""}'; var newFieldsetModel = '{"alias": "", "remove": false, "collapse": false, "labelTemplate": "", "icon": "", "label": "", "properties": [' + newPropertyModel + ']}'; - var defaultFieldsetConfigModel = JSON.parse('{"showAdvancedOptions": false, "hideFieldsetToolbar": false, "enableMultipleFieldsets": false, "hideFieldsetControls": false, "hidePropertyLabel": false, "maxFieldsets": null, "enableCollapsing": true, "fieldsets": [' + newFieldsetModel + ']}'); + var defaultFieldsetConfigModel = JSON.parse('{"showAdvancedOptions": false, "startWithAddButton": false, "hideFieldsetToolbar": false, "enableMultipleFieldsets": false, "hideFieldsetControls": false, "hidePropertyLabel": false, "maxFieldsets": null, "enableCollapsing": true, "fieldsets": [' + newFieldsetModel + ']}'); //ini the model $scope.model.value = $scope.model.value || defaultFieldsetConfigModel; - + //ini the render model initConfigRenderModel(); - + //get the available datatypes archetypePropertyEditorResource.getAllDataTypes().then(function(data) { $scope.availableDataTypes = data; @@ -40,16 +40,16 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio } }; - + //function that determines how to manage expanding/collapsing fieldsets $scope.focusFieldset = function(fieldset){ var iniState; - + if(fieldset) { iniState = fieldset.collapse; } - + _.each($scope.archetypeConfigRenderModel.fieldsets, function(fieldset){ if($scope.archetypeConfigRenderModel.fieldsets.length == 1 && fieldset.remove == false) { @@ -66,7 +66,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio fieldset.collapse = false; } }); - + if(iniState) { fieldset.collapse = !iniState; @@ -79,7 +79,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio //function that determines how to manage expanding/collapsing properties $scope.focusProperty = function(properties, property){ var iniState; - + if(property) { iniState = property.collapse; @@ -95,7 +95,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio property.collapse = false; } }); - + if(iniState) { property.collapse = !iniState; @@ -106,24 +106,24 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio _.each($scope.archetypeConfigRenderModel.fieldsets, function(fieldset){ $scope.focusProperty(fieldset.properties); }); - + //setup JSON.stringify helpers $scope.archetypeConfigRenderModel.toString = stringify; - + //encapsulate stringify (should be built into browsers, not sure of IE support) function stringify() { return JSON.stringify(this); } - + //watch for changes $scope.$watch('archetypeConfigRenderModel', function (v) { //console.log(v); - if (typeof v === 'string') { + if (typeof v === 'string') { $scope.archetypeConfigRenderModel = JSON.parse(v); $scope.archetypeConfigRenderModel.toString = stringify; } }); - + $scope.autoPopulateAlias = function(s) { var modelType = s.hasOwnProperty('fieldset') ? 'fieldset' : 'property'; var modelProperty = s[modelType]; @@ -144,7 +144,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio //helper that returns if an item can be removed $scope.canRemoveFieldset = function () - { + { return countVisibleFieldset() > 1; } @@ -153,10 +153,10 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio { return countVisibleFieldset() > 1; } - + //helper that returns if an item can be removed $scope.canRemoveProperty = function (fieldset) - { + { return countVisibleProperty(fieldset) > 1; } @@ -176,7 +176,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio return dataType == null ? "" : dataType.name; } - + //helper to count what is visible function countVisibleFieldset() { @@ -190,7 +190,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio return count; } - + //determines how many properties are visible function countVisibleProperty(fieldset) { @@ -204,13 +204,13 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio return count; } - + //handles a fieldset add $scope.addFieldsetRow = function ($index, $event) { $scope.archetypeConfigRenderModel.fieldsets.splice($index + 1, 0, JSON.parse(newFieldsetModel)); $scope.focusFieldset(); } - + //rather than splice the archetypeConfigRenderModel, we're hiding this and cleaning onFormSubmitting $scope.removeFieldsetRow = function ($index) { if ($scope.canRemoveFieldset()) { @@ -219,12 +219,12 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio } } } - + //handles a property add $scope.addPropertyRow = function (fieldset, $index) { fieldset.properties.splice($index + 1, 0, JSON.parse(newPropertyModel)); } - + //rather than splice the archetypeConfigRenderModel, we're hiding this and cleaning onFormSubmitting $scope.removePropertyRow = function (fieldset, $index) { if ($scope.canRemoveProperty(fieldset)) { @@ -233,7 +233,7 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio } } } - + //helper to ini the render model function initConfigRenderModel() { @@ -257,38 +257,38 @@ angular.module("umbraco").controller("Imulus.ArchetypeConfigController", functio }); }); } - + //sync things up on save $scope.$on("formSubmitting", function (ev, args) { syncModelToRenderModel(); }); - + //helper to sync the model to the renderModel function syncModelToRenderModel() { $scope.model.value = $scope.archetypeConfigRenderModel; var fieldsets = []; - + _.each($scope.archetypeConfigRenderModel.fieldsets, function(fieldset){ //check fieldsets if (!fieldset.remove) { fieldsets.push(fieldset); - + var properties = []; _.each(fieldset.properties, function(property){ if (!property.remove) { properties.push(property); - } + } }); fieldset.properties = properties; } }); - + $scope.model.value.fieldsets = fieldsets; } - + //archetype css assetsService.loadCss("/App_Plugins/Archetype/css/archetype.css"); }); diff --git a/app/controllers/controller.js b/app/controllers/controller.js index f89e0a9..9ceb769 100644 --- a/app/controllers/controller.js +++ b/app/controllers/controller.js @@ -1,5 +1,5 @@ angular.module("umbraco").controller("Imulus.ArchetypeController", function ($scope, $http, assetsService, angularHelper, notificationsService, $timeout) { - + //$scope.model.value = ""; $scope.model.hideLabel = $scope.model.config.hideLabel == 1; @@ -8,14 +8,14 @@ //set the config equal to our prevalue config $scope.model.config = $scope.model.config.archetypeConfig; - + //ini the model - $scope.model.value = $scope.model.value || { fieldsets: [getEmptyRenderFieldset($scope.model.config.fieldsets[0])] }; + $scope.model.value = $scope.model.value || getDefaultModel($scope.model.config); //ini the render model $scope.archetypeRenderModel = {}; initArchetypeRenderModel(); - + //helper to get $eval the labelTemplate $scope.getFieldsetTitle = function(fieldsetConfigModel, fieldsetIndex) { var fieldset = $scope.archetypeRenderModel.fieldsets[fieldsetIndex]; @@ -100,8 +100,9 @@ //helper that returns if an item can be removed $scope.canRemove = function () - { - return countVisible() > 1; + { + return countVisible() > 1 + || $scope.model.config.startWithAddButton; } //helper that returns if an item can be sorted @@ -110,6 +111,12 @@ return countVisible() > 1; } + //helpers for determining if the add button should be shown + $scope.showAddButton = function () { + return $scope.model.config.startWithAddButton + && countVisible() === 0; + } + //helper, ini the render model from the server (model.value) function initArchetypeRenderModel() { $scope.archetypeRenderModel = removeNulls($scope.model.value); @@ -119,7 +126,7 @@ fieldset.remove = false; fieldset.collapse = false; fieldset.isValid = true; - }); + }); } //helper to get the correct fieldset from config @@ -136,7 +143,7 @@ }); return (typeof property !== 'undefined') ? property.value : ''; }; - + //helper for expanding/collapsing fieldsets $scope.focusFieldset = function(fieldset){ fixDisableSelection(); @@ -144,30 +151,30 @@ if (!$scope.model.config.enableCollapsing) { return; } - + var iniState; - + if(fieldset) { iniState = fieldset.collapse; } - + _.each($scope.archetypeRenderModel.fieldsets, function(fieldset){ fieldset.collapse = true; }); - + if(!fieldset && $scope.archetypeRenderModel.fieldsets.length == 1 && $scope.archetypeRenderModel.fieldsets[0].remove == false) { $scope.archetypeRenderModel.fieldsets[0].collapse = false; return; } - + if(iniState && fieldset) { fieldset.collapse = !iniState; } } - + //ini the fieldset expand/collapse $scope.focusFieldset(); @@ -241,7 +248,7 @@ if(propertyConfig){ delete property.isValid; } - else + else { //need to remove the whole property tempFieldset.properties.splice(index, 1); @@ -253,10 +260,17 @@ } } + // helper to get initial model if none was provided + function getDefaultModel(config) { + if (config.startWithAddButton) + return { fieldsets: [] }; + + return { fieldsets: [getEmptyRenderFieldset(config.fieldsets[0])] }; + } + //helper to add an empty fieldset to the render model - function getEmptyRenderFieldset (fieldsetModel) - { - return JSON.parse('{"alias": "' + fieldsetModel.alias + '", "remove": false, "isValid": true, "properties": []}'); + function getEmptyRenderFieldset (fieldsetModel) { + return {alias: fieldsetModel.alias, remove: false, isValid: true, properties: []}; } //helper to ensure no nulls make it into the model @@ -268,7 +282,7 @@ removeNulls(model); } }); - + return model; } } @@ -277,9 +291,9 @@ function fixDisableSelection() { $timeout(function() { $('.archetypeEditor .controls') - .bind('mousedown.ui-disableSelection selectstart.ui-disableSelection', function(e) { + .bind('mousedown.ui-disableSelection selectstart.ui-disableSelection', function(e) { e.stopImmediatePropagation(); - }); + }); }, 1000); } @@ -307,7 +321,7 @@ { notificationsService.warning("Cannot Save Document", "The document could not be saved because of missing required fields.") } - else + else { syncModelToRenderModel(); } @@ -316,7 +330,7 @@ //custom js if ($scope.model.config.customJsPath) { assetsService.loadJs($scope.model.config.customJsPath); - } + } //archetype css assetsService.loadCss("/App_Plugins/Archetype/css/archetype.css"); diff --git a/app/less/archetype.less b/app/less/archetype.less index eb7370f..215aac8 100644 --- a/app/less/archetype.less +++ b/app/less/archetype.less @@ -36,7 +36,7 @@ cursor: pointer; label { - span { + span { text-decoration: underline; } &:hover { @@ -297,6 +297,14 @@ } } +.archetypeEditor .archetypeAddButton:hover { + text-decoration: none; + + .archetypeAddButtonText { + text-decoration: underline; + } +} + .ui-sortable-placeholder { visibility: visible !important; background-color: #d0e7f1 !important; diff --git a/app/views/archetype.config.html b/app/views/archetype.config.html index c80bf10..a5e3b0f 100644 --- a/app/views/archetype.config.html +++ b/app/views/archetype.config.html @@ -27,7 +27,7 @@
-
+
+
+ + +
@@ -96,11 +100,11 @@
-
+
-
+
diff --git a/app/views/archetype.html b/app/views/archetype.html index b565237..f20cde2 100644 --- a/app/views/archetype.html +++ b/app/views/archetype.html @@ -9,7 +9,7 @@
-