
structr.js.entities.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of structr-ui Show documentation
Show all versions of structr-ui Show documentation
Structr is an open source framework based on the popular Neo4j graph database.
The newest version!
/*
* Copyright (C) 2010-2016 Structr GmbH
*
* This file is part of Structr .
*
* Structr is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* Structr 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 Structr. If not, see .
*/
var buttonClicked;
var activeElements = {};
var activeQueryTabPrefix = 'structrActiveQueryTab_' + port;
var activeEditTabPrefix = 'structrActiveEditTab_' + port;
var _Entities = {
numberAttrs: ['position', 'size'],
hiddenAttrs: ['base'], //'deleted', 'ownerId', 'owner', 'group', 'categories', 'tag', 'createdBy', 'visibilityStartDate', 'visibilityEndDate', 'parentFolder', 'url', 'path', 'elements', 'components', 'paths', 'parents'],
readOnlyAttrs: ['lastModifiedDate', 'createdDate', 'createdBy', 'id', 'checksum', 'size', 'version', 'relativeFilePath'],
changeBooleanAttribute: function(attrElement, value, activeLabel, inactiveLabel) {
_Logger.log(_LogType.ENTITIES, 'Change boolean attribute ', attrElement, ' to ', value);
if (value === true) {
attrElement.removeClass('inactive').addClass('active').prop('checked', true).html('
' + (activeLabel ? ' ' + activeLabel : ''));
} else {
attrElement.removeClass('active').addClass('inactive').prop('checked', false).text((inactiveLabel ? inactiveLabel : '-'));
}
},
reloadChildren: function(id) {
var el = Structr.node(id);
_Logger.log(_LogType.ENTITIES, 'reloadChildren', el);
$(el).children('.node').remove();
_Entities.resetMouseOverState(el);
Command.children(id);
},
deleteNode: function(button, entity, rec, callback) {
buttonClicked = button;
if (isDisabled(button))
return;
Structr.confirmation('Delete ' + entity.type + ' \'' + entity.name + '\' [' + entity.id + ']' + (rec ? ' recursively' : '') + '?
',
function() {
Command.deleteNode(entity.id, rec);
$.unblockUI({
fadeOut: 25
});
if (callback) {
callback(entity);
}
});
},
showSyncDialog: function(source, target) {
Structr.dialog('Sync between ' + source.id + ' and ' + target.id, function() {
return true;
}, function() {
return true;
});
dialog.append('');
dialog.append('');
dialog.append('');
$('input[name=syncMode]:radio', dialog).on('change', function() {
Command.setSyncMode(source.id, target.id, $(this).val());
});
},
dataBindingDialog: function(entity, el) {
el.append('
');
var t = $('.props', el);
// General
_Entities.appendRowWithInputField(entity, t, 'data-structr-id', 'Element ID (set to ${this.id})');
_Entities.appendRowWithInputField(entity, t, 'data-structr-attr', 'Attribute Key (if set, render input field in edit mode)');
_Entities.appendRowWithInputField(entity, t, 'data-structr-type', 'Data type (e.g. Date, Boolean; default: String)');
_Entities.appendRowWithInputField(entity, t, 'data-structr-placeholder', 'Placeholder text in edit mode');
_Entities.appendRowWithInputField(entity, t, 'data-structr-custom-options-query', 'Custom REST query for value options');
_Entities.appendRowWithInputField(entity, t, 'data-structr-options-key', 'Attribute key used to display option labels (default: name)');
_Entities.appendRowWithInputField(entity, t, 'data-structr-raw-value', 'Raw value (unformatted value for Date or Number fields)');
_Entities.appendRowWithInputField(entity, t, 'data-structr-hide', 'Hide [edit|non-edit|edit,non-edit]');
_Entities.appendRowWithInputField(entity, t, 'data-structr-edit-class', 'Custom CSS class in edit mode');
if (entity.type === 'Button' || entity.type === 'A') {
// Buttons
_Entities.appendRowWithInputField(entity, t, 'data-structr-action', 'Action [create:<Type>|delete:<Type>|edit|login|logout]');
_Entities.appendRowWithInputField(entity, t, 'data-structr-attributes', 'Attributes (for create, edit, login or registration actions)');
t.append('Reload ');
_Entities.appendBooleanSwitch($('#reload', t), entity, 'data-structr-reload', '', 'If active, the page will refresh after a successfull action.');
// Confirm action?
t.append('Confirm action? ');
_Entities.appendBooleanSwitch($('#confirmOnDel', t), entity, 'data-structr-confirm', '', 'If active, a user has to confirm the action.');
_Entities.appendRowWithInputField(entity, t, 'data-structr-return', 'Return URI after successful action');
t.append('Append ID on create ');
_Entities.appendBooleanSwitch($('#append-id', t), entity, 'data-structr-append-id', '', 'On create, append ID of first created object to the return URI.');
} else if (entity.type === 'Input' || entity.type === 'Select' || entity.type === 'Textarea') {
// Input fields
_Entities.appendRowWithInputField(entity, t, 'data-structr-name', 'Field name (for create action)');
}
// _Entities.appendBooleanSwitch(el, entity, 'hideOnEdit', 'Hide in edit mode', 'If active, this node will not be visible in edit mode.');
// _Entities.appendBooleanSwitch(el, entity, 'hideOnNonEdit', 'Hide in non-edit mode', 'If active, this node will not be visible in default (non-edit) mode.');
//_Entities.appendInput(dialog, entity, 'partialUpdateKey', 'Types to trigger partial update', '');
},
appendRowWithInputField: function(entity, el, key, label) {
el.append('' + label + ' 
');
var inp = $('[name="' + key + '"]', el);
_Entities.activateInput(inp, entity.id);
var nullIcon = $('#null_' + key, el);
nullIcon.on('click', function() {
Command.setProperty(entity.id, key, null, false, function() {
inp.val(null);
blinkGreen(inp);
dialogMsg.html('Property "' + key + '" was set to null.');
$('.infoBox', dialogMsg).delay(2000).fadeOut(1000);
});
});
},
queryDialog: function(entity, el) {
el.append('
');
var t = $('.props', el);
t.append('Query auto-limit ');
t.append('Hide in index mode ');
t.append('Hide in details mode ');
_Entities.appendBooleanSwitch($('#queryAutoLimit', t), entity, 'renderDetails', ['Query is limited', 'Query is not limited'], 'Limit result to the object with the ID the URL ends with.');
_Entities.appendBooleanSwitch($('#hideIndexMode', t), entity, 'hideOnIndex', ['Hidden in index mode', 'Visible in index mode'], 'if URL does not end with an ID');
_Entities.appendBooleanSwitch($('#hideDetailsMode', t), entity, 'hideOnDetail', ['Hidden in details mode', 'Visible in details mode'], 'if URL ends with an ID.');
el.append('- REST Query
- Cypher Query
- XPath Query
- Function Query
'
+ '');
_Entities.appendTextarea($('#content-tab-rest'), entity, 'restQuery', 'REST Query', '');
_Entities.appendTextarea($('#content-tab-cypher'), entity, 'cypherQuery', 'Cypher Query', '');
_Entities.appendTextarea($('#content-tab-xpath'), entity, 'xpathQuery', 'XPath Query', '');
_Entities.appendTextarea($('#content-tab-function'), entity, 'functionQuery', 'Function Query', '');
_Entities.appendInput(el, entity, 'dataKey', 'Data Key', 'The data key is either a word to reference result objects, or it can be the name of a collection property of the result object.
' +
'You can access result objects or the objects of the collection using ${<dataKey>.<propertyKey>}');
_Entities.activateTabs(entity.id, '#data-tabs', '#content-tab-rest');
//_Entities.appendInput(dialog, entity, 'partialUpdateKey', 'Types to trigger partial update', '');
},
activateTabs: function(nodeId, elId, activeId) {
var el = $(elId);
var tabs = $('li', el);
$.each(tabs, function(i, tab) {
$(tab).on('click', function() {
var tab = $(this);
tabs.removeClass('active');
tab.addClass('active');
el.children('div').hide();
var id = tab.prop('id').substring(4);
LSWrapper.setItem(activeQueryTabPrefix + '_' + nodeId, id);
var content = $('#content-tab-' + id);
content.show();
});
});
var id = LSWrapper.getItem(activeQueryTabPrefix + '_' + nodeId) || activeId.substring(13);
var tab = $('#tab-' + id);
if (!tab.hasClass('active')) {
tab.click();
}
},
editSource: function(entity) {
Structr.dialog('Edit source of "' + (entity.name ? entity.name : entity.id) + '"', function () {
_Logger.log(_LogType.ENTITIES, 'Element source saved');
}, function () {
_Logger.log(_LogType.ENTITIES, 'cancelled');
});
// Get content in widget mode
var url = viewRootUrl + entity.id + '?edit=3', contentType = 'text/html';
$.ajax({
url: url,
//async: false,
contentType: contentType,
success: function(data) {
text = data;
text = text.replace(/]*>/, '');
var startTag = text.replace(/(<[^>]*>)([^]*)(<\/[^>]*>)/, '$1').replace(/^\s+|\s+$/g, '');
var innerText = text.replace(/(<[^>]*>)([^]*)(<\/[^>]*>)/, '$2').replace(/^\s+|\s+$/g, '');
var endTag = text.replace(/(<[^>]*>)([^]*)(<\/[^>]*>)/, '$3').replace(/^\s+|\s+$/g, '');
text = innerText;
dialog.append('');
var contentBox = $('.editor', dialog);
var lineWrapping = LSWrapper.getItem(lineWrappingKey);
// Intitialize editor
editor = CodeMirror(contentBox.get(0), {
value: unescapeTags(innerText),
mode: contentType,
lineNumbers: true,
lineWrapping: lineWrapping,
indentUnit: 4,
tabSize:4,
indentWithTabs: true
});
$('.CodeMirror-scroll').prepend('');
$('.CodeMirror-scroll').append('');
$('.starttag', dialog).append(escapeTags(startTag.replace(/\sdata-structr-hash=".{32}"/, "")));
$('.endtag', dialog).append(escapeTags(endTag));
editor.id = entity.id;
dialogBtn.append('');
dialogBtn.append('');
dialogSaveButton = $('#saveFile', dialogBtn);
saveAndClose = $('#saveAndClose', dialogBtn);
editor.on('scroll', function() {
_Entities.hideDataHashAttribute(editor);
});
editor.on('change', function(cm, change) {
//text1 = $(contentNode).children('.content_').text();
text2 = editor.getValue();
//console.log(text, text2, text === text2);
if (text === text2) {
dialogSaveButton.prop("disabled", true).addClass('disabled');
saveAndClose.prop("disabled", true).addClass('disabled');
} else {
dialogSaveButton.prop("disabled", false).removeClass('disabled');
saveAndClose.prop("disabled", false).removeClass('disabled');
}
_Entities.hideDataHashAttribute(editor);
});
dialogSaveButton.on('click', function(e) {
e.stopPropagation();
text2 = editor.getValue();
//console.log(text, text2, text === text2);
if (text === text2) {
dialogSaveButton.prop("disabled", true).addClass('disabled');
saveAndClose.prop("disabled", true).addClass('disabled');
} else {
dialogSaveButton.prop("disabled", false).removeClass('disabled');
saveAndClose.prop("disabled", false).removeClass('disabled');
}
Command.saveNode(startTag + editor.getValue() + endTag, entity.id, function() {
$.ajax({
url: url,
contentType: contentType,
success: function(data) {
text = unescapeTags(data).replace(/]*>/, '');
text = text.replace(/(<[^>]*>)([^]*)(<\/[^>]*>)/, '$2').replace(/^\s+|\s+$/g, '');
editor.setValue(text);
dialogSaveButton.prop("disabled", true).addClass('disabled');
saveAndClose.prop("disabled", true).addClass('disabled');
dialogMsg.html('Node source saved and DOM tree rebuilt.');
$('.infoBox', dialogMsg).delay(2000).fadeOut(200);
if (_Entities.isExpanded(Structr.node(entity.id))) {
$('.expand_icon', Structr.node(entity.id)).click().click();
}
}
});
});
});
saveAndClose.on('click', function(e) {
e.stopPropagation();
dialogSaveButton.click();
setTimeout(function() {
dialogSaveButton.remove();
saveAndClose.remove();
dialogCancelButton.click();
}, 500);
});
dialogMeta.append(' ');
$('#lineWrapping').on('change', function() {
var inp = $(this);
if (inp.is(':checked')) {
LSWrapper.setItem(lineWrappingKey, "1");
editor.setOption('lineWrapping', true);
} else {
LSWrapper.removeItem(lineWrappingKey);
editor.setOption('lineWrapping', false);
}
editor.refresh();
});
Structr.resize();
_Entities.hideDataHashAttribute(editor);
},
error: function(xhr, statusText, error) {
console.log(xhr, statusText, error);
}
});
},
hideDataHashAttribute: function(editor) {
var sc = editor.getSearchCursor(/\sdata-structr-hash=".{32}"/);
while (sc.findNext()) {
editor.markText(sc.from(), sc.to(), {className: 'data-structr-hash', collapsed: true, inclusiveLeft: true});
}
},
showProperties: function(obj, activeViewOverride) {
Command.get(obj.id, function (entity) {
var views, activeView = 'ui';
var isRelationship = false;
var tabTexts = [];
if (activeViewOverride) {
activeView = activeViewOverride;
}
if (entity.hasOwnProperty('relType')) {
isRelationship = true;
views = ['ui'];//, 'sourceNode', 'targetNode'];
tabTexts.ui = 'Relationship Properties';
tabTexts.sourceNode = 'Source Node Properties';
tabTexts.targetNode = 'Target Node Properties';
Structr.dialog('Edit Properties of ' + (entity.type ? entity.type : '') + (isRelationship ? ' relationship ' : ' node ') + (entity.name ? entity.name : entity.id), function() {
return true;
}, function() {
return true;
});
var tabsdiv = dialogHead.append('');
var mainTabs = tabsdiv.append('
');
var contentEl = dialog.append('');
_Entities.appendViews(entity, views, tabTexts, mainTabs, contentEl, activeView);
} else {
views = ['ui', 'in', 'out'];
var hasHtmlAttributes = entity.isDOMNode;
if (hasHtmlAttributes && !entity.isContent) {
views.unshift('_html_');
//console.log(lastMenuEntry)
if (lastMenuEntry === 'pages') {
activeView = '_html_';
}
}
tabTexts._html_ = 'HTML Attributes';
tabTexts.ui = 'Node Properties';
tabTexts.in = 'Incoming Relationships';
tabTexts.out = 'Outgoing Relationships';
Structr.dialog('Edit Properties of ' + (entity.type ? entity.type : '') + (isRelationship ? ' relationship ' : ' node ') + (entity.name ? entity.name : entity.id), function() {
return true;
}, function() {
return true;
});
var tabsdiv = dialogHead.append('');
var mainTabs = tabsdiv.append('
');
var contentEl = dialog.append('');
if (hasHtmlAttributes) {
_Entities.appendPropTab(entity, mainTabs, contentEl, 'query', 'Query and Data Binding', true, function(c) {
_Entities.queryDialog(entity, c);
});
_Entities.appendPropTab(entity, mainTabs, contentEl, 'editBinding', 'Edit Mode Binding', false, function(c) {
_Entities.dataBindingDialog(entity, c);
});
}
_Entities.appendViews(entity, views, tabTexts, mainTabs, contentEl, activeView, activeViewOverride);
}
Structr.resize();
});
},
appendPropTab: function(entity, tabsEl, contentEl, name, label, active, callback) {
var ul = tabsEl.children('ul');
ul.append('' + label + ' ');
var tab = $('#tab-' + name + '');
if (active) {
tab.addClass('active');
}
tab.on('click', function(e) {
e.stopPropagation();
var self = $(this);
$('.propTabContent').hide();
$('li', ul).removeClass('active');
contentEl.append('');
$('#tabView-' + name).show();
self.addClass('active');
LSWrapper.setItem(activeEditTabPrefix + '_' + entity.id, name);
});
contentEl.append('');
var content = $('#tabView-' + name);
if (active) {
content.show();
}
if (callback) {
callback(content);
}
return content;
},
appendViews: function(entity, views, texts, tabsEl, contentEl, activeView, activeViewOverride) {
var ul = tabsEl.children('ul');
$(views).each(function(i, view) {
var tabText = texts[view];
ul.append('' + tabText + ' ');
contentEl.append('');
var tab = $('#tab-' + view);
tab.on('click', function(e) {
e.stopPropagation();
var self = $(this);
contentEl.children('div').hide();
$('li', ul).removeClass('active');
self.addClass('active');
var tabView = $('#tabView-' + view);
fastRemoveAllChildren(tabView[0]);
tabView.show();
LSWrapper.setItem(activeEditTabPrefix + '_' + entity.id, view);
$.ajax({
url: rootUrl + '_schema/' + entity.type + '/ui',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function(data) {
var typeInfo = {};
$(data.result).each(function(i, prop) {
typeInfo[prop.jsonName] = prop;
});
_Entities.listProperties(entity, view, tabView, typeInfo);
}
});
});
});
activeView = activeViewOverride || LSWrapper.getItem(activeEditTabPrefix + '_' + entity.id) || activeView;
$('#tab-' + activeView).click();
},
listProperties: function (entity, view, tabView, typeInfo) {
var null_prefix = 'null_attr_';
$.ajax({
url: rootUrl + entity.id + (view ? '/' + view : '') + '?pageSize=10', // TODO: Implement paging or scroll-into-view here
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function(data) {
// Default: Edit node id
var id = entity.id;
// ID of graph object to edit
$(data.result).each(function(i, res) {
// reset id for each object group
id = entity.id;
var keys = Object.keys(res);
tabView.append('
');
var props = $('.props.' + view + '.' + res['id'] + '_', tabView);
var focusAttr = 'class';
if (view === '_html_') {
keys.sort();
}
$(keys).each(function(i, key) {
if (view === '_html_') {
var display = false;
_Elements.mostUsedAttrs.forEach(function(mostUsed) {
if (isIn(entity.tag, mostUsed.elements) && isIn(key.substring(6), mostUsed.attrs)) {
display = true;
focusAttr = mostUsed.focus ? mostUsed.focus : focusAttr;
}
});
// Always show non-empty, non 'data-structr-' attributes
if (res[key] !== null && key.indexOf('data-structr-') !== 0) {
display = true;
}
if (display || key === '_html_class' || key === '_html_id') {
props.append('' + key.replace(view, '') + ' '
+ '' + formatValueInputField(key, res[key]) + ' 
');
} else if (key !== 'id') {
props.append('' + key.replace(view, '') + ' '
+ '' + formatValueInputField(key, res[key]) + ' 
');
}
} else if (view === 'in' || view === 'out') {
if (key === 'id') {
// set ID to rel ID
id = res[key];
}
props.append('' + key + ' ' + formatValueInputField(key, res[key]) + ' 
');
} else {
props.append('' + formatKey(key) + ' 
');
var cell = $('.value.' + key + '_', props);
if (!typeInfo[key]) {
cell.append(formatValueInputField(key, res[key], isPassword, isReadOnly));
} else {
var type = typeInfo[key].type;
var isHidden = isIn(key, _Entities.hiddenAttrs);
var isReadOnly = isIn(key, _Entities.readOnlyAttrs) || (typeInfo[key].readOnly);
var isSystem = typeInfo[key].system;
if (type) {
var isBoolean = (type === 'Boolean'); //typeInfo[key].className === 'org.structr.core.property.BooleanProperty'; //isIn(key, _Entities.booleanAttrs);
var isDate = (type === 'Date'); //typeInfo[key].className === 'org.structr.core.property.ISO8601DateProperty'; //isIn(key, _Entities.dateAttrs);
var isPassword = (typeInfo[key].className === 'org.structr.core.property.PasswordProperty');
var isRelated = typeInfo[key].relatedType;
}
if (!key.startsWith('_html_') && !isHidden) {
if (isBoolean) {
cell.removeClass('value').append('');
var checkbox = $(props.find('input[type="checkbox"].' + key + '_'));
Command.getProperty(id, key, function(val) {
if (val) {
checkbox.prop('checked', true);
}
if ((!isReadOnly || isAdmin) && !isSystem) {
checkbox.on('change', function() {
var checked = checkbox.prop('checked');
_Entities.setProperty(id, key, checked, false, function(newVal) {
if (val !== newVal) {
blinkGreen(cell);
}
checkbox.prop('checked', newVal);
val = newVal;
});
});
} else {
checkbox.prop('disabled', 'disabled');
checkbox.addClass('readOnly');
checkbox.addClass('disabled');
}
});
} else if (isDate && !isReadOnly) {
if (!res[key] || res[key] === 'null') {
res[key] = '';
}
cell.append('');
var dateField = $(props.find('.dateField'));
var dateTimePickerFormat = getDateTimePickerFormat(typeInfo[key].format);
dateField.datetimepicker({
dateFormat: dateTimePickerFormat.dateFormat,
timeFormat: dateTimePickerFormat.timeFormat,
separator: dateTimePickerFormat.separator
});
} else if (isRelated && res[key] && (res[key].constructor === Object || res[key].constructor === Array)) {
if (res[key] && res[key].constructor === Object) {
_Entities.appendRelatedNode(cell, props, id, key, res[key], function(nodeEl) {
$('.remove', nodeEl).on('click', function(e) {
e.preventDefault();
_Entities.setProperty(id, key, null, false, function(newVal) {
if (!newVal) {
blinkGreen(cell);
dialogMsg.html('Related node "' + displayName + '" was removed from property "' + key + '".');
$('.infoBox', dialogMsg).delay(2000).fadeOut(1000);
cell.empty();
} else {
blinkRed(cell);
}
});
return false;
});
});
} else if (res[key] && res[key].constructor === Array) {
res[key].forEach(function(node) {
_Entities.appendRelatedNode(cell, props, id, key, node, function(nodeEl) {
$('.remove', nodeEl).on('click', function(e) {
e.preventDefault();
Command.removeFromCollection(id, key, node.id, function() {
nodeEl.remove();
blinkGreen(cell);
});
return false;
});
});
});
}
} else {
cell.append(formatValueInputField(key, res[key], isPassword, isReadOnly));
}
}
}
}
var nullIcon = $('#' + null_prefix + key);
nullIcon.on('click', function() {
var key = $(this).prop('id').substring(null_prefix.length);
var input = $('.' + key + '_').find('input');
_Entities.setProperty(id, key, null, false, function(newVal) {
if (!newVal) {
blinkGreen(cell);
dialogMsg.html('Property "' + key + '" was set to null.');
$('.infoBox', dialogMsg).delay(2000).fadeOut(1000);
if (key === 'name') {
var entity = StructrModel.objects[id];
if (entity.type !== 'Template' && entity.type !== 'Content') {
entity.name = entity.tag ? entity.tag : '[' + entity.type + ']';
}
StructrModel.refresh(id);
}
if (isRelated) {
cell.empty();
}
} else {
blinkRed(input);
}
if (!isRelated) {
input.val(newVal);
}
});
});
});
props.append(' ');
$('.props tr td.value input', dialog).each(function(i, v) {
_Entities.activateInput(v, id);
});
if (view === '_html_') {
$('input[name="_html_' + focusAttr + '"]', props).focus();
tabView.append('');
$('.show-all', tabView).on('click', function() {
$('tr.hidden').toggle();
$(this).remove();
});
}
});
}
});
},
appendRelatedNode: function(cell, props, id, key, node, onDelete) {
var displayName = _Crud.displayName(node);
cell.append('' + fitStringToWidth(displayName, 80) + '
');
var nodeEl = $('#_' + node.id, props);
nodeEl.on('click', function(e) {
e.preventDefault();
_Entities.showProperties(node);
return false;
});
if (onDelete) {
return onDelete(nodeEl);
}
},
activateInput: function(el, id) {
var input = $(el);
var oldVal = input.val();
var relId = input.parent().attr('rel_id');
if (!input.hasClass('readonly') && !input.hasClass('newKey')) {
input.on('focus', function() {
input.addClass('active');
});
input.on('change', function() {
input.data('changed', true);
_Pages.reloadPreviews();
});
input.on('focusout', function() {
_Logger.log(_LogType.ENTITIES, 'relId', relId);
var objId = relId ? relId : id;
_Logger.log(_LogType.ENTITIES, 'set properties of obj', objId);
var keyInput = input.parent().parent().children('td').first().children('input');
_Logger.log(_LogType.ENTITIES, keyInput);
if (keyInput && keyInput.length) {
var newKey = keyInput.val();
var val = input.val();
// new key
_Logger.log(_LogType.ENTITIES, 'new key: Command.setProperty(', objId, newKey, val);
Command.setProperty(objId, newKey, val, false, function() {
blinkGreen(input);
dialogMsg.html('New property "' + newKey + '" was added and saved with value "' + val + '".');
$('.infoBox', dialogMsg).delay(2000).fadeOut(1000);
});
} else {
var key = input.prop('name');
var val = input.val();
var isPassword = input.prop('type') === 'password';
if (input.data('changed')) {
input.data('changed', false);
_Logger.log(_LogType.ENTITIES, 'existing key: Command.setProperty(', objId, key, val);
_Entities.setProperty(objId, key, val, false, function(newVal) {
if (isPassword || (newVal && newVal !== oldVal)) {
blinkGreen(input);
input.val(newVal);
dialogMsg.html('Updated property "' + key + '"' + (!isPassword ? ' with value "' + newVal + '".' : ''));
$('.infoBox', dialogMsg).delay(2000).fadeOut(200);
} else {
input.val(oldVal);
}
oldVal = newVal;
});
}
}
input.removeClass('active');
input.parent().children('.icon').each(function(i, img) {
$(img).remove();
});
});
}
},
setProperty: function(id, key, val, recursive, callback) {
Command.setProperty(id, key, val, recursive, function() {
Command.getProperty(id, key, callback);
});
},
appendAccessControlIcon: function(parent, entity) {
var protected = !entity.visibleToPublicUsers || !entity.visibleToAuthenticatedUsers;
var keyIcon = $('.key_icon', parent);
var newKeyIcon = '
';
if (!(keyIcon && keyIcon.length)) {
parent.append(newKeyIcon);
keyIcon = $('.key_icon', parent);
if (protected) {
keyIcon.show();
keyIcon.addClass('donthide');
}
_Entities.bindAccessControl(keyIcon, entity.id);
}
},
bindAccessControl: function(btn, id) {
btn.on('click', function(e) {
e.stopPropagation();
_Entities.showAccessControlDialog(id);
});
},
showAccessControlDialog: function(id) {
Structr.dialog('Access Control and Visibility', function() {
}, function() {
Command.get(id, function(entity) {
_Crud.refreshRow(id, entity, entity.type);
});
});
Command.get(id, function(entity) {
_Entities.appendSimpleSelection(dialogText, entity, 'users', 'Owner', 'owner.id');
dialogText.append('Visibility
');
//('');
if (entity.type === 'Template' || entity.isFolder || (lastMenuEntry === 'pages' && !(entity.isContent))) {
dialogText.append('Apply visibility switches recursively?
');
}
_Entities.appendBooleanSwitch(dialogText, entity, 'visibleToPublicUsers', ['Visible to public users', 'Not visible to public users'], 'Click to toggle visibility for users not logged-in', '#recursive');
_Entities.appendBooleanSwitch(dialogText, entity, 'visibleToAuthenticatedUsers', ['Visible to auth. users', 'Not visible to auth. users'], 'Click to toggle visibility to logged-in users', '#recursive');
dialogText.append('Access Rights
');
dialogText.append('Name Read Write Delete Access Control
');
$.ajax({
url: rootUrl + '/' + entity.id + '/in',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function(data) {
$(data.result).each(function(i, result) {
var permissions = {
'read': isIn('read', result.allowed),
'write': isIn('write', result.allowed),
'delete': isIn('delete', result.allowed),
'accessControl': isIn('accessControl', result.allowed)
};
var principalId = result.principalId;
if (principalId) {
Command.get(principalId, function(p) {
addPrincipal(entity, p, permissions);
});
}
});
}
});
var select = $('#newPrincipal');
select.chosen({width: '90%'});
var i = 0, n = 10000;
Command.getByType('Group', n, 1, 'name', 'asc', 'id,name', false, function(groups) {
groups.forEach(function(group) {
select.append('');
});
select.trigger("chosen:updated");
});
i = 0;
var al2 = Structr.loaderIcon(select.parent(), {float: 'right'});
Command.getByType('User', n, 1, 'name', 'asc', 'id,name', false, function(users) {
users.forEach(function(user) {
select.append('');
});
select.trigger("chosen:updated");
if (al2.length)
al2.remove();
});
select.on('change', function() {
var sel = $(this);
var pId = sel[0].value;
var rec = $('#recursive', dialogText).is(':checked');
Command.setPermission(entity.id, pId, 'grant', 'read', rec);
$('#new', tb).selectedIndex = 0;
Command.get(pId, function(p) {
addPrincipal(entity, p, {'read': true});
});
});
});
},
appendTextarea: function(el, entity, key, label, desc) {
if (!el || !entity) {
return false;
}
el.append('' + label + '
' + desc + '
');
el.append('');
var btn = $('.apply_' + key, el);
btn.on('click', function() {
Command.setProperty(entity.id, key, $('.' + key + '_', el).val(), false, function(obj) {
_Logger.log(_LogType.ENTITIES, key + ' successfully updated!', obj[key]);
blinkGreen(btn);
_Pages.reloadPreviews();
});
});
},
appendInput: function(el, entity, key, label, desc) {
if (!el || !entity) {
return false;
}
el.append('' + label + '
' + desc + '
');
var btn = $('.save_' + key, el);
btn.on('click', function() {
Command.setProperty(entity.id, key, $('.' + key + '_', el).val(), false, function(obj) {
_Logger.log(_LogType.ENTITIES, key + ' successfully updated!', obj[key]);
blinkGreen(btn);
_Pages.reloadPreviews();
});
});
},
appendBooleanSwitch: function(el, entity, key, label, desc, recElementId) {
if (!el || !entity) {
return false;
}
el.append('' + desc + '');
var sw = $('.' + key + '_', el);
_Entities.changeBooleanAttribute(sw, entity[key], label[0], label[1]);
sw.on('click', function(e) {
e.stopPropagation();
Command.setProperty(entity.id, key, sw.hasClass('inactive'), $(recElementId, el).is(':checked'), function(obj) {
if (obj.id !== entity.id) {
return false;
}
_Entities.changeBooleanAttribute(sw, obj[key], label[0], label[1]);
blinkGreen(sw);
return true;
});
});
},
appendSimpleSelection: function(el, entity, type, title, key) {
var subKey;
if (key.contains('.')) {
subKey = key.substring(key.indexOf('.') + 1, key.length);
key = key.substring(0, key.indexOf('.'));
}
el.append('' + title + '
');
var element = $('.' + key + 'Box', el);
element.append('');
var selectElement = $('.' + key + 'Select');
selectElement.append('');
selectElement.css({'width': '400px'}).chosen();
var id = (subKey && entity[key] ? entity[key][subKey] : entity[key]);
var al = Structr.loaderIcon(el, {position: 'absolute', left: '416px', top: '32px'});
var n = 10000;
Command.getByType(type, n, 1, 'name', 'asc', 'id,name', false, function (results) {
results.forEach(function(result) {
var selected = (id === result.id ? 'selected' : '');
selectElement.append('');
});
selectElement.trigger("chosen:updated");
if (al.length)
al.remove();
});
selectElement.on('change', function() {
var value = selectElement.val();
if (subKey) {
entity[key][subKey] = value;
}
Command.setProperty(entity.id, key, value, false, function() {
blinkGreen($('.' + key + 'Select_chosen .chosen-single'));
});
});
},
appendEditSourceIcon: function(parent, entity) {
if (entity.tag === 'html' || entity.tag === 'body' || entity.tag === 'head'
|| entity.tag === 'title' || entity.tag === 'script'
|| entity.tag === 'input' || entity.tag === 'label' || entity.tag === 'button' || entity.tag === 'textarea'
|| entity.tag === 'link' || entity.tag === 'meta' || entity.tag === 'noscript'
|| entity.tag === 'tbody' || entity.tag === 'thead' || entity.tag === 'tr' || entity.tag === 'td'
|| entity.tag === 'caption' || entity.tag === 'colgroup' || entity.tag === 'tfoot' || entity.tag === 'col') {
return;
}
var editIcon = $('.edit_icon', parent);
if (!(editIcon && editIcon.length)) {
parent.append('
');
editIcon = $('.edit_icon', parent);
}
editIcon.on('click', function(e) {
e.stopPropagation();
_Logger.log(_LogType.ENTITIES, 'editSource', entity);
_Entities.editSource(entity);
});
},
appendEditPropertiesIcon: function(parent, entity, visible) {
var editIcon = $('.edit_props_icon', parent);
if (!(editIcon && editIcon.length)) {
parent.append('
');
editIcon = $('.edit_props_icon', parent);
}
editIcon.on('click', function(e) {
e.stopPropagation();
_Logger.log(_LogType.ENTITIES, 'showProperties', entity);
_Entities.showProperties(entity);
});
if (visible) {
editIcon.css({
visibility: 'visible',
display: 'inline-block'
});
}
return editIcon;
},
appendCollapseChildrenIcon: function(parent, entity, visible) {
var collapseChildrenIcon = $('.collapse_children_icon', parent);
if (!(collapseChildrenIcon && collapseChildrenIcon.length)) {
parent.append('
');
collapseChildrenIcon = $('.collapse_children_icon', parent);
}
collapseChildrenIcon.on('click', function(e) {
});
if (visible) {
collapseChildrenIcon.css({
visibility: 'visible',
display: 'inline-block'
});
}
return collapseChildrenIcon;
},
appendDataIcon: function(parent, entity) {
var dataIcon = $('.data_icon', parent);
if (!(dataIcon && dataIcon.length)) {
parent.append('
');
dataIcon = $('.data_icon', parent);
}
dataIcon.on('click', function(e) {
e.stopPropagation();
_Logger.log(_LogType.ENTITIES, 'showDataDialog', entity);
_Entities.showDataDialog(entity);
});
},
appendExpandIcon: function(el, entity, hasChildren, expand) {
_Logger.log(_LogType.ENTITIES, '_Entities.appendExpandIcon', el, entity, hasChildren, expand);
var button = $(el.children('.expand_icon').first());
if (button && button.length) {
_Logger.log(_LogType.ENTITIES, 'Expand icon already existing', el, button);
return;
}
if (hasChildren) {
_Logger.log(_LogType.ENTITIES, 'appendExpandIcon hasChildren?', hasChildren, 'expand?', expand);
var typeIcon = $(el.children('.typeIcon').first());
var icon = expand ? Structr.expanded_icon : Structr.expand_icon;
var displayName = getElementDisplayName(entity);
typeIcon.css({
paddingRight: 0 + 'px'
}).after('
');
$(el).on('click', function(e) {
e.stopPropagation();
_Entities.toggleElement(this);
});
button = $(el.children('.expand_icon').first());
if (button) {
button.on('click', function(e) {
e.stopPropagation();
_Entities.toggleElement($(this).parent('.node'));
});
// Prevent expand icon from being draggable
button.on('mousedown', function(e) {
e.stopPropagation();
});
if (expand) {
_Entities.ensureExpanded(el);
}
}
} else {
el.children('.typeIcon').css({
paddingRight: 11 + 'px'
});
}
},
removeExpandIcon: function(el) {
if (!el)
return;
_Logger.log(_LogType.ENTITIES, 'removeExpandIcon', el);
var button = $(el.children('.expand_icon').first());
// unregister click handlers
$(el).off('click');
$(button).off('click');
button.remove();
el.children('.typeIcon').css({
paddingRight: 11 + 'px'
});
},
makeSelectable: function(el) {
var node = $(el).closest('.node');
if (!node || !node.children) {
return;
}
node.on('click', function() {
$(this).toggleClass('selected');
});
},
setMouseOver: function(el, allowClick, syncedNodes) {
var node = $(el).closest('.node');
if (!node || !node.children) {
return;
}
if (!allowClick) {
node.on('click', function(e) {
e.stopPropagation();
return false;
});
}
node.children('b.name_').on('click', function(e) {
e.stopPropagation();
_Entities.makeNameEditable(node);
});
var nodeId = Structr.getId(el), isComponent;
if (nodeId === undefined) {
nodeId = Structr.getComponentId(el);
if (nodeId) {
isComponent = true;
} else {
nodeId = Structr.getActiveElementId(el);
}
}
node.on({
mouseover: function(e) {
e.stopPropagation();
var self = $(this);
$('#componentId_' + nodeId).addClass('nodeHover');
if (isComponent) {
$('#id_' + nodeId).addClass('nodeHover');
}
if (syncedNodes && syncedNodes.length) {
syncedNodes.forEach(function(s) {
$('#id_' + s).addClass('nodeHover');
$('#componentId_' + s).addClass('nodeHover');
});
}
var page = $(el).closest('.page');
if (page.length) {
try {
$('#preview_' + Structr.getId(page)).contents().find('[data-structr-id=' + nodeId + ']').addClass('nodeHover');
} catch (e) {}
}
self.addClass('nodeHover').children('img.button').show().css('display', 'inline-block');
self.children('.icons').children('img.button').show();
},
mouseout: function(e) {
e.stopPropagation();
$('#componentId_' + nodeId).removeClass('nodeHover');
if (isComponent) {
$('#id_' + nodeId).removeClass('nodeHover');
}
if (syncedNodes && syncedNodes.length) {
syncedNodes.forEach(function(s) {
$('#id_' + s).removeClass('nodeHover');
$('#componentId_' + s).removeClass('nodeHover');
});
}
_Entities.resetMouseOverState(this);
}
});
},
resetMouseOverState: function(element) {
var el = $(element);
var node = el.closest('.node');
if (node) {
node.removeClass('nodeHover');
node.find('img.button').not('.donthide').hide().css('display', 'none');
}
var page = node.closest('.page');
if (page.length) {
//$('#preview_' + Structr.getId(page)).contents().find('[data-structr-id=' + Structr.getId(node) + ']').removeClass('nodeHover');
try {
$('#preview_' + Structr.getId(page)).contents().find('[data-structr-id]').removeClass('nodeHover');
} catch (e) {}
}
},
isExpanded: function(element) {
var b = $(element).children('.expand_icon').first(), src = b.prop('src');
if (!b || !src) {
return false;
}
return src.endsWith('icon/tree_arrow_down.png');
},
ensureExpanded: function(element, callback) {
if (!element) {
return;
}
var el = $(element);
var id = Structr.getId(el);
if (!id) {
return;
}
addExpandedNode(id);
if (_Entities.isExpanded(element)) {
return;
} else {
_Logger.log(_LogType.ENTITIES, 'ensureExpanded: fetch children', el);
Command.children(id, callback);
var displayName = getElementDisplayName(Structr.entity(id));
el.children('.expand_icon').first().prop('src', 'icon/tree_arrow_down.png')
.prop('alt', 'Collapse ' + displayName)
.prop('title', 'Collapse ' + displayName);
}
},
expandAll: function(ids) {
if (!ids || ids.length === 0) {
return;
}
ids.forEach(function(id) {
var el = Structr.node(id);
if (el) {
$('.nodeSelected').removeClass('nodeSelected');
el.addClass('nodeSelected');
}
_Entities.ensureExpanded(el, function(childNodes) {
if (childNodes && childNodes.length) {
var childNode = childNodes[0];
var i = ids.indexOf(childNode.id);
if (i > 1) {
ids.slice(i - 1, i);
}
_Entities.expandAll(ids);
}
});
});
},
toggleElement: function(element, expanded) {
var el = $(element);
var id = Structr.getId(el) || Structr.getComponentId(el);
_Logger.log(_LogType.ENTITIES, 'toggleElement: ', el, id);
var b = el.children('.expand_icon').first();
var displayName = getElementDisplayName(Structr.entity(id));
if (_Entities.isExpanded(element)) {
$.each(el.children('.node'), function(i, child) {
$(child).remove();
});
b.prop('src', 'icon/tree_arrow_right.png')
.prop('alt', 'Expand ' + displayName)
.prop('title', 'Expand ' + displayName);
removeExpandedNode(id);
} else {
if (!expanded) {
_Logger.log(_LogType.ENTITIES, 'toggleElement: fetch children', id);
Command.children(id);
}
b.prop('src', 'icon/tree_arrow_down.png')
.prop('alt', 'Collapse ' + displayName)
.prop('title', 'Collapse ' + displayName);
;
addExpandedNode(id);
}
},
makeNameEditable: function(element, width) {
var w = width || 200;
//element.off('dblclick');
//element.off('hover');
var oldName = $.trim(element.children('b.name_').attr('title'));
element.children('b.name_').replaceWith('');
//element.find('.button').hide();
var input = $('input', element);
input.focus().select();
input.on('blur', function() {
var self = $(this);
var newName = self.val();
self.replaceWith('' + fitStringToWidth(oldName, w) + '');
element.children('b.name_').on('click', function(e) {
e.stopPropagation();
_Entities.makeNameEditable(element, w);
});
Command.setProperty(Structr.getId(element), "name", newName);
_Pages.reloadPreviews();
});
input.keypress(function(e) {
if (e.keyCode === 13) {
var self = $(this);
var newName = self.val();
self.replaceWith('' + fitStringToWidth(oldName, w) + '');
element.children('b.name_').on('click', function(e) {
e.stopPropagation();
_Entities.makeNameEditable(element, w);
});
Command.setProperty(Structr.getId(element), "name", newName);
_Pages.reloadPreviews();
}
});
//element.off('click');
},
handleActiveElement: function(entity) {
if (entity) {
var idString = 'id_' + entity.id;
if (!activeElements.hasOwnProperty(idString)) {
activeElements[idString] = entity;
var parent = $('#activeElements div.inner');
var id = entity.id;
if (entity.parentId) {
parent = $('#active_' + entity.parentId);
}
parent.append('');
var div = $('#active_' + id);
var query = entity.query;
//var dataKey = (entity.dataKey.split(',')[entity.recursionDepth] || '');
var expand = entity.state === 'Query';
var icon = _Elements.icon;
var name = '', content = '', action = '';
switch (entity.state) {
case 'Query':
icon = 'icon/database_table.png';
name = query || entity.dataKey.replace(',', '.');
break;
case 'Content':
icon = _Contents.icon;
content = entity.content ? entity.content : entity.type;
break;
case 'Button':
icon = 'icon/button.png';
action = entity.action;
break;
case 'Link':
icon = 'icon/link.png';
content = entity.action;
break;
default:
content = entity.state;
}
div.append('
'
+ '' + fitStringToWidth(name, 180, 'slideOut') + ''
+ '' + (action ? action : ' ') + ''
+ '' + (content ? fitStringToWidth(content, 180, 'slideOut') : ' ') + ''
+ '' + entity.id + ''
// + (entity._html_id ? '#' + entity._html_id.replace(/\${.*}/g, '${…}') + '' : '')
// + (entity._html_class ? '.' + entity._html_class.replace(/\${.*}/g, '${…}').replace(/ /g, '.') + '' : '')
);
_Entities.setMouseOver(div);
var editIcon = $('.edit_icon', div);
if (!(editIcon && editIcon.length)) {
div.append('
');
editIcon = $('.edit_icon', div);
}
editIcon.on('click', function(e) {
e.stopPropagation();
switch (entity.state) {
case 'Query':
_Entities.openQueryDialog(entity.id);
break;
case 'Content':
_Contents.openEditContentDialog(this, entity);
break;
case 'Button':
_Entities.openEditModeBindingDialog(entity.id);
break;
case 'Link':
_Entities.showProperties(entity);
break;
default:
_Entities.showProperties(entity);
}
});
$('b[title]', div).on('click', function() {
_Entities.openQueryDialog(entity.id);
});
$('.content_', div).on('click', function() {
_Contents.openEditContentDialog(this, entity);
});
$('.action', div).on('click', function() {
_Entities.openEditModeBindingDialog(entity.id);
});
var typeIcon = $(div.children('.typeIcon').first());
var padding = 0;
var displayName = getElementDisplayName(entity);
if (!expand) {
padding = 11;
} else {
typeIcon.css({
paddingRight: padding + 'px'
}).after('
');
}
}
}
},
openQueryDialog: function(id) {
Command.get(id, function(obj) {
var entity = StructrModel.create(obj);
Structr.dialog('Query and Data Binding of ' + (entity.name ? entity.name : entity.id), function() {
return true;
}, function() {
return true;
});
dialogText.append('');
_Entities.queryDialog(entity, dialogText);
if (entity.restQuery) {
_Entities.activateTabs(entity.id, '#data-tabs', '#content-tab-rest');
} else if (entity.cypherQuery) {
_Entities.activateTabs(entity.id, '#data-tabs', '#content-tab-cypher');
} else if (entity.xpathQuery) {
_Entities.activateTabs(entity.id, '#data-tabs', '#content-tab-xpath');
} else {
_Entities.activateTabs(entity.id, '#data-tabs', '#content-tab-rest');
}
});
},
openEditModeBindingDialog: function(id) {
Command.get(id, function(obj) {
var entity = StructrModel.create(obj);
Structr.dialog('Edit mode binding for ' + (entity.name ? entity.name : entity.id), function() {
return true;
}, function() {
return true;
});
dialogText.append('');
_Entities.dataBindingDialog(entity, dialogText);
});
}
};
function addPrincipal(entity, principal, permissions) {
$('#newPrincipal option[value="' + principal.id + '"]').remove();
$('#newPrincipal').trigger('chosen:updated');
$('#new').after('
' + principal.name + '');
var row = $('._' + principal.id, dialogText);
['read', 'write', 'delete', 'accessControl'].forEach(function(perm) {
row.append(' ');
var disabled = false;
$('.' + perm, row).on('dblclick', function() {
return false;
});
$('.' + perm, row).on('click', function(e) {
e.preventDefault();
if (disabled)
return false;
var sw = $(this);
disabled = true;
sw.prop('disabled', 'disabled');
window.setTimeout(function() {
disabled = false;
sw.prop('disabled', null);
}, 200);
if (!$('input:checked', row).length) {
$('#newPrincipal').append('').trigger('chosen:updated');
row.remove();
}
var rec = $('#recursive', dialogText).is(':checked');
Command.setPermission(entity.id, principal.id, permissions[perm] ? 'revoke' : 'grant', perm, rec, function() {
permissions[perm] = !permissions[perm];
sw.prop('checked', permissions[perm]);
_Logger.log(_LogType.ENTITIES, 'Permission successfully updated!');
blinkGreen(sw.parent());
});
});
});
}
function formatValueInputField(key, obj, isPassword, isReadOnly) {
if (obj === null) {
return '';
} else if (obj.constructor === Object) {
var node = obj;
var displayName = _Crud.displayName(node);
return '' + fitStringToWidth(displayName, 80) + '
';
//return '';
} else if (obj.constructor === Array) {
var out = '';
$(obj).each(function(i, v) {
out += formatValueInputField(key, v, isPassword, isReadOnly) + '
';
});
return out;
//return '';
} else {
return '';
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy