First commit waiting for Budget Alert
This commit is contained in:
431
sophal/js/form/form.input.json.js
Normal file
431
sophal/js/form/form.input.json.js
Normal file
@ -0,0 +1,431 @@
|
||||
/*
|
||||
* Axelor Business Solutions
|
||||
*
|
||||
* Copyright (C) 2005-2019 Axelor (<http://axelor.com>).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
(function() {
|
||||
|
||||
"use strict";
|
||||
|
||||
var ui = angular.module('axelor.ui');
|
||||
|
||||
ui.formWidget('PanelJson', {
|
||||
showTitle: false,
|
||||
transclude: true,
|
||||
template: "<div class='panel-json' ui-transclude></div>"
|
||||
});
|
||||
|
||||
ui.formInput('JsonField', 'String', {
|
||||
showTitle: false,
|
||||
link: function (scope, element, attrs, model) {
|
||||
var field = scope.field;
|
||||
var jsonFields = field.jsonFields || [];
|
||||
var jsonNames = _.pluck(jsonFields, 'name');
|
||||
var jsonFix = {};
|
||||
|
||||
jsonFields.forEach(function (item) {
|
||||
if (item.widget && item.showTitle === undefined) {
|
||||
var widget = ui.getWidgetDef(item.widget);
|
||||
if (widget) {
|
||||
item.showTitle = widget.showTitle;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var defaultValues = {};
|
||||
var parentUnwatch = null;
|
||||
var selfUnwatch = null;
|
||||
|
||||
scope.formPath = scope.formPath ? scope.formPath + "." + field.name : field.name;
|
||||
scope.record = {};
|
||||
|
||||
jsonFields.forEach(function (item) {
|
||||
if (item.target === 'com.axelor.meta.db.MetaJsonRecord' &&
|
||||
item.targetName && item.targetName.indexOf('attrs.') === 0) {
|
||||
jsonFix[item.name] = function (v) {
|
||||
if (v) {
|
||||
v[item.targetName.substring(6)] = v[item.targetName];
|
||||
}
|
||||
return v;
|
||||
};
|
||||
}
|
||||
if (item.contextField && item.contextFieldValue) {
|
||||
if (item.showIf === undefined && item.hideIf === undefined && item.hidden) {
|
||||
return;
|
||||
}
|
||||
var condition = "($record." + item.contextField + ".id === " + item.contextFieldValue + ")";
|
||||
if (item.showIf) condition += " && (" + item.showIf + ")";
|
||||
if (item.hideIf) condition += " && !(" + item.hideIf + ")";
|
||||
item.showIf = condition;
|
||||
item.hideIf = null;
|
||||
}
|
||||
});
|
||||
|
||||
function getDefaultValues() {
|
||||
jsonFields.forEach(function (item) {
|
||||
if (item.defaultValue === undefined) return;
|
||||
var value = item.defaultValue;
|
||||
switch(item.type) {
|
||||
case 'integer':
|
||||
value = +(value);
|
||||
break;
|
||||
case 'date':
|
||||
case 'datetime':
|
||||
value = value === 'now' ? new Date() : moment(value).toDate();
|
||||
break;
|
||||
}
|
||||
defaultValues[item.name] = value;
|
||||
});
|
||||
return angular.copy(defaultValues);
|
||||
}
|
||||
|
||||
function unwatchParent() {
|
||||
if (parentUnwatch) {
|
||||
parentUnwatch();
|
||||
parentUnwatch = null;
|
||||
}
|
||||
}
|
||||
|
||||
function unwatchSelf() {
|
||||
if (selfUnwatch) {
|
||||
selfUnwatch();
|
||||
selfUnwatch = null;
|
||||
}
|
||||
}
|
||||
|
||||
function watchParent() {
|
||||
unwatchParent();
|
||||
parentUnwatch = scope.$watch('$parent.record.' + field.name, function jsonParentWatch(value, old) {
|
||||
if (value === old) return;
|
||||
onRender();
|
||||
});
|
||||
}
|
||||
|
||||
function watchSelf() {
|
||||
unwatchSelf();
|
||||
selfUnwatch = scope.$watch('record', function jsonRecordWatch(record, old) {
|
||||
if (record !== old) {
|
||||
onUpdate();
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
function format(name, value) {
|
||||
var func = jsonFix[name];
|
||||
return func ? func(value) : value;
|
||||
}
|
||||
|
||||
function onUpdate() {
|
||||
var rec = null;
|
||||
_.each(scope.record, function (v, k) {
|
||||
if (k.indexOf('$') === 0 || v === null || v === undefined) return;
|
||||
if (_.isArray(v)) {
|
||||
if (v.length == 0) return;
|
||||
v = v.map(function (x) {
|
||||
return x.id ? { id: x.id } : x;
|
||||
});
|
||||
}
|
||||
if (rec === null) {
|
||||
rec = {};
|
||||
}
|
||||
rec[k] = format(k, v);
|
||||
});
|
||||
unwatchParent();
|
||||
if (scope.$parent.record[field.name] || rec) {
|
||||
scope.$parent.record[field.name] = rec ? angular.toJson(rec) : rec;
|
||||
}
|
||||
watchParent();
|
||||
}
|
||||
|
||||
function onRender() {
|
||||
var record = scope.$parent.record || {};
|
||||
var value = record[field.name];
|
||||
unwatchSelf();
|
||||
if (value) {
|
||||
scope.record = angular.fromJson(value);
|
||||
} else {
|
||||
scope.record = getDefaultValues();
|
||||
if (!_.isEmpty(scope.record)) {
|
||||
record[field.name] = angular.toJson(scope.record);
|
||||
}
|
||||
onUpdate();
|
||||
}
|
||||
scope._jsonContext = { '$record': record };
|
||||
record['$' + field.name] = scope.record;
|
||||
watchSelf();
|
||||
}
|
||||
|
||||
scope.$on('on:new', onRender);
|
||||
scope.$on('on:edit', function () {
|
||||
if (scope.viewType === 'form' || (!scope.viewType && scope._isPopup)) onRender();
|
||||
});
|
||||
|
||||
scope.updateJsonValues = function (values) {
|
||||
var rec = null;
|
||||
_.each(values, function (v, k) {
|
||||
if (jsonNames.indexOf(k) === -1 && scope.fields[k]) {
|
||||
scope.$parent.record[k] = v;
|
||||
} else {
|
||||
if (rec === null) {
|
||||
rec = {};
|
||||
}
|
||||
rec[k] = v;
|
||||
}
|
||||
});
|
||||
if (rec) {
|
||||
scope.record = _.extend({}, scope.record, rec);
|
||||
}
|
||||
};
|
||||
|
||||
watchParent();
|
||||
|
||||
// hide parent panel if no jsonFields defined
|
||||
scope.$evalAsync(function () {
|
||||
var parent = scope.$parent.field || {};
|
||||
if (parent.type === 'panel' && _.size(parent.items) === 1 && _.isEmpty(field.jsonFields)) {
|
||||
element.parents('.panel:first').addClass('hide').hide();
|
||||
}
|
||||
});
|
||||
|
||||
scope.$on('on:update-context', function (e, context) {
|
||||
if (context && !context[field.name]) {
|
||||
context[field.name] = angular.toJson(scope.record || {});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
ui.formInput('JsonRaw', 'String', {
|
||||
showTitle: false,
|
||||
link: function (scope, element, attrs, model) {
|
||||
|
||||
scope.placeHolderKey = _t('name');
|
||||
scope.placeHolderVal = _t('value');
|
||||
|
||||
scope.items = [];
|
||||
|
||||
scope.onAdd = function () {
|
||||
var last = _.last(scope.items);
|
||||
if (last && !(_.trim(last.name) && _.trim(last.value))) return;
|
||||
scope.items.push({});
|
||||
};
|
||||
|
||||
scope.onRemove = function (index) {
|
||||
if (scope.items.length > 0) {
|
||||
scope.items.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
var unwatch = null;
|
||||
|
||||
function doWatch () {
|
||||
if (unwatch) {
|
||||
unwatch();
|
||||
}
|
||||
unwatch = scope.$watch('items', function jsonItemsWatch(items, old) {
|
||||
if (items === old) return;
|
||||
var record = null;
|
||||
_.each(items, function (item) {
|
||||
if (!_.trim(item.name) || !_.trim(item.value)) return;
|
||||
if (record === null) {
|
||||
record = {};
|
||||
}
|
||||
record[item.name] = item.value;
|
||||
});
|
||||
model.$setViewValue(record ? angular.toJson(record) : null);
|
||||
}, true);
|
||||
}
|
||||
|
||||
model.$render = function () {
|
||||
var value = model.$viewValue;
|
||||
if (value) {
|
||||
value = angular.fromJson(value);
|
||||
} else {
|
||||
value = {};
|
||||
}
|
||||
scope.items = _.map(_.keys(value), function (name) {
|
||||
return { name: name, value: value[name] || '' };
|
||||
});
|
||||
doWatch();
|
||||
};
|
||||
},
|
||||
template_readonly:
|
||||
"<div class='json-editor'>" +
|
||||
"<table class='form-layout'>" +
|
||||
"<tr ng-repeat='(i, item) in items'>" +
|
||||
"<td class='form-label'>" +
|
||||
"<strong class='display-text'>{{item.name}}</strong>:" +
|
||||
"</td>" +
|
||||
"<td class='form-item'>" +
|
||||
"<span class='display-text'>{{item.value}}</span>" +
|
||||
"</td>" +
|
||||
"</tr>" +
|
||||
"</table>" +
|
||||
"</div>",
|
||||
template_editable:
|
||||
"<div class='json-editor'>" +
|
||||
"<table class='form-layout'>" +
|
||||
"<tr ng-repeat='(i, item) in items'>" +
|
||||
"<td class='form-item'><span class='form-item-container'>" +
|
||||
"<input type='text' placeholder='{{placeHolderKey}}' ng-model='item.name'></span>" +
|
||||
"</td>" +
|
||||
"<td class='form-item'><span class='form-item-container'>" +
|
||||
"<input type='text' placeholder='{{placeHolderVal}}' ng-model='item.value'></span>" +
|
||||
"</td>" +
|
||||
"<td><a href='' ng-click='onRemove(i)'><i class='fa fa-minus'></i></a></td>" +
|
||||
"</tr>" +
|
||||
"</table>" +
|
||||
"<a href='' ng-click='onAdd()'><i class='fa fa-plus'></i></a>" +
|
||||
"</div>"
|
||||
});
|
||||
|
||||
ui.formInput('JsonRefSelect', {
|
||||
|
||||
css: 'multi-object-select',
|
||||
|
||||
controller: ['$scope', 'ViewService', function($scope, ViewService) {
|
||||
|
||||
$scope.createElement = function(id, name, selectionList) {
|
||||
|
||||
var elemGroup = $('<div ui-group ui-table-layout cols="2" x-widths="150,*"></div>');
|
||||
var elemSelect = $('<input ui-select showTitle="false">')
|
||||
.attr("name", name + "$model")
|
||||
.attr("x-for-widget", id)
|
||||
.attr("ng-model", "record." + name + ".model");
|
||||
|
||||
var elemSelects = $('<div></div>').attr('ng-switch', "record." + name + ".model");
|
||||
var elemItems = _.map(selectionList, function(s) {
|
||||
return $('<input ui-json-ref-item ng-switch-when="' + s.value +'">')
|
||||
.attr('ng-model', 'record.' + name)
|
||||
.attr('name', name)
|
||||
.attr('x-target', s.value);
|
||||
});
|
||||
|
||||
elemGroup
|
||||
.append($('<div></div>').append(elemSelect))
|
||||
.append(elemSelects.append(elemItems));
|
||||
|
||||
return ViewService.compile(elemGroup)($scope);
|
||||
};
|
||||
}],
|
||||
|
||||
link: function(scope, element, attrs, model) {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
var name = scope.field.name;
|
||||
var selectionList = scope.field.selectionList;
|
||||
|
||||
scope.fieldsCache = {};
|
||||
|
||||
scope.refFireEvent = function (name) {
|
||||
var handler = scope.$events[name];
|
||||
if (handler) {
|
||||
return handler();
|
||||
}
|
||||
};
|
||||
|
||||
var elem = scope.createElement(element.attr('id'), name, selectionList);
|
||||
setTimeout(function() {
|
||||
element.append(elem);
|
||||
});
|
||||
|
||||
scope.$watch("record." + name + ".model", function jsonModelWatch(value, old) {
|
||||
if (value === old || old === undefined) return;
|
||||
if (scope.record && scope.record[name]) {
|
||||
scope.record[name] = _.pick(scope.record[name], 'model');
|
||||
if (!scope.record[name].model) {
|
||||
delete scope.record[name];
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
template_editable: null,
|
||||
template_readonly: null
|
||||
});
|
||||
|
||||
ui.formInput('JsonRefItem', 'ManyToOne', {
|
||||
|
||||
showTitle: false,
|
||||
|
||||
link: function(scope, element, attrs, model) {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
if (scope.field.targetName) {
|
||||
return this._link.apply(this, arguments);
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var target = element.attr('x-target');
|
||||
var data = (_.findWhere(scope.$parent.field.selectionList, {value: target})||{}).data || {};
|
||||
|
||||
function doLink(fields) {
|
||||
var name = false,
|
||||
search = [];
|
||||
|
||||
_.each(fields, function(f) {
|
||||
if (f.nameColumn) name = f.name;
|
||||
if (f.name === "name") search.push("name");
|
||||
if (f.name === "code") search.push("code");
|
||||
});
|
||||
|
||||
if (!name && _.contains(search, "name")) {
|
||||
name = "name";
|
||||
}
|
||||
|
||||
_.extend(scope.field, {
|
||||
target: scope._model,
|
||||
targetName: name,
|
||||
targetSearch: search,
|
||||
domain: data.domain
|
||||
});
|
||||
|
||||
self._link(scope, element, attrs, model);
|
||||
}
|
||||
|
||||
if (scope.fieldsCache[scope._model]) {
|
||||
doLink(scope.fieldsCache[scope._model]);
|
||||
} else {
|
||||
scope.loadFields().success(function (fields) {
|
||||
scope.fieldsCache[scope._model] = fields;
|
||||
doLink(fields);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_link: function(scope, element, attrs, model) {
|
||||
var name = element.attr('name');
|
||||
|
||||
scope.getValue = function () {
|
||||
return scope.record[name];
|
||||
};
|
||||
|
||||
var __setValue = scope.setValue;
|
||||
|
||||
scope.setValue = function (value) {
|
||||
var val = _.pick(scope.record[name], 'model');
|
||||
val = _.extend(val, value);
|
||||
__setValue.call(scope, val);
|
||||
};
|
||||
|
||||
function doSelect() {
|
||||
var value = (scope.record || {})[name];
|
||||
scope.select(value);
|
||||
}
|
||||
|
||||
scope.$watch("record", doSelect);
|
||||
}
|
||||
});
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user