508 lines
16 KiB
JavaScript
508 lines
16 KiB
JavaScript
var writePermission = false;
|
|
var showParams = false;
|
|
var showConsole = false;
|
|
var prompt = false // True while a prompt is opened.
|
|
|
|
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
// COMMUNICATION
|
|
|
|
function getGroup(s, name) {
|
|
reqJSON(s, "http://" + hostPort + "/getblock?path=" + name
|
|
+ "&id=" + clientID, successHandler, errorHandler);
|
|
}
|
|
|
|
function sendCommand(s, command) {
|
|
reqJSON(s, "http://" + hostPort + "/sendcommand?command=" + encodeURIComponent(command)
|
|
+ "&id=" + clientID, successHandler, errorHandler);
|
|
}
|
|
|
|
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
// GROUP
|
|
|
|
function createContent(message) {
|
|
// Depending on the message received from the server the content of the
|
|
// group is created dynamically. Handles draw-message.
|
|
|
|
var content = document.createElement('div');
|
|
content.classList.add("content");
|
|
// Process components of the message
|
|
for (var i = 0; i < message.components.length; i++) {
|
|
var component = message.components[i];
|
|
if (!("title" in component))
|
|
component.title = component.name;
|
|
if (!("command" in component))
|
|
component.command = component.name;
|
|
|
|
if (message.title == 'modules') {
|
|
let row = createRowForModules(component);
|
|
content.appendChild(row);
|
|
} else {
|
|
let row = createRowForParameters(component);
|
|
content.appendChild(row);
|
|
}
|
|
}
|
|
return content;
|
|
}
|
|
|
|
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
|
|
// ROW
|
|
|
|
function createRowForModules(component) {
|
|
let left = createLeftColumnForModules(component);
|
|
left.id = component.name;
|
|
left.setAttribute('name', 'component.title');
|
|
|
|
let right = createRightColumnForModules(component);
|
|
let row = appendToContent(left, right);
|
|
|
|
row.onclick = function () {
|
|
getGroup(s, component.title);
|
|
}
|
|
row.classList.add('row-clickable');
|
|
return row;
|
|
}
|
|
|
|
function createRowForParameters(component) {
|
|
let left = createLeftColumnForParameters(component);
|
|
let right = createRightColumnForParameters(component);
|
|
return appendToContent(left, right);
|
|
}
|
|
|
|
function appendToContent(left, right) {
|
|
let row = document.createElement('div');
|
|
row.classList.add("row");
|
|
row.appendChild(left);
|
|
row.appendChild(right);
|
|
return row;
|
|
}
|
|
|
|
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
|
|
// LEFT COLUMN
|
|
|
|
function createLeftColumnForModules(component) {
|
|
var left = document.createElement('span');
|
|
left.classList.add('col-left');
|
|
if (component.statusname) {
|
|
left.appendChild(createStatusIcon(component));
|
|
}
|
|
let modules_title = document.createElement('span');
|
|
modules_title.classList.add('modules-title');
|
|
modules_title.innerHTML = component.title;
|
|
if (component.type == 'pushbutton') {
|
|
modules_title.classList.add('push-button');
|
|
if (writePermission == true) {
|
|
modules_title.classList.add('push-button-active');
|
|
}
|
|
modules_title.onclick = function () {
|
|
if (writePermission == true) {
|
|
let row = button.closest('div');
|
|
row.classList.add('row-waiting-for-answer');
|
|
sendCommand(s, component.command);
|
|
}
|
|
}
|
|
}
|
|
left.appendChild(modules_title);
|
|
if (component.statusname) {
|
|
let status_info = document.createElement('span');
|
|
status_info.classList.add('status-info');
|
|
status_info.setAttribute('name', component.title + '-info');
|
|
left.appendChild(status_info);
|
|
}
|
|
if (component.info) {
|
|
let icon_info = createInfoIcon(component);
|
|
left.appendChild(icon_info);
|
|
left.appendChild(createInfoBox(component));
|
|
}
|
|
return left;
|
|
|
|
function createStatusIcon(component) {
|
|
let icon_status = document.createElement('img');
|
|
icon_status.setAttribute('src', 'res/icon_status.png');
|
|
icon_status.setAttribute('name', component.title + ':status');
|
|
icon_status.classList.add('icon-modules', 'icon-status');
|
|
return icon_status;
|
|
}
|
|
|
|
function createInfoIcon(component) {
|
|
let icon_info = document.createElement('img');
|
|
icon_info.setAttribute('src', 'res/icon_info.png');
|
|
icon_info.classList.add('icon-modules', 'icon-info');
|
|
if (isTouchDevice) {
|
|
icon_info.onclick = function (event) {
|
|
event.stopPropagation()
|
|
icon_info.nextSibling.classList.toggle("info-box-visible-by-click");
|
|
}
|
|
}
|
|
return icon_info;
|
|
}
|
|
|
|
function createInfoBox(component) {
|
|
// Creates info-box, which isn't visible by default but can be displayed.
|
|
let info_box = document.createElement('span');
|
|
info_box.classList.add("info-box");
|
|
info_box.innerHTML = '<b>' + component.title + '</b>: ' + component.info;
|
|
return info_box;
|
|
}
|
|
}
|
|
|
|
function createLeftColumnForParameters(component) {
|
|
let left = document.createElement('span');
|
|
left.classList.add('col-left');
|
|
if (component.type == 'pushbutton') {
|
|
left.appendChild(createPushButton (component));
|
|
} else {
|
|
left.innerHTML = component.title;
|
|
}
|
|
return left;
|
|
|
|
function createPushButton (component) {
|
|
let button = document.createElement('span');
|
|
button.classList.add('push-button');
|
|
if (writePermission == true) {
|
|
button.classList.add('push-button-active');
|
|
}
|
|
button.innerHTML = component.title;
|
|
button.onclick = function () {
|
|
if (writePermission == true) {
|
|
let row = button.closest('div');
|
|
row.classList.add('row-waiting-for-answer');
|
|
sendCommand(s, component.command);
|
|
}
|
|
}
|
|
return button;
|
|
}
|
|
}
|
|
|
|
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
|
|
// RIGHT COLUMN
|
|
|
|
function createRightColumnForModules(component) {
|
|
|
|
var right = document.createElement('span');
|
|
right.classList.add('col-right', 'col-right-modules');
|
|
|
|
right.appendChild(createValue(component));
|
|
|
|
if (component.targetname) {
|
|
if (component.type == 'input' ||
|
|
component.type == 'checkbox' ||
|
|
component.type == 'enum'
|
|
) {
|
|
let input_element = chooseTypeOfInput(component);
|
|
let icon_edit = createIconEdit(input_element);
|
|
right.appendChild(icon_edit);
|
|
right.appendChild(input_element);
|
|
}
|
|
}
|
|
return right;
|
|
}
|
|
|
|
function createRightColumnForParameters(component) {
|
|
|
|
let right = document.createElement('span');
|
|
right.classList.add('col-right-parameters');
|
|
|
|
right.appendChild(createValue(component));
|
|
|
|
if (component.type == 'input' ||
|
|
component.type == 'checkbox' ||
|
|
component.type == 'enum'
|
|
) {
|
|
let input_element = chooseTypeOfInput(component);
|
|
let icon_edit = createIconEdit(input_element);
|
|
right.appendChild(icon_edit);
|
|
right.appendChild(input_element);
|
|
}
|
|
return right;
|
|
}
|
|
|
|
function createValue (component) {
|
|
let value = document.createElement('span');
|
|
value.classList.add('col-right-value');
|
|
if (writePermission == true) {
|
|
value.classList.add('col-right-value-with-write-permission');
|
|
}
|
|
value.setAttribute('name', component.name);
|
|
if (component.type == 'pushbutton') {
|
|
value.__ctype__ = 'none';
|
|
} else {
|
|
value.__ctype__ = 'rdonly';
|
|
}
|
|
return value;
|
|
}
|
|
|
|
function createIconEdit (input_element) {
|
|
|
|
let icon_edit = document.createElement('img');
|
|
icon_edit.setAttribute('src', 'res/icon_edit.png');
|
|
icon_edit.classList.add('icon-modules', 'icon-edit');
|
|
if (writePermission == false) {
|
|
icon_edit.classList.add('icon-edit-hidden');
|
|
}
|
|
|
|
icon_edit.onclick = function (event) {
|
|
event.stopPropagation()
|
|
let is_hidden = input_element.classList.contains('input-element-hidden');
|
|
hideInputElements();
|
|
if (is_hidden) {
|
|
input_element.classList.remove('input-element-hidden');
|
|
if (input_element.inputChild) {
|
|
// update input value before edit
|
|
input_element.inputChild.value = input_element.inputChild.actualValue;
|
|
}
|
|
icon_edit.setAttribute('src', 'res/icon_edit_close.png');
|
|
} else {
|
|
icon_edit.setAttribute('src', 'res/icon_edit.png');
|
|
}
|
|
}
|
|
|
|
return icon_edit;
|
|
}
|
|
|
|
function chooseTypeOfInput (component) {
|
|
let input_element;
|
|
switch (component.type) {
|
|
case 'enum':
|
|
input_element = createEnum(component);
|
|
input_element.classList.add('input-element', 'input-element-hidden');
|
|
break;
|
|
case 'input':
|
|
input_element = createInputText(component);
|
|
input_element.classList.add('input-element', 'input-element-hidden');
|
|
break;
|
|
case 'checkbox':
|
|
input_element = createCheckbox(component);
|
|
input_element.classList.add('input-element', 'input-element-hidden');
|
|
break;
|
|
}
|
|
return input_element;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------------------- */
|
|
// input elements
|
|
|
|
|
|
function createInputText(component) {
|
|
// Creates row-element containing input-item.
|
|
|
|
var input = createInputElement(component, 'input', 'input-text');
|
|
input.type = "text";
|
|
input.style.width = "100px";
|
|
input.onclick = function (e) {
|
|
e.stopPropagation();
|
|
}
|
|
// Prevent updates, while user is changing textfield
|
|
input.addEventListener("focus", function(evt) {
|
|
let elm = evt.target;
|
|
setTimeout(function(){elm.setSelectionRange(0, elm.value.length);},0);
|
|
});
|
|
|
|
input.onkeydown = function (e) {
|
|
if (e.key == "Escape") {
|
|
// User decided to cancel
|
|
let input = e.target;
|
|
input.value = input.oldValue;
|
|
resizeTextfield(input);
|
|
var row = input.closest('div');
|
|
row.classList.remove('row-waiting-for-answer');
|
|
hideInputElements();
|
|
}
|
|
}
|
|
|
|
input.onfocus = function () {
|
|
input.oldValue = input.value;
|
|
if (isTouchDevice)
|
|
setTimeout(function () {
|
|
posTextfield(s, left);
|
|
}, 1);
|
|
}
|
|
|
|
var form = document.createElement('form');
|
|
form.onsubmit = function (e) {
|
|
e.preventDefault();
|
|
var row = form.closest('div');
|
|
row.classList.add('row-waiting-for-answer');
|
|
// Request for command
|
|
input.actualValue = input.value;
|
|
if (component.targetname) {
|
|
sendCommand(s, component.targetname + " " + input.value);
|
|
} else {
|
|
sendCommand(s, component.name + " " + input.value);
|
|
}
|
|
row.classList.add('row-waiting-for-answer');
|
|
input.blur();
|
|
hideInputElements();
|
|
};
|
|
form.appendChild(input);
|
|
form.appendChild(createSubmitButton());
|
|
form.inputChild = input;
|
|
return form;
|
|
}
|
|
|
|
function createCheckbox(component) {
|
|
// Creates row-element containing checkbox-item
|
|
let input = createInputElement(component, 'input', 'parameter-checkbox');
|
|
input.type = "checkbox";
|
|
input.onclick = function (e) {
|
|
e.stopPropagation;
|
|
}
|
|
|
|
let form = document.createElement('form');
|
|
form.onsubmit = function (e) {
|
|
e.preventDefault();
|
|
var row = form.closest('div');
|
|
row.classList.add('row-waiting-for-answer');
|
|
sendCommand(s, component.command + " " + input.checked);
|
|
hideInputElements();
|
|
};
|
|
form.appendChild(input);
|
|
form.appendChild(createSubmitButton());
|
|
return form;
|
|
}
|
|
|
|
function createEnum(component) {
|
|
// Creates row-element containing dropdown-selection.
|
|
var buttons = component.enum_names;
|
|
var select = createInputElement(component, 'select', 'select-params');
|
|
|
|
for (var i = 0; i < buttons.length; i++) {
|
|
var option = document.createElement('option');
|
|
option.type = "enum";
|
|
option.classList.add("option-params");
|
|
option.value = buttons[i].value;
|
|
option.appendChild(document.createTextNode(buttons[i].title));
|
|
select.add(option);
|
|
}
|
|
|
|
select.oninput = function () {
|
|
let row = select.closest('div');
|
|
row.classList.add('row-waiting-for-answer');
|
|
let index = select.value - 1;
|
|
console.log('send', buttons[index].title);
|
|
sendCommand(s, component.command + " " + select.value);
|
|
// hideInputElements();
|
|
};
|
|
|
|
select.onfocus = function () {
|
|
// select.oldIndex = select.selectedIndex;
|
|
console.log(select.selectedValue);
|
|
}
|
|
|
|
var right = document.createElement('span');
|
|
right.appendChild(select);
|
|
return right;
|
|
}
|
|
|
|
function createRadio(component) {
|
|
|
|
console.log(component);
|
|
let array_names = component.enum_names;
|
|
|
|
let form = createInputElement(component, 'form', 'radio-button-group');
|
|
form.onsubmit = function (e) {
|
|
e.preventDefault();
|
|
var row = form.closest('div');
|
|
row.classList.add('row-waiting-for-answer');
|
|
sendCommand(s, component.command + " " + 'on');
|
|
hideInputElements();
|
|
};
|
|
|
|
for (var i = 0; i < array_names.length; i++) {
|
|
let label = document.createElement('label');
|
|
label.setAttribute('for', array_names[i].title);
|
|
label.innerHTML = array_names[i].title;
|
|
|
|
let radio = document.createElement('input');
|
|
radio.setAttribute('type', 'radio');
|
|
radio.classList.add("radio");
|
|
radio.setAttribute('id', array_names[i].title);
|
|
radio.setAttribute('name', component.name);
|
|
radio.onclick = function(e) {
|
|
e.stopPropagation();
|
|
}
|
|
|
|
form.appendChild(label);
|
|
form.appendChild(radio);
|
|
}
|
|
|
|
form.appendChild(createSubmitButton());
|
|
return form;
|
|
}
|
|
|
|
function createInputElement(component, tag='span', cls='col-right-modules') {
|
|
var input_element = document.createElement(tag);
|
|
input_element.classList.add('col-right');
|
|
if (cls)
|
|
input_element.classList.add(cls);
|
|
if (component.targetname) {
|
|
input_element.setAttribute('name', component.targetname);
|
|
} else {
|
|
input_element.setAttribute('name', component.name);
|
|
}
|
|
// Add DOM-property
|
|
input_element.__ctype__ = component.type;
|
|
return input_element;
|
|
}
|
|
|
|
function createSubmitButton () {
|
|
let submit_btn = document.createElement('input');
|
|
submit_btn.setAttribute('type', 'image');
|
|
submit_btn.classList.add('icon-modules', 'icon-okay');
|
|
submit_btn.setAttribute('src', 'res/icon_okay.png');
|
|
submit_btn.onclick = function (e) {
|
|
e.stopPropagation();
|
|
}
|
|
return submit_btn;
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------------------- */
|
|
|
|
// Hides all input elements (input text, pushbotton, enum, checkbox)
|
|
// Changes all iconEditClose (cross) back to iconEdit (pen)
|
|
function hideInputElements(){
|
|
let input_elements = document.getElementsByClassName('input-element');
|
|
for (let i = 0; i < input_elements.length; i++) {
|
|
input_elements[i].classList.add('input-element-hidden');
|
|
}
|
|
|
|
let array_icon_edit = document.getElementsByClassName('icon-edit');
|
|
for (let i = 0; i < array_icon_edit.length; i++) {
|
|
array_icon_edit[i].setAttribute('src', 'res/icon_edit.png');
|
|
}
|
|
}
|
|
|
|
function resizeTextfield(input) {
|
|
if (input.value.length > input.size * 12 / 20) {
|
|
var str0 = window.getComputedStyle(input).fontSize;
|
|
var str1 = str0.substring(0, str0.length - 2);
|
|
if (input.value.length < 43) {
|
|
input.style.width = input.value.length * str1 * 12 / 20 + "px";
|
|
}
|
|
} else {
|
|
input.style.width = "100px";
|
|
}
|
|
}
|
|
|
|
/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
|
|
// CONTENT
|
|
|
|
function appendToGridElement(s, title, type, content) {
|
|
let panel = document.createElement('div');
|
|
panel.classList.add("panel");
|
|
|
|
titlewrapper = document.createElement('span');
|
|
titlewrapper.innerHTML = title;
|
|
panel.appendChild(titlewrapper);
|
|
|
|
let gridContainer = document.createElement('div');
|
|
gridContainer.classList.add("grid-container");
|
|
// Store type so it can be found easiely later.
|
|
gridContainer.slideType = type;
|
|
gridContainer.appendChild(panel);
|
|
gridContainer.appendChild(content);
|
|
|
|
let gridelements = document.getElementsByClassName('grid-element');
|
|
gridelements[s].innerHTML = "";
|
|
gridelements[s].appendChild(gridContainer);
|
|
}
|