Add Multi Url Picker

This commit is contained in:
Rasmus John Pedersen
2019-01-21 20:08:09 +01:00
committed by Sebastiaan Janssen
parent 9b9c9ef455
commit e1175b814e
12 changed files with 599 additions and 0 deletions

View File

@@ -0,0 +1,135 @@
function multiUrlPickerController($scope, angularHelper, localizationService, entityResource, iconHelper, editorService) {
$scope.renderModel = [];
if ($scope.preview) {
return;
}
if (!Array.isArray($scope.model.value)) {
$scope.model.value = [];
}
var currentForm = angularHelper.getCurrentForm($scope);
$scope.sortableOptions = {
distance: 10,
tolerance: "pointer",
scroll: true,
zIndex: 6000,
update: function () {
currentForm.$setDirty();
}
};
$scope.model.value.forEach(function (link) {
link.icon = iconHelper.convertFromLegacyIcon(link.icon);
$scope.renderModel.push(link);
});
$scope.$on("formSubmitting", function () {
$scope.model.value = $scope.renderModel;
});
$scope.$watch(
function () {
return $scope.renderModel.length;
},
function () {
//Validate!
if ($scope.model.config && $scope.model.config.minNumber && parseInt($scope.model.config.minNumber) > $scope.renderModel.length) {
$scope.multiUrlPickerForm.minCount.$setValidity("minCount", false);
}
else {
$scope.multiUrlPickerForm.minCount.$setValidity("minCount", true);
}
if ($scope.model.config && $scope.model.config.maxNumber && parseInt($scope.model.config.maxNumber) < $scope.renderModel.length) {
$scope.multiUrlPickerForm.maxCount.$setValidity("maxCount", false);
}
else {
$scope.multiUrlPickerForm.maxCount.$setValidity("maxCount", true);
}
$scope.sortableOptions.disabled = $scope.renderModel.length === 1;
}
);
$scope.remove = function ($index) {
$scope.renderModel.splice($index, 1);
currentForm.$setDirty();
};
$scope.openLinkPicker = function (link, $index) {
var target = link ? {
name: link.name,
anchor: link.queryString,
// the linkPicker breaks if it get an udi for media
udi: link.isMedia ? null : link.udi,
url: link.url,
target: link.target
} : null;
var linkPicker = {
currentTarget: target,
submit: function (model) {
if (model.target.url) {
// if an anchor exists, check that it is appropriately prefixed
if (model.target.anchor && model.target.anchor[0] !== '?' && model.target.anchor[0] !== '#') {
model.target.anchor = (model.target.anchor.indexOf('=') === -1 ? '#' : '?') + model.target.anchor;
}
if (link) {
if (link.isMedia && link.url === model.target.url) {
// we can assume the existing media item is changed and no new file has been selected
// so we don't need to update the udi and isMedia fields
} else {
link.udi = model.target.udi;
link.isMedia = model.target.isMedia;
}
link.name = model.target.name || model.target.url;
link.queryString = model.target.anchor;
link.target = model.target.target;
link.url = model.target.url;
} else {
link = {
isMedia: model.target.isMedia,
name: model.target.name || model.target.url,
queryString: model.target.anchor,
target: model.target.target,
udi: model.target.udi,
url: model.target.url
};
$scope.renderModel.push(link);
}
if (link.udi) {
var entityType = link.isMedia ? "media" : "document";
entityResource.getById(link.udi, entityType).then(function (data) {
link.icon = iconHelper.convertFromLegacyIcon(data.icon);
link.published = (data.metaData && data.metaData.IsPublished === false && entityType === "Document") ? false : true;
link.trashed = data.trashed;
if (link.trashed) {
item.url = localizationService.dictionary.general_recycleBin;
}
});
} else {
link.icon = "icon-link";
link.published = true;
}
currentForm.$setDirty();
}
editorService.close();
},
close: function () {
editorService.close();
}
};
editorService.linkPicker(linkPicker);
};
}
angular.module("umbraco").controller("Umbraco.PropertyEditors.MultiUrlPickerController", multiUrlPickerController);

View File

@@ -0,0 +1,77 @@
<div ng-controller="Umbraco.PropertyEditors.MultiUrlPickerController" class="umb-property-editor umb-contentpicker">
<p ng-if="(renderModel|filter:{trashed:true}).length == 1"><localize key="contentPicker_pickedTrashedItem"></localize></p>
<p ng-if="(renderModel|filter:{trashed:true}).length > 1"><localize key="contentPicker_pickedTrashedItems"></localize></p>
<ng-form name="multiUrlPickerForm">
<div ui-sortable="sortableOptions" ng-model="renderModel">
<umb-node-preview ng-repeat="link in renderModel"
icon="link.icon"
name="link.name"
published="link.published"
description="link.url + (link.queryString ? link.queryString : '')"
sortable="!sortableOptions.disabled"
allow-remove="true"
allow-edit="true"
on-remove="remove($index)"
on-edit="openContentEditor(link, $index)">
</umb-node-preview>
</div>
<a ng-show="!model.config.maxNumber || renderModel.length < model.config.maxNumber"
class="umb-node-preview-add"
href
ng-click="openLinkPicker()"
prevent-default>
<localize key="general_add">Add</localize>
</a>
<div class="umb-contentpicker__min-max-help">
<!-- Both min and max items -->
<span ng-if="model.config.minNumber && model.config.maxNumber && model.config.minNumber !== model.config.maxNumber">
<span ng-if="renderModel.length < model.config.maxNumber">Add between {{model.config.minNumber}} and {{model.config.maxNumber}} items</span>
<span ng-if="renderModel.length > model.config.maxNumber">
<localize key="validation_maxCount">You can only have</localize> {{model.config.maxNumber}} <localize key="validation_itemsSelected"> items selected</localize>
</span>
</span>
<!-- Equal min and max -->
<span ng-if="model.config.minNumber && model.config.maxNumber && model.config.minNumber === model.config.maxNumber">
<span ng-if="renderModel.length < model.config.maxNumber">Add {{model.config.minNumber - renderModel.length}} item(s)</span>
<span ng-if="renderModel.length > model.config.maxNumber">
<localize key="validation_maxCount">You can only have</localize> {{model.config.maxNumber}} <localize key="validation_itemsSelected"> items selected</localize>
</span>
</span>
<!-- Only max -->
<span ng-if="!model.config.minNumber && model.config.maxNumber">
<span ng-if="renderModel.length < model.config.maxNumber">Add up to {{model.config.maxNumber}} items</span>
<span ng-if="renderModel.length > model.config.maxNumber">
<localize key="validation_maxCount">You can only have</localize> {{model.config.maxNumber}} <localize key="validation_itemsSelected">items selected</localize>
</span>
</span>
<!-- Only min -->
<span ng-if="model.config.minNumber && !model.config.maxNumber && renderModel.length < model.config.minNumber">
Add at least {{model.config.minNumber}} item(s)
</span>
</div>
<!--These are here because we need ng-form fields to validate against-->
<input type="hidden" name="minCount" ng-model="renderModel" />
<input type="hidden" name="maxCount" ng-model="renderModel" />
<div ng-messages="contentPickerForm.minCount.$error" show-validation-on-submit>
<div class="help-inline" ng-message="minCount">
<localize key="validation_minCount">You need to add at least</localize> {{model.config.minNumber}} <localize key="validation_items">items</localize>
</div>
</div>
<div ng-messages="contentPickerForm.maxCount.$error" show-validation-on-submit>
<div class="help-inline" ng-message="maxCount">
<localize key="validation_maxCount">You can only have</localize> {{model.config.maxNumber}} <localize key="validation_itemsSelected">items selected</localize>
</div>
</div>
</ng-form>
</div>