You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ocr/htmlweb/modeler/scripts/controllers/form-builder.js

322 lines
14 KiB

/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
angular.module('flowableModeler')
.controller('FormBuilderController', ['$rootScope', '$scope', '$translate', '$http', '$timeout', '$location', '$modal', '$routeParams', '$popover', 'FormBuilderService',
function ($rootScope, $scope, $translate, $http, $timeout, $location, $modal, $routeParams, $popover, FormBuilderService) {
// Main page (needed for visual indicator of current page)
$rootScope.setMainPageById('forms');
// Needs to be on root scope to be available in the toolbar controller
$rootScope.formBuilder = {activeTab: 'design'};
$scope.model = {
useOutcomes: false
};
$rootScope.currentReadonlyFields = {fields: {}};
$scope.$watch('model.useOutcomes', function (value) {
if (value) {
if (!$rootScope.currentOutcomes || $rootScope.currentOutcomes.length === 0) {
$rootScope.currentOutcomes = [{name: ''}];
}
} else {
$rootScope.currentOutcomes = [];
}
});
// tabs for tab-control. NOT using templates for the tabs, we control the view
// ourselves, based on the active tab binding
$scope.tabs = [
{
id: 'design',
title: 'FORM-BUILDER.TITLE.DESIGN'
},
{
id: 'outcome',
title: 'FORM-BUILDER.TITLE.OUTCOME'
}
];
$scope.form = {
name: '',
key: '',
description: '',
version: 1
};
$scope.formElements = [];
$rootScope.currentOutcomes = [];
$rootScope.formChanges = false;
var guidSequence = 0;
function setFieldDragDropAttributes (field, prefix) {
if (!field._guid) {
field._guid = prefix + guidSequence++;
}
if (!field._width) {
field._width = 1;
}
}
var lastDropArrayTarget = null;
$scope.onFieldMoved = function (field, fieldArraySource) {
};
$scope.onFieldDrop = function (paletteElementOrField, dropArrayTarget, event, index) {
// Is it an existing object?
if (paletteElementOrField.hasOwnProperty('_guid')) {
lastDropArrayTarget = dropArrayTarget;
if (dropArrayTarget) {
var i = -1;
dropArrayTarget.forEach(function (f, index) {
if (paletteElementOrField._guid == f._guid) {
i = index;
}
});
if (i != -1) {
dropArrayTarget.splice(i, 1);
}
}
if (navigator.appVersion.indexOf("MSIE 9") != -1) {
// update _guid which is what ngRepeat is tracking by to force dom updates
paletteElementOrField._guid += '_';
}
return paletteElementOrField;
}
lastDropArrayTarget = null;
var fieldId = paletteElementOrField.type;
var fieldType;
if (fieldId === 'radio-buttons' || fieldId === 'dropdown') {
fieldType = 'OptionFormField';
} else if (fieldId === 'expression') {
fieldType = 'ExpressionFormField';
}
var field = {
type: fieldId,
fieldType: fieldType,
name: 'Label',
required: false,
readOnly: false
};
setFieldDragDropAttributes(field, 'newField');
if (fieldId === 'radio-buttons') {
field.options = [{
name: $translate.instant('FORM-BUILDER.COMPONENT.RADIO-BUTTON-DEFAULT')
}];
}
if (fieldId === 'dropdown') {
field.options = [
{name: $translate.instant('FORM-BUILDER.COMPONENT.DROPDOWN-DEFAULT-EMPTY-SELECTION')}
];
field.value = field.options[0];
field.hasEmptyValue = true;
}
return field;
};
if ($routeParams.modelId) {
var url;
if ($routeParams.modelHistoryId) {
url = FLOWABLE.APP_URL.getFormModelHistoryUrl($routeParams.modelId, $routeParams.modelHistoryId);
} else {
url = FLOWABLE.APP_URL.getFormModelUrl($routeParams.modelId);
}
$http({method: 'GET', url: url}).
success(function (response, status, headers, config) {
if (response.formDefinition.fields) {
for (var i = 0; i < response.formDefinition.fields.length; i++) {
var field = response.formDefinition.fields[i];
if (!field.params) {
field.params = {};
}
setFieldDragDropAttributes(field, 'savedField');
}
$scope.formElements = response.formDefinition.fields;
} else {
$scope.formElements = [];
}
if (response.formDefinition.outcomes) {
$rootScope.currentOutcomes = response.formDefinition.outcomes;
if ($rootScope.currentOutcomes.length > 0) {
$scope.model.useOutcomes = true;
}
} else {
$rootScope.currentOutcomes = [];
}
$rootScope.currentForm = response;
delete $rootScope.currentForm.formDefinition;
$rootScope.formItems = $scope.formElements;
$rootScope.formChanges = false;
$timeout(function () {
// Flip switch in timeout to start watching all form-related models
// after next digest cycle, to prevent first false-positive
$scope.formLoaded = true;
}, 200);
}).
error(function (response, status, headers, config) {
$scope.model.loading = false;
});
} else {
$scope.formLoaded = true;
}
$scope.palletteElements = [
{'type': 'text', 'title': $translate.instant('FORM-BUILDER.PALLETTE.TEXT'), 'icon': 'images/form-builder/textfield-icon.png', 'width': 1},
{'type': 'password', 'title': $translate.instant('FORM-BUILDER.PALLETTE.PASSWORD'), 'icon': 'images/form-builder/password-icon.png', 'width': 1},
{'type': 'multi-line-text', 'title': $translate.instant('FORM-BUILDER.PALLETTE.MULTILINE-TEXT'), 'icon': 'images/form-builder/multi-line-textfield-icon.png', 'width': 1},
{'type': 'integer', 'title': $translate.instant('FORM-BUILDER.PALLETTE.NUMBER'), 'icon': 'images/form-builder/numberfield-icon.png', 'width': 1},
{'type': 'decimal', 'title': $translate.instant('FORM-BUILDER.PALLETTE.DECIMAL'), 'icon': 'images/form-builder/decimalfield-icon.png', 'width': 1},
{'type': 'boolean', 'title': $translate.instant('FORM-BUILDER.PALLETTE.CHECKBOX'), 'icon': 'images/form-builder/booleanfield-icon.png', 'width': 1},
{'type': 'date', 'title': $translate.instant('FORM-BUILDER.PALLETTE.DATE'), 'icon': 'images/form-builder/datefield-icon.png', 'width': 1},
{'type': 'dropdown', 'title': $translate.instant('FORM-BUILDER.PALLETTE.DROPDOWN'), 'icon': 'images/form-builder/dropdownfield-icon.png', 'width': 1},
{'type': 'radio-buttons', 'title': $translate.instant('FORM-BUILDER.PALLETTE.RADIO'), 'icon': 'images/form-builder/choicefield-icon.png', 'width': 1},
{'type': 'people', 'title': $translate.instant('FORM-BUILDER.PALLETTE.PEOPLE'), 'icon': 'images/form-builder/peoplefield-icon.png', 'width': 1},
{'type': 'functional-group', 'title': $translate.instant('FORM-BUILDER.PALLETTE.GROUP-OF-PEOPLE'), 'icon': 'images/form-builder/peoplefield-icon.png', 'width': 1},
{'type': 'upload', 'title': $translate.instant('FORM-BUILDER.PALLETTE.UPLOAD'), 'icon': 'images/form-builder/uploadfield-icon.png', 'width': 1},
{'type': 'expression', 'title': $translate.instant('FORM-BUILDER.PALLETTE.EXPRESSION'), 'icon': 'images/form-builder/readonly-icon.png', 'width': 1},
{'type': 'hyperlink', 'title': $translate.instant('FORM-BUILDER.PALLETTE.HYPERLINK'), 'icon': 'images/form-builder/hyperlink-icon.png', 'width':1},
{'type': 'spacer', 'title': $translate.instant('FORM-BUILDER.PALLETTE.SPACER'), 'icon': 'images/form-builder/spacer-icon.png', 'width':1},
{'type': 'horizontal-line', 'title': $translate.instant('FORM-BUILDER.PALLETTE.HORIZONTAL-LINE'), 'icon': 'images/form-builder/horizontal-line-icon.png', 'width':1},
{'type': 'headline', 'title': $translate.instant('FORM-BUILDER.PALLETTE.HEADLINE'), 'icon': 'images/form-builder/headline-icon.png', 'width':1},
{'type': 'headline-with-line', 'title': $translate.instant('FORM-BUILDER.PALLETTE.HEADLINE-WITH-LINE'), 'icon': 'images/form-builder/headline-with-line-icon.png', 'width':1}
];
$scope.$watch('formItems', function () {
if ($scope.formLoaded) {
$rootScope.formChanges = true;
}
}, true);
$scope.$watch('currentOutcomes', function () {
if ($scope.formLoaded) {
$rootScope.formChanges = true;
}
}, true);
$scope.addOutcome = function () {
$rootScope.currentOutcomes[$rootScope.currentOutcomes.length] = {name: ''};
};
$scope.removeOutcome = function (index) {
$rootScope.currentOutcomes.splice(index, 1);
};
$scope.$on('$locationChangeStart', function (event, next, current) {
if (!$rootScope.ignoreChanges && $rootScope.formChanges) {
// Always prevent location from changing. We'll use a popup to determine the action we want to take
event.preventDefault();
var discardCallback = function () {
$rootScope.ignoreChanges = true;
$location.url(next.substring(next.indexOf('/#') + 2));
};
var continueEditingCallback = function () {
// Don't change the location and make sure "main navigation" is still correct
$rootScope.ignoreChanges = false;
$rootScope.setMainPageById('forms');
};
$scope.yesNoCancel = false;
showDiscardPopup($scope, null, discardCallback, continueEditingCallback);
} else {
// Clear marker
$rootScope.ignoreChanges = false;
}
});
$scope.$on("formChangesEvent", function () {
var discardCallback = function () {
$scope.$broadcast("discardDataEvent");
};
var saveDataCallback = function () {
$scope.$broadcast("mustSaveEvent");
};
var continueEditingCallback = function () {
$scope.$broadcast("continueEditingEvent");
};
$scope.yesNoCancel = true;
showDiscardPopup($scope, saveDataCallback, discardCallback, continueEditingCallback);
});
function showDiscardPopup($scope, saveCallback, discardCallback, cancelCallback) {
if (!$scope.unsavedChangesModalInstance) {
$scope.handleResponseFunction = function (discard) {
$scope.unsavedChangesModalInstance = undefined;
if (discard == true) {
if (discardCallback) {
discardCallback();
}
} else if (discard == false) {
if (saveCallback) {
saveCallback();
}
} else {
if (cancelCallback) {
cancelCallback();
}
}
};
_internalCreateModal({
template: 'editor-app/popups/unsaved-changes.html',
scope: $scope
}, $modal, $scope);
}
};
// get current step and sequential steps for form field resolving
if ($rootScope.editorHistory && $rootScope.editorHistory.length > 0) {
$scope.stepId = $rootScope.editorHistory[0].stepId;
$scope.allSteps = $rootScope.editorHistory[0].allSteps;
}
}]);