Files
Archetype/app/controllers/controller.js
T

604 lines
20 KiB
JavaScript
Raw Normal View History

2015-10-07 17:11:26 -04:00
{{VERSION}}
2015-10-04 21:39:50 +02:00
angular.module("umbraco").controller("Imulus.ArchetypeController", function ($scope, $http, $filter, assetsService, angularHelper, notificationsService, $timeout, fileManager, entityResource, archetypeService, archetypeLabelService, archetypeCacheService, archetypePropertyEditorResource) {
2014-01-10 17:20:35 -07:00
//$scope.model.value = "";
$scope.model.hideLabel = $scope.model.config.hideLabel == 1;
2014-01-10 17:20:35 -07:00
2014-01-19 08:14:27 -05:00
//get a reference to the current form
2014-05-12 12:43:38 -04:00
$scope.form = $scope.form || angularHelper.getCurrentForm($scope);
2014-01-15 17:31:31 -05:00
2014-01-19 08:14:27 -05:00
//set the config equal to our prevalue config
$scope.model.config = $scope.model.config.archetypeConfig;
2014-01-19 08:14:27 -05:00
//ini the model
$scope.model.value = $scope.model.value || getDefaultModel($scope.model.config);
2014-06-23 20:58:42 -04:00
// store the umbraco property alias to help generate unique IDs. Hopefully there's a better way to get this in the future :)
$scope.umbracoHostPropertyAlias = $scope.$parent.$parent.model.alias;
2016-01-05 22:19:08 +01:00
$scope.isDebuggingEnabled = Umbraco.Sys.ServerVariables.isDebuggingEnabled;
2014-06-23 20:58:42 -04:00
2015-08-18 17:59:20 +02:00
$scope.overlayMenu = {
show: false,
style: {}
};
2014-04-29 12:31:02 -04:00
init();
//hold references to helper resources
$scope.resources = {
entityResource: entityResource,
archetypePropertyEditorResource: archetypePropertyEditorResource
}
//hold references to helper services
$scope.services = {
archetypeService: archetypeService,
2015-06-01 13:49:34 -04:00
archetypeLabelService: archetypeLabelService,
archetypeCacheService: archetypeCacheService
}
//helper to get $eval the labelTemplate
2015-05-29 08:55:08 -04:00
$scope.getFieldsetTitle = function (fieldsetConfigModel, fieldsetIndex) {
return archetypeLabelService.getFieldsetTitle($scope, fieldsetConfigModel, fieldsetIndex);
2014-08-12 16:56:23 -04:00
}
2014-01-31 20:56:40 -07:00
2015-05-11 15:31:46 -04:00
var draggedRteSettings;
2015-10-02 13:40:09 +02:00
var rteClass = ".umb-rte textarea";
2014-01-10 17:20:35 -07:00
2014-01-19 08:14:27 -05:00
//sort config
$scope.sortableOptions = {
2014-01-10 17:20:35 -07:00
axis: 'y',
cursor: "move",
handle: ".handle",
2015-03-13 10:18:57 -04:00
start: function(ev, ui) {
2015-05-11 15:31:46 -04:00
draggedRteSettings = {};
2015-10-02 13:40:09 +02:00
$(rteClass, ui.item.parent()).each(function () {
var id = $(this).attr("id");
draggedRteSettings[id] = _.findWhere(tinyMCE.editors, { id: id }).settings;
tinymce.execCommand('mceRemoveEditor', false, id);
$(this).css("visibility", "hidden");
2015-03-13 10:18:57 -04:00
});
},
2014-01-10 17:20:35 -07:00
update: function (ev, ui) {
2014-05-12 21:51:19 +02:00
$scope.setDirty();
2014-01-10 17:20:35 -07:00
},
stop: function (ev, ui) {
2015-10-02 13:40:09 +02:00
$(rteClass, ui.item.parent()).each(function () {
var id = $(this).attr("id");
draggedRteSettings[id] = draggedRteSettings[id] || _.findWhere(tinyMCE.editors, { id: id }).settings;
tinyMCE.execCommand("mceRemoveEditor", false, id);
tinyMCE.init(draggedRteSettings[id]);
2015-03-13 10:18:57 -04:00
});
2014-01-10 17:20:35 -07:00
}
};
2014-01-12 14:05:39 -05:00
//handles a fieldset add
2015-08-18 17:59:20 +02:00
$scope.openFieldsetPicker = function ($index, event) {
if ($scope.canAdd() == false) {
return;
}
2015-10-04 21:39:50 +02:00
var allFieldsets = [];
2015-08-18 17:59:20 +02:00
_.each($scope.model.config.fieldsets, function (fieldset) {
var icon = fieldset.icon;
2015-10-04 21:39:50 +02:00
allFieldsets.push({
2015-08-18 17:59:20 +02:00
alias: fieldset.alias,
label: fieldset.label,
2015-10-04 21:39:50 +02:00
icon: (fieldset.icon || "icon-document-dashed-line"), // default icon if none is chosen
group: fieldset.group ? fieldset.group.name : null
2015-08-18 17:59:20 +02:00
});
});
// sanity check
2015-10-04 21:39:50 +02:00
if (allFieldsets == 0) {
2015-08-18 17:59:20 +02:00
return;
}
2015-10-04 21:39:50 +02:00
if (allFieldsets.length == 1) {
2015-08-18 17:59:20 +02:00
// only one fieldset type - no need to display the picker
2015-10-04 21:39:50 +02:00
$scope.addRow(allFieldsets[0].alias, $index);
2015-08-18 17:59:20 +02:00
return;
}
2015-10-04 21:39:50 +02:00
$scope.overlayMenu.fieldsetGroups = [];
if ($scope.model.config.fieldsetGroups && $scope.model.config.fieldsetGroups.length > 0) {
_.each($scope.model.config.fieldsetGroups, function (fieldsetGroup) {
2015-10-05 14:37:11 +02:00
$scope.overlayMenu.fieldsetGroups.push({ name: fieldsetGroup.name, fieldsets: $filter("filter")(allFieldsets, { group: fieldsetGroup.name }, true) });
2015-10-04 21:39:50 +02:00
})
}
else {
$scope.overlayMenu.fieldsetGroups.push({ name: "", fieldsets: allFieldsets });
}
$scope.overlayMenu.index = $index;
$scope.overlayMenu.activeFieldsetGroup = $scope.overlayMenu.fieldsetGroups[0];
2015-08-18 17:59:20 +02:00
// 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;
}
$scope.overlayMenu.show = true;
};
$scope.closeFieldsetPicker = function () {
$scope.overlayMenu.show = false;
};
$scope.pickFieldset = function (fieldsetAlias, $index) {
$scope.closeFieldsetPicker();
$scope.addRow(fieldsetAlias, $index);
};
2014-01-12 14:05:39 -05:00
$scope.addRow = function (fieldsetAlias, $index) {
2015-01-27 10:51:22 -05:00
if ($scope.canAdd()) {
if ($scope.model.config.fieldsets) {
2014-01-16 13:42:08 -05:00
var newFieldset = getEmptyRenderFieldset($scope.getConfigFieldsetByAlias(fieldsetAlias));
2014-01-12 14:05:39 -05:00
if (typeof $index != 'undefined')
{
2014-04-29 12:31:02 -04:00
$scope.model.value.fieldsets.splice($index + 1, 0, newFieldset);
2014-01-12 14:05:39 -05:00
}
else
{
2014-04-29 12:31:02 -04:00
$scope.model.value.fieldsets.push(newFieldset);
2014-01-12 14:05:39 -05:00
}
2014-01-10 17:20:35 -07:00
}
2015-08-18 13:03:11 -04:00
2016-03-20 13:28:22 +01:00
addCustomPropertiesToFieldset(newFieldset);
2014-05-12 21:51:19 +02:00
$scope.setDirty();
2015-08-18 13:03:11 -04:00
$scope.$broadcast("archetypeAddFieldset", {index: $index, visible: countVisible()});
newFieldset.collapse = $scope.model.config.enableCollapsing ? true : false;
2015-08-18 13:03:11 -04:00
$scope.focusFieldset(newFieldset);
2014-01-10 17:20:35 -07:00
}
}
$scope.removeRow = function ($index) {
if ($scope.canRemove()) {
if (confirm('Are you sure you want to remove this?')) {
2014-05-12 21:51:19 +02:00
$scope.setDirty();
2014-04-29 12:31:02 -04:00
$scope.model.value.fieldsets.splice($index, 1);
2015-05-26 08:28:32 -04:00
$scope.$broadcast("archetypeRemoveFieldset", {index: $index});
2014-01-10 17:20:35 -07:00
}
}
}
2015-01-27 10:51:22 -05:00
$scope.cloneRow = function ($index) {
if ($scope.canClone() && typeof $index != 'undefined') {
var newFieldset = angular.copy($scope.model.value.fieldsets[$index]);
if(newFieldset) {
$scope.model.value.fieldsets.splice($index + 1, 0, newFieldset);
$scope.setDirty();
newFieldset.collapse = $scope.model.config.enableCollapsing ? true : false;
$scope.focusFieldset(newFieldset);
}
}
}
2014-06-28 12:42:36 +02:00
$scope.enableDisable = function (fieldset) {
fieldset.disabled = !fieldset.disabled;
// explicitly set the form as dirty when manipulating the enabled/disabled state of a fieldset
$scope.setDirty();
}
2014-01-10 17:20:35 -07:00
//helpers for determining if a user can do something
2015-01-27 10:51:22 -05:00
$scope.canAdd = function () {
if ($scope.model.config.maxFieldsets)
2014-01-10 17:20:35 -07:00
{
return countVisible() < $scope.model.config.maxFieldsets;
2014-01-10 17:20:35 -07:00
}
return true;
}
2014-01-12 14:05:39 -05:00
//helper that returns if an item can be removed
2015-01-27 10:51:22 -05:00
$scope.canRemove = function () {
return countVisible() > 1
|| ($scope.model.config.maxFieldsets == 1 && $scope.model.config.fieldsets.length > 1)
|| $scope.model.config.startWithAddButton;
2014-01-10 17:20:35 -07:00
}
2015-01-27 10:51:22 -05:00
$scope.canClone = function () {
2015-01-27 11:05:43 -05:00
if (!$scope.model.config.enableCloning) {
return false;
}
2015-01-27 10:51:22 -05:00
if ($scope.model.config.maxFieldsets)
{
2015-01-27 11:05:43 -05:00
return countVisible() < $scope.model.config.maxFieldsets;
2015-01-27 10:51:22 -05:00
}
return true;
}
2014-01-12 14:05:39 -05:00
//helper that returns if an item can be sorted
2014-01-10 17:20:35 -07:00
$scope.canSort = function ()
{
return countVisible() > 1;
}
2014-06-28 12:42:36 +02:00
//helper that returns if an item can be disabled
$scope.canDisable = function () {
return $scope.model.config.enableDisabling;
}
//helpers for determining if the add button should be shown
$scope.showAddButton = function () {
return $scope.model.config.startWithAddButton
2014-05-08 13:32:04 -04:00
&& countVisible() === 0;
///&& $scope.model.config.fieldsets.length == 1;
}
2016-03-20 12:02:21 +01:00
//helper that returns if an item can use publishing
$scope.canPublish = function () {
return $scope.model.config.enablePublishing;
}
2016-04-04 21:21:02 +02:00
$scope.canUseMemberGroups = function() {
return $scope.model.config.enableMemberGroups;
}
2016-03-20 12:02:21 +01:00
//helper that returns if the "misc fieldset configuration" section should be visible
$scope.canConfigure = function () {
2016-04-04 21:21:02 +02:00
// currently the "misc fieldset configuration" section contains the publishing and the member groups setup
return $scope.canPublish() || $scope.canUseMemberGroups();
2016-03-20 12:02:21 +01:00
}
$scope.showDisableIcon = function (fieldset) {
if ($scope.canDisable() == false) {
return false;
}
// disabled state takes precedence over publishing
if (fieldset.disabled) {
return true;
}
return $scope.isDisabledByPublishing(fieldset) == false;
}
$scope.showPublishingIcon = function (fieldset) {
if ($scope.canPublish() == false) {
return false;
}
if ($scope.canDisable()) {
// disabled state takes precedence over publishing
if (fieldset.disabled) {
return false;
}
return $scope.isDisabledByPublishing(fieldset);
2016-03-20 12:02:21 +01:00
}
return true;
2016-03-20 12:02:21 +01:00
}
$scope.isDisabledByPublishing = function (fieldset) {
if ($scope.canPublish() === false) {
return false;
}
2016-03-22 19:35:40 +01:00
// NOTE: all comparison is done in local datetime
// - that's fine because the selected local datetimes will be converted to UTC datetimes when submitted
2016-03-20 12:02:21 +01:00
if (fieldset.expireDateModel && fieldset.expireDateModel.value) {
// an expired release affects the fieldset
return moment() > moment(fieldset.expireDateModel.value);
}
if (fieldset.releaseDateModel && fieldset.releaseDateModel.value) {
// a pending release affects the fieldset
return moment(fieldset.releaseDateModel.value) > moment();
}
return false;
}
$scope.isDisabled = function(fieldset) {
if (fieldset.disabled) {
return true;
}
return $scope.isDisabledByPublishing(fieldset);
2016-03-20 12:02:21 +01:00
}
2014-01-10 17:20:35 -07:00
//helper, ini the render model from the server (model.value)
2014-04-29 12:31:02 -04:00
function init() {
$scope.model.value = removeNulls($scope.model.value);
addDefaultProperties($scope.model.value.fieldsets);
2014-04-29 12:31:02 -04:00
}
2014-01-16 12:37:01 -05:00
function addDefaultProperties(fieldsets)
2014-04-29 12:31:02 -04:00
{
_.each(fieldsets, function (fieldset)
{
2014-01-16 12:37:01 -05:00
fieldset.collapse = false;
fieldset.isValid = true;
});
2014-01-10 17:20:35 -07:00
}
function addCustomProperties(fieldsets) {
_.each(fieldsets, function (fieldset) {
2016-03-20 13:28:22 +01:00
addCustomPropertiesToFieldset(fieldset);
2016-03-20 12:02:21 +01:00
});
}
2016-03-20 13:28:22 +01:00
function addCustomPropertiesToFieldset(fieldset) {
2016-03-22 19:35:40 +01:00
// create models for publish configuration (utilizing the built-in datepicker data type)
// NOTE: all datetimes must be converted from UTC to local
2016-03-20 13:28:22 +01:00
fieldset.releaseDateModel = {
alias: _.uniqueId("archetypeReleaseDate_"),
view: "datepicker",
2016-03-22 19:35:40 +01:00
value: fromUtc(fieldset.releaseDate)
2016-03-20 13:28:22 +01:00
};
fieldset.expireDateModel = {
alias: _.uniqueId("archetypeExpireDate_"),
view: "datepicker",
2016-03-22 19:35:40 +01:00
value: fromUtc(fieldset.expireDate)
2016-03-20 13:28:22 +01:00
};
2016-03-23 15:08:07 +01:00
// create model for allowed member groups
fieldset.allowedMemberGroupsModel = {
alias: _.uniqueId("archetypeAllowedMemberGroups_"),
view: "membergrouppicker",
value: fieldset.allowedMemberGroups
};
2016-03-20 13:28:22 +01:00
}
2014-01-12 14:05:39 -05:00
//helper to get the correct fieldset from config
$scope.getConfigFieldsetByAlias = function(alias) {
2014-01-16 12:37:01 -05:00
return _.find($scope.model.config.fieldsets, function(fieldset){
return fieldset.alias == alias;
});
2014-01-12 14:05:39 -05:00
}
//helper to get a property by alias from a fieldset
$scope.getPropertyValueByAlias = function(fieldset, propertyAlias) {
var property = _.find(fieldset.properties, function(p) {
return p.alias == propertyAlias;
});
return (typeof property !== 'undefined') ? property.value : '';
};
2014-04-29 12:31:02 -04:00
$scope.isCollapsed = function(fieldset)
{
if(typeof fieldset.collapse === "undefined")
{
fieldset.collapse = true;
}
return fieldset.collapse;
}
2014-01-19 08:14:27 -05:00
//helper for expanding/collapsing fieldsets
$scope.focusFieldset = function(fieldset){
fixDisableSelection();
if (!$scope.model.config.enableCollapsing) {
return;
}
var iniState;
if(fieldset)
{
iniState = fieldset.collapse;
}
2014-04-29 12:31:02 -04:00
_.each($scope.model.value.fieldsets, function(fieldset){
2014-01-16 12:37:01 -05:00
fieldset.collapse = true;
});
2014-04-29 12:31:02 -04:00
if(!fieldset && $scope.model.value.fieldsets.length == 1)
2014-03-14 22:28:27 -06:00
{
2014-04-29 12:31:02 -04:00
$scope.model.value.fieldsets[0].collapse = false;
2014-03-14 22:28:27 -06:00
return;
}
2014-03-14 22:28:27 -06:00
if(iniState && fieldset)
{
fieldset.collapse = !iniState;
}
}
2014-01-19 08:14:27 -05:00
//ini the fieldset expand/collapse
$scope.focusFieldset();
2014-01-12 14:05:39 -05:00
2014-01-10 17:20:35 -07:00
//developerMode helpers
2014-04-29 12:31:02 -04:00
$scope.model.value.toString = stringify;
2014-01-10 17:20:35 -07:00
2014-05-20 21:28:29 +02:00
// issue 114: register handler for file selection
2014-05-18 18:19:20 +02:00
$scope.model.value.setFiles = setFiles;
2014-01-12 14:05:39 -05:00
//encapsulate stringify (should be built into browsers, not sure of IE support)
2014-01-10 17:20:35 -07:00
function stringify() {
return JSON.stringify(this);
}
2014-05-20 21:28:29 +02:00
// issue 114: handler for file selection
function setFiles(files) {
2014-05-18 18:19:20 +02:00
// get all currently selected files from file manager
var currentFiles = fileManager.getFiles();
2014-05-18 18:19:20 +02:00
// get the files already selected for this archetype (by alias)
var archetypeFiles = [];
_.each(currentFiles, function (item) {
if (item.alias === $scope.model.alias) {
archetypeFiles.push(item.file);
}
});
2014-05-20 21:28:29 +02:00
2014-05-18 18:19:20 +02:00
// add the newly selected files
_.each(files, function (file) {
archetypeFiles.push(file);
});
2014-05-20 21:28:29 +02:00
// update the selected files for this archetype (by alias)
2014-05-18 18:19:20 +02:00
fileManager.setFiles($scope.model.alias, archetypeFiles);
}
2014-01-10 17:20:35 -07:00
//watch for changes
2014-04-29 12:31:02 -04:00
$scope.$watch('model.value', function (v) {
2014-01-10 17:20:35 -07:00
if ($scope.model.config.developerMode) {
2014-01-14 12:10:26 -05:00
console.log(v);
2014-01-10 17:20:35 -07:00
if (typeof v === 'string') {
2014-04-29 12:31:02 -04:00
$scope.model.value = JSON.parse(v);
$scope.model.value.toString = stringify;
2014-01-10 17:20:35 -07:00
}
}
2015-06-23 17:21:26 +02:00
2014-05-20 21:28:29 +02:00
// issue 114: re-register handler for files selection and reset the currently selected files on the file manager
2014-05-18 18:19:20 +02:00
$scope.model.value.setFiles = setFiles;
2014-05-20 21:28:29 +02:00
fileManager.setFiles($scope.model.alias, []);
2015-06-23 17:21:26 +02:00
2015-04-04 21:57:49 +02:00
// reset submit watcher counter on save
$scope.activeSubmitWatcher = 0;
2016-03-20 12:02:21 +01:00
2016-03-20 14:05:31 +01:00
// create properties needed for the backoffice to work (data that is not serialized to DB)
addCustomProperties($scope.model.value.fieldsets);
2014-01-10 17:20:35 -07:00
});
//helper to count what is visible
function countVisible()
{
2014-04-29 12:31:02 -04:00
return $scope.model.value.fieldsets.length;
2014-01-10 17:20:35 -07:00
}
// helper to get initial model if none was provided
function getDefaultModel(config) {
if (config.startWithAddButton)
return { fieldsets: [] };
return { fieldsets: [getEmptyRenderFieldset(config.fieldsets[0])] };
}
2014-01-19 08:14:27 -05:00
//helper to add an empty fieldset to the render model
function getEmptyRenderFieldset (fieldsetModel) {
2014-04-29 12:31:02 -04:00
return {alias: fieldsetModel.alias, collapse: false, isValid: true, properties: []};
2014-01-12 14:05:39 -05:00
}
//helper to ensure no nulls make it into the model
function removeNulls(model){
if(model.fieldsets){
_.each(model.fieldsets, function(fieldset, index){
if(!fieldset){
model.fieldsets.splice(index, 1);
removeNulls(model);
}
});
return model;
}
}
// Hack for U4-4281 / #61
function fixDisableSelection() {
$timeout(function() {
$('.archetypeEditor .controls')
.bind('mousedown.ui-disableSelection selectstart.ui-disableSelection', function(e) {
e.stopImmediatePropagation();
});
}, 1000);
}
2014-01-19 08:14:27 -05:00
//helper to lookup validity when given a fieldsetIndex and property alias
2014-01-16 12:37:01 -05:00
$scope.getPropertyValidity = function(fieldsetIndex, alias)
{
2014-04-29 12:31:02 -04:00
if($scope.model.value.fieldsets[fieldsetIndex])
2014-01-16 12:37:01 -05:00
{
2014-04-29 12:31:02 -04:00
var property = _.find($scope.model.value.fieldsets[fieldsetIndex].properties, function(property){
2014-01-16 12:37:01 -05:00
return property.alias == alias;
});
2014-01-15 17:31:31 -05:00
}
2014-01-16 12:37:01 -05:00
return (typeof property == 'undefined') ? true : property.isValid;
2014-01-15 17:31:31 -05:00
}
//helper to lookup validity when given a fieldset
$scope.getFieldsetValidity = function (fieldset) {
if (fieldset.isValid == false) {
return false;
}
// recursive validation of nested fieldsets
var nestedFieldsetsValid = true;
_.each(fieldset.properties, function (property) {
if (property != null && property.value != null && property.propertyEditorAlias == "Imulus.Archetype") {
_.each(property.value.fieldsets, function (inner) {
if ($scope.getFieldsetValidity(inner) == false) {
nestedFieldsetsValid = false;
}
});
}
});
return nestedFieldsetsValid;
}
2014-05-12 21:51:19 +02:00
// helper to force the current form into the dirty state
$scope.setDirty = function () {
if($scope.form) {
$scope.form.$setDirty();
}
}
2014-01-10 17:20:35 -07:00
//custom js
if ($scope.model.config.customJsPath) {
assetsService.loadJs($scope.model.config.customJsPath);
}
2014-01-10 17:20:35 -07:00
//archetype css
2015-08-14 14:49:41 +02:00
assetsService.loadCss("../App_Plugins/Archetype/css/archetype.css");
2014-01-10 17:20:35 -07:00
//custom css
if($scope.model.config.customCssPath)
{
assetsService.loadCss($scope.model.config.customCssPath);
}
2015-04-04 21:57:49 +02:00
// submit watcher handling:
// because some property editors use the "formSubmitting" event to set/clean up their model.value,
// we need to monitor the "formSubmitting" event from a custom property and broadcast our own event
// to forcefully update the appropriate model.value's
$scope.activeSubmitWatcher = 0;
$scope.submitWatcherOnLoad = function () {
$scope.activeSubmitWatcher++;
return $scope.activeSubmitWatcher;
}
2015-12-14 09:53:01 -05:00
$scope.submitWatcherOnSubmit = function (args) {
$scope.$broadcast("archetypeFormSubmitting", args);
}
// we need to hook into this event to save the custom fieldset properties because the lazy loading
// of property editors means that the submitWatcherOnSubmit won't necessarily be fired
$scope.$on("formSubmitting", function(ev, args) {
_.each($scope.model.value.fieldsets, function (fieldset) {
2016-03-22 19:35:40 +01:00
// extract the publish configuration from the fieldsets (and convert local datetimes to UTC)
fieldset.releaseDate = toUtc(fieldset.releaseDateModel.value);
fieldset.expireDate = toUtc(fieldset.expireDateModel.value);
2016-03-23 15:08:07 +01:00
// extract the allowed member groups
fieldset.allowedMemberGroups = fieldset.allowedMemberGroupsModel.value;
2016-03-20 12:02:21 +01:00
});
});
2016-03-22 19:35:40 +01:00
2016-04-04 21:21:02 +02:00
// we need to hook into this event for saving back the custom properties, because of the lazy loading of property editors
$scope.$on("formSubmitting", function(ev, args) {
});
2016-03-22 19:35:40 +01:00
function toUtc(date) {
if (!date) {
return null;
}
return moment(date, "YYYY-MM-DD HH:mm:ss").utc().toDate();
}
function fromUtc(date) {
if (!date) {
return null;
}
return moment(moment.utc(date).toDate()).format("YYYY-MM-DD HH:mm:ss")
}
2014-01-10 17:20:35 -07:00
});