');
$dialogMessage = $('#dialog-message');
}
if (icon) {
$dialogMessage.find('.dialog-icon')
.show()
.html(icon);
} else {
$dialogMessage.find('.dialog-icon').hide();
}
if (title) {
$dialogMessage.find('.dialog-title').html(title).show();
} else {
$dialogMessage.find('.dialog-title').hide();
}
$dialogMessage.find('.dialog-text').html(message);
$dialogMessage.modal().modal('open');
}
function confirmMessageJQ(message, title, icon, buttons, callback) {
var $dialogConfirm = $('#dialog-confirm-settings');
if (!$dialogConfirm.length) {
$('body').append('
\n' +
'
' +
'\n' +
'\n' +
'
\n' +
'
');
$dialogConfirm = $('#dialog-confirm-settings');
$dialogConfirm.dialog({
autoOpen: false,
modal: true
});
}
if (typeof buttons === 'function') {
callback = buttons;
$dialogConfirm.dialog('option', 'buttons', [
{
text: _('Ok'),
click: function () {
var cb = $(this).data('callback');
$(this).data('callback', null);
$(this).dialog('close');
if (cb) cb(true);
}
},
{
text: _('Cancel'),
click: function () {
var cb = $(this).data('callback');
$(this).data('callback', null);
$(this).dialog('close');
if (cb) cb(false);
}
}
]);
} else if (typeof buttons === 'object') {
for (var b = 0; b < buttons.length; b++) {
buttons[b] = {
text: buttons[b],
id: 'dialog-confirm-button-' + b,
click: function (e) {
var id = parseInt(e.currentTarget.id.substring('dialog-confirm-button-'.length), 10);
var cb = $(this).data('callback');
$(this).data('callback', null);
$(this).dialog('close');
if (cb) cb(id);
}
}
}
$dialogConfirm.dialog('option', 'buttons', buttons);
}
$dialogConfirm.dialog('option', 'title', title || _('Message'));
$('#dialog-confirm-text-settings').html(message);
if (icon) {
$('#dialog-confirm-icon-settings')
.show()
.attr('class', '')
.addClass('ui-icon ui-icon-' + icon);
} else {
$('#dialog-confirm-icon-settings').hide();
}
$dialogConfirm.data('callback', callback);
$dialogConfirm.dialog('open');
}
function confirmMessage(message, title, icon, buttons, callback) {
if (!isMaterialize) {
return confirmMessageJQ(message, title, icon, buttons, callback);
}
var $dialogConfirm;
// noinspection JSJQueryEfficiency
$dialogConfirm = $('#dialog-confirm');
if (!$dialogConfirm.length) {
$('body').append(
'
' +
'
' +
' ' +
'
' +
'
' +
' ' +
'
'
);
$dialogConfirm = $('#dialog-confirm');
}
if (typeof buttons === 'function') {
callback = buttons;
$dialogConfirm.find('.modal-footer').html(
'' + _('Ok') + '' +
'' + _('Cancel') + '');
$dialogConfirm.find('.modal-footer .modal-action').on('click', function () {
var cb = $dialogConfirm.data('callback');
cb && cb($(this).data('result'));
});
} else if (typeof buttons === 'object') {
var tButtons = '';
for (var b = buttons.length - 1; b >= 0; b--) {
tButtons += '' + buttons[b] + '';
}
$dialogConfirm.find('.modal-footer').html(tButtons);
$dialogConfirm.find('.modal-footer .modal-action').on('click', function () {
var cb = $dialogConfirm.data('callback');
cb && cb($(this).data('id'));
});
}
$dialogConfirm.find('.dialog-title').text(title || _('Please confirm'));
if (icon) {
$dialogConfirm.find('.dialog-icon')
.show()
.html(icon);
} else {
$dialogConfirm.find('.dialog-icon').hide();
}
if (title) {
$dialogConfirm.find('.dialog-title').html(title).show();
} else {
$dialogConfirm.find('.dialog-title').hide();
}
$dialogConfirm.find('.dialog-text').html(message);
$dialogConfirm.data('callback', callback);
$dialogConfirm.modal({
dismissible: false
}).modal('open');
}
function showError(error) {
showMessage(_(error), _('Error'), 'error_outline');
}
function showToast(parent, message, icon, duration, isError, classes) {
if (typeof parent === 'string') {
classes = isError;
isError = duration;
icon = message;
message = parent;
parent = null;
}
if (parent && parent instanceof jQuery) {
parent = parent[0];
}
classes = classes || [];
if (typeof classes === 'string') {
classes = [classes];
}
isError && classes.push('dropZone-error');
M.toast({
parentSelector: parent || $('body')[0],
html: message + (icon ? '' + icon + '' : ''),
displayLength: duration || 3000,
classes: classes
});
}
function getObject(id, callback) {
socket.emit('getObject', id, function (err, res) {
if (!err && res) {
if (callback) callback(err, res);
} else {
if (callback) callback(null);
}
});
}
function getState(id, callback) {
socket.emit('getState', id, function (err, res) {
if (!err && res) {
if (callback) callback(err, res);
} else {
if (callback) callback(null);
}
});
}
function getEnums(_enum, callback) {
socket.emit('getObjectView', 'system', 'enum', {startkey: 'enum.' + _enum, endkey: 'enum.' + _enum + '.\u9999'}, function (err, res) {
if (!err && res) {
var _res = {};
for (var i = 0; i < res.rows.length; i++) {
if (res.rows[i].id === 'enum.' + _enum) continue;
_res[res.rows[i].id] = res.rows[i].value;
}
if (callback) callback(null, _res);
} else {
if (callback) callback(err, []);
}
});
}
function getGroups(callback) {
socket.emit('getObjectView', 'system', 'group', {startkey: 'system.group.', endkey: 'system.group.\u9999'}, function (err, res) {
if (!err && res) {
var _res = {};
for (var i = 0; i < res.rows.length; i++) {
_res[res.rows[i].id] = res.rows[i].value;
}
if (callback) callback(null, _res);
} else {
if (callback) callback(err, []);
}
});
}
function getUsers(callback) {
socket.emit('getObjectView', 'system', 'user', {startkey: 'system.user.', endkey: 'system.user.\u9999'}, function (err, res) {
if (!err && res) {
var _res = {};
for (var i = 0; i < res.rows.length; i++) {
_res[res.rows[i].id] = res.rows[i].value;
}
if (callback) callback(null, _res);
} else {
if (callback) callback(err, []);
}
});
}
function fillUsers(elemId, current, callback) {
getUsers(function (err, users) {
// Answer is like
// {
// "admin": { <<=== This is a common.name!
// "type": "user",
// "common": {
// "name": "admin",
// "password": "aaa",
// "dontDelete": true,
// "enabled": true,
// "icon": "data:image/png;base64,xxx",
// "color": "#ca0808",
// "desc": ""
// },
// "_id": "system.user.admin"
// },
// ...
// }
var text = '';
// Warning u is name of user and not ID.
var len = 'system.user.'.length;
for (var u in users) {
if (users.hasOwnProperty(u)) {
var id = users[u]._id.substring(len);
text += '\n';
}
}
$(elemId).html(text);
if (isMaterialize) {
$(elemId).select();
}
});
}
function getIPs(host, callback) {
if (typeof host === 'function') {
callback = host;
host = null;
}
socket.emit('getHostByIp', host || common.host, function (ip, _host) {
if (_host) {
host = _host;
var IPs4 = [{name: '[IPv4] 0.0.0.0 - ' + _('Listen on all IPs'), address: '0.0.0.0', family: 'ipv4'}];
var IPs6 = [{name: '[IPv6] ::', address: '::', family: 'ipv6'}];
if (host.native.hardware && host.native.hardware.networkInterfaces) {
for (var eth in host.native.hardware.networkInterfaces) {
if (!host.native.hardware.networkInterfaces.hasOwnProperty(eth)) continue;
for (var num = 0; num < host.native.hardware.networkInterfaces[eth].length; num++) {
if (host.native.hardware.networkInterfaces[eth][num].family !== 'IPv6') {
IPs4.push({name: '[' + host.native.hardware.networkInterfaces[eth][num].family + '] ' + host.native.hardware.networkInterfaces[eth][num].address + ' - ' + eth, address: host.native.hardware.networkInterfaces[eth][num].address, family: 'ipv4'});
} else {
IPs6.push({name: '[' + host.native.hardware.networkInterfaces[eth][num].family + '] ' + host.native.hardware.networkInterfaces[eth][num].address + ' - ' + eth, address: host.native.hardware.networkInterfaces[eth][num].address, family: 'ipv6'});
}
}
}
}
for (var i = 0; i < IPs6.length; i++) {
IPs4.push(IPs6[i]);
}
callback(IPs4);
}
});
}
function fillSelectIPs(id, actualAddr, noIPv4, noIPv6, callback) {
getIPs(function (ips) {
var str = '';
for (var i = 0; i < ips.length; i++) {
if (noIPv4 && ips[i].family === 'ipv4') continue;
if (noIPv6 && ips[i].family === 'ipv6') continue;
str += '';
}
$(id).html(str);
if (isMaterialize) {
$(id).select();
}
if (typeof callback === 'function') {
callback();
}
});
}
function sendTo(_adapter_instance, command, message, callback) {
socket.emit('sendTo', (_adapter_instance || adapter + '.' + instance), command, message, callback);
}
function sendToHost(host, command, message, callback) {
socket.emit('sendToHost', host || common.host, command, message, callback);
}
function getInterfaces(onlyNames, callback) {
if (typeof onlyNames === 'function') {
callback = onlyNames;
onlyNames = false;
}
socket.emit('sendToHost', common.host, 'getInterfaces', null, function (result) {
if (result && result.result) {
if (onlyNames) {
callback(null, Object.keys(result.result));
} else {
callback(null, result);
}
} else {
callback((result && result.error) || 'cannot read');
}
});
}
// fills select with names of the certificates and preselect it
function fillSelectCertificates(id, type, actualValued) {
var str = '';
for (var i = 0; i < certs.length; i++) {
if (certs[i].type && certs[i].type !== type) continue;
str += '';
}
$(id).html(str);
if (isMaterialize) {
$(id).select();
}
}
function getAdapterInstances(_adapter, callback) {
if (typeof _adapter === 'function') {
callback = _adapter;
_adapter = null;
}
socket.emit('getObjectView', 'system', 'instance', {startkey: 'system.adapter.' + (_adapter || adapter), endkey: 'system.adapter.' + (_adapter || adapter) + '.\u9999'}, function (err, doc) {
if (err) {
if (callback) callback ([]);
} else {
if (doc.rows.length === 0) {
if (callback) callback ([]);
} else {
var res = [];
for (var i = 0; i < doc.rows.length; i++) {
res.push(doc.rows[i].value);
}
if (callback) callback(res);
}
}
});
}
function getExtendableInstances(_adapter, callback) {
if (typeof _adapter === 'function') {
callback = _adapter;
_adapter = null;
}
socket.emit('getObjectView', 'system', 'instance', null, function (err, doc) {
if (err) {
if (callback) callback ([]);
} else {
if (doc.rows.length === 0) {
if (callback) callback ([]);
} else {
var res = [];
for (var i = 0; i < doc.rows.length; i++) {
if (doc.rows[i].value.common.webExtendable) {
res.push(doc.rows[i].value);
}
}
if (callback) callback (res);
}
}
});
}
function getIsAdapterAlive(_adapter, callback) {
if (typeof _adapter === 'function') {
callback = _adapter;
_adapter = null;
}
getState('system.adapter.' + (_adapter || adapter) + '.' + instance + '.alive', function (err, obj) {
if (!obj || !obj.val) {
callback(false);
} else {
callback(true);
}
});
}
// Adds one entry to the created with editTable table
// tabId - the id of the table used by editTable
// value - is one object to add in form {ip: '3.3.3.3', room: 'enum.room.bla3', desc: 'Bla3'}
// $grid - [optional] - object returned by editTable to speed up the addition
// _isInitial - [optional] - if it is initial fill of the table. To not trigger the onChange
function addToTable(tabId, value, $grid, _isInitial) {
$grid = $grid || $('#' + tabId);
var obj = {_id: $grid[0]._maxIdx++};
var cols = $grid[0]._cols;
for (var i = 0; i < cols.length; i++) {
if (cols[i] === 'room') {
obj[cols[i]] = ($grid[0]._rooms[value[cols[i]]]) ? $grid[0]._rooms[value[cols[i]]].common.name : value[cols[i]];
} else {
obj[cols[i]] = value[cols[i]];
}
}
obj._commands =
'' +
'' +
'' +
'';
$grid.jqGrid('addRowData', tabId + '_' + obj._id, obj);
_editInitButtons($grid, tabId, obj._id);
if (!_isInitial && $grid[0]._onChange) $grid[0]._onChange('add', value);
}
function _editInitButtons($grid, tabId, objId) {
var search = objId ? '[data-' + tabId + '-id="' + objId + '"]' : '';
$('.' + tabId + '-edit-submit' + search).off('click').button({
icons: {primary: 'ui-icon-pencil'},
text: false
}).on('click', function () {
var id = $(this).attr('data-' + tabId + '-id');
$('.' + tabId + '-edit-submit').hide();
$('.' + tabId + '-delete-submit').hide();
$('.' + tabId + '-ok-submit[data-' + tabId + '-id="' + id + '"]').show();
$('.' + tabId + '-cancel-submit[data-' + tabId + '-id="' + id + '"]').show();
$grid.jqGrid('editRow', tabId + '_' + id, {url: 'clientArray'});
if ($grid[0]._edited.indexOf(id) === -1) {
$grid[0]._edited.push(id);
}
changed = true;
var $navButtons = $('.dialog-config-buttons');
$navButtons.find('.btn-save').removeClass('disabled');
$navButtons.find('.btn-save-close').removeClass('disabled');
if (onChangeSupported) {
$navButtons.find('.btn-cancel').find('span').html(_('cancel'));
}
}).css({'height': '18px', width: '22px'});
$('.' + tabId + '-delete-submit' + search).off('click').button({
icons: {primary: 'ui-icon-trash'},
text: false
}).on('click', function () {
var id = $(this).attr('data-' + tabId + '-id');
$grid.jqGrid('delRowData', tabId + '_' + id);
changed = true;
var $navButtons = $('.dialog-config-buttons');
$navButtons.find('.btn-save').removeClass('disabled');
$navButtons.find('.btn-save-close').removeClass('disabled');
if (onChangeSupported) {
$navButtons.find('.btn-cancel').find('span').html(_('cancel'));
}
var pos = $grid[0]._edited.indexOf(id);
if (pos !== -1) {
$grid[0]._edited.splice(pos, 1);
}
if ($grid[0]._onChange) $grid[0]._onChange('del', id);
}).css({'height': '18px', width: '22px'});
$('.' + tabId + '-ok-submit' + search).off('click').button({
icons: {primary: 'ui-icon-check'},
text: false
}).on('click', function () {
var id = $(this).attr('data-' + tabId + '-id');
$('.' + tabId + '-edit-submit').show();
$('.' + tabId + '-delete-submit').show();
$('.' + tabId + '-ok-submit').hide();
$('.' + tabId + '-cancel-submit').hide();
$grid.jqGrid('saveRow', tabId + '_' + id, {url: 'clientArray'});
changed = true;
var $navButtons = $('.dialog-config-buttons');
$navButtons.find('.btn-save').removeClass('disabled');
$navButtons.find('.btn-save-close').removeClass('disabled');
if (onChangeSupported) {
$navButtons.find('.btn-cancel').find('span').html(_('cancel'));
}
var pos = $grid[0]._edited.indexOf(id);
if (pos !== -1) {
$grid[0]._edited.splice(pos, 1);
}
if ($grid[0]._onChange) $grid[0]._onChange('changed', $grid.jqGrid('getRowData', tabId + '_' + id));
}).css({'height': '18px', width: '22px'});
$('.' + tabId + '-cancel-submit' + search).off('click').button({
icons: {primary: 'ui-icon-close'},
text: false
}).on('click', function () {
var id = $(this).attr('data-' + tabId + '-id');
$('.' + tabId + '-edit-submit').show();
$('.' + tabId + '-delete-submit').show();
$('.' + tabId + '-ok-submit').hide();
$('.' + tabId + '-cancel-submit').hide();
$grid.jqGrid('restoreRow', tabId + '_' + id, false);
var pos = $grid[0]._edited.indexOf(id);
if (pos !== -1) {
$grid[0]._edited.splice(pos, 1);
}
}).css({'height': '18px', width: '22px'});
}
function _editTable(tabId, cols, values, rooms, top, onChange) {
var title = 'Device list';
if (typeof tabId === 'object') {
cols = tabId.cols;
values = tabId.values;
rooms = tabId.rooms;
top = tabId.top;
onChange = tabId.onChange;
if (tabId.title) title = tabId.title;
tabId = tabId.tabId;
}
initGridLanguage(systemLang);
var colNames = [];
var colModel = [];
var $grid = $('#' + tabId);
var room;
colNames.push('id');
colModel.push({
name: '_id',
index: '_id',
hidden: true
});
for (var i = 0; i < cols.length; i++) {
var width = null;
var checkbox = null;
if (typeof cols[i] === 'object') {
width = cols[i].width;
if (cols[i].checkbox) checkbox = true;
cols[i] = cols[i].name;
}
colNames.push(_(cols[i]));
var _obj = {
name: cols[i],
index: cols[i],
// width: 160,
editable: true
};
if (width) _obj.width = width;
if (checkbox) {
_obj.edittype = 'checkbox';
_obj.editoptions = {value: 'true:false'};
}
if (cols[i] === 'room') {
var list = {'': _('none')};
for (room in rooms) {
list[room] = _(translateName(rooms[room].common.name));
}
_obj.stype = 'select';
_obj.edittype = 'select';
_obj.editoptions = {value: list};
_obj.searchoptions = {
sopt: ['eq'],
value: ':' + _('all')
};
for (room in rooms) {
_obj.searchoptions.value += ';' + _(translateName(rooms[room].common.name)) + ':' + _(translateName(rooms[room].common.name));
}
}
colModel.push(_obj);
}
colNames.push('');
colModel.push({name: '_commands', index: '_commands', width: 50, editable: false, align: 'center', search: false});
$grid[0]._cols = cols;
$grid[0]._rooms = rooms;
$grid[0]._maxIdx = 0;
$grid[0]._top = top;
$grid[0]._edited = [];
$grid[0]._onChange = onChange;
$grid.jqGrid({
datatype: 'local',
colNames: colNames,
colModel: colModel,
width: 800,
height: 330,
pager: $('#pager-' + tabId),
rowNum: 1000,
rowList: [1000],
ondblClickRow: function (rowid) {
var id = rowid.substring((tabId + '_').length);
$('.' + tabId + '-edit-submit').hide();
$('.' + tabId + '-delete-submit').hide();
$('.' + tabId + '-ok-submit[data-' + tabId + '-id="' + id + '"]').show();
$('.' + tabId + '-cancel-submit[data-' + tabId + '-id="' + id + '"]').show();
$grid.jqGrid('editRow', rowid, {url: 'clientArray'});
if ($grid[0]._edited.indexOf(id) === -1) $grid[0]._edited.push(id);
changed = true;
var $navButtons = $('.dialog-config-buttons');
$navButtons.find('.btn-save').removeClass('disabled');
$navButtons.find('.btn-save-close').removeClass('disabled');
if (onChangeSupported) {
$navButtons.find('.btn-cancel').find('span').html(_('cancel'));
}
},
sortname: 'id',
sortorder: 'desc',
viewrecords: false,
pgbuttons: false,
pginput: false,
pgtext: false,
caption: _(title),
ignoreCase: true,
loadComplete: function () {
_editInitButtons($grid, tabId);
},
onSortCol: function () {
changed = true;
var $navButtons = $('.dialog-config-buttons');
$navButtons.find('.btn-save').removeClass('disabled');
$navButtons.find('.btn-save-close').removeClass('disabled');
if (onChangeSupported) {
$navButtons.find('.btn-cancel').find('span').html(_('cancel'));
}
}
}).jqGrid('filterToolbar', {
defaultSearch: 'cn',
autosearch: true,
searchOnEnter: false,
enableClear: false,
afterSearch: function () {
_editInitButtons($grid, tabId);
}
});
$('#pager-' + tabId + '_center').hide();
if ($('#pager-' + tabId).length) {
$grid.navGrid('#pager-' + tabId, {
search: false,
edit: false,
add: false,
del: false,
refresh: false
}).jqGrid('navButtonAdd', '#pager-' + tabId, {
caption: '',
buttonicon: 'ui-icon-plus',
onClickButton: function () {
// Find new unique name
var found;
var newText = _('New');
var ids = $grid.jqGrid('getDataIDs');
var idx = 1;
var obj;
do {
found = true;
for (var _id = 0; _id < ids.length; _id++) {
obj = $grid.jqGrid('getRowData', ids[_id]);
if (obj && obj[$grid[0]._cols[0]] === newText + idx) {
idx++;
found = false;
break;
}
}
} while (!found);
obj = {};
for (var t = 0; t < $grid[0]._cols.length; t++) {
obj[$grid[0]._cols[t]] = '';
}
obj[$grid[0]._cols[0]] = newText + idx;
changed = true;
var $navButtons = $('.dialog-config-buttons');
$navButtons.find('.btn-save').removeClass('disabled');
$navButtons.find('.btn-save-close').removeClass('disabled');
if (onChangeSupported) {
$navButtons.find('.btn-cancel').find('span').html(_('cancel'));
}
addToTable(tabId, obj, $grid);
},
position: 'first',
id: 'add-cert',
title: _('new device'),
cursor: 'pointer'
});
}
if (values) {
for (var u = 0; u < values.length; u++) {
addToTable(tabId, values[u], $grid, true);
}
}
$(window).on('resize', function () {
$grid.setGridHeight($(this).height() - top).setGridWidth($(this).width() - 10);
});
$(window).trigger('resize');
// hide scrollbar
$('.ui-jqgrid-bdiv').css({'overflow-x': 'hidden'});
return $grid;
}
// converts "enum.room.Sleeping_room" to "Sleeping room"
// As input gets the list from getEnum
function enumName2Id(enums, name) {
name = name.toLowerCase();
for (var enumId in enums) {
if (!enums.hasOwnProperty(enumId)) continue;
if (enums[enumId] && enums[enumId].common && enums[enumId].common.name) {
if (typeof enums[enumId].common.name === 'object') {
for (var lang in enums[enumId].common.name) {
if (enums[enumId].common.name.hasOwnProperty(lang) && enums[enumId].common.name[lang].toLowerCase() === name) {
return enumId;
}
}
} else {
if (enums[enumId].common.name && enums[enumId].common.name.toLowerCase() === name) return enumId;
}
}
if (enums[enumId] && enums[enumId].name) {
if (typeof enums[enumId].name === 'object') {
for (var lang in enums[enumId].name) {
if (enums[enumId].name.hasOwnProperty(lang) && enums[enumId].name[lang].toLowerCase() === name) {
return enumId;
}
}
} else {
if (enums[enumId].name.toLowerCase() === name) return enumId;
}
}
}
return '';
}
// Creates edit table for any configuration array
// tabId - is id of table where the jqGrid must be created. E.g:
// cols - array with names of the properties of entry. E.g: ['ip', 'room', 'desc']
// if column has name room, for that will be automatically the room enums loaded and shown
// values - array with values in form [{ip: '1.1.1.1', room: 'enum.room.bla1', desc: 'Bla1'}, {ip: '2.2.2.2', room: 'enum.room.bla2', desc: 'Bla2'}
// top - top position of the table to set the height of the table automatically. Table must be always as last on the page.
// onChange - callback called if something is changed in the table
//
// returns the jquery object of $('#tabId')
// To extract data from table
function editTable(tabId, cols, values, top, onChange) {
if (typeof tabId === 'object') {
cols = tabId.cols;
}
if (cols.indexOf('room') !== -1) {
getEnums('rooms', function (err, list) {
return _editTable(tabId, cols, values, list, top, onChange);
});
} else {
return _editTable(tabId, cols, values, null, top, onChange);
}
}
// Extract edited array from table
// tabId - is id of table where the jqGrid must be created. E.g:
// cols - array with names of the properties of entry. E.g: ['ip', 'room', 'desc']
//
// Returns array with values
function getTableResult(tabId, cols) {
var $grid = $('#' + tabId);
for (var j = 0; j < $grid[0]._edited.length; j++) {
$grid.jqGrid('saveRow', tabId + '_' + $grid[0]._edited[j], {url: 'clientArray'});
}
$('.' + tabId + '-edit-submit').show();
$('.' + tabId + '-delete-submit').show();
$('.' + tabId + '-ok-submit').hide();
$('.' + tabId + '-cancel-submit').hide();
var data = $grid.jqGrid('getRowData');
var res = [];
for (var i = 0; i < data.length; i++) {
var obj = {};
for (var z = 0; z < cols.length; z++) {
if (cols[z] === 'room') {
obj[cols[z]] = enumName2Id($grid[0]._rooms, data[i][cols[z]]);
} else {
obj[cols[z]] = data[i][cols[z]];
}
}
res.push(obj);
}
return res;
}
/*
Context
Room
Room
Enabled
*/
/**
* Create edit table from javascript array.
*
* This function creates a html edit table.
*
*
*
*
*
*
*
*
*
Context
*
Context
*
Room
*
Room
*
Enabled
*
*
*
*
*
*
*
*
* @param {string} divId name of the html element (or empty).
* @param {string} values data array
* @param {function} onChange this function will be called if something changed
* @param {function} onReady called, when the table is ready (may be to modify some elements of it)
* @param {number} maxRaw maximal number of rows
* @return {object} array with values
*/
function values2table(divId, values, onChange, onReady, maxRaw) {
if (typeof values === 'function') {
typeof onChange === 'number' ? maxRaw = onChange : maxRaw = null;
onChange = values;
values = divId;
divId = '';
}
if (typeof onReady === 'number') {
maxRaw = onReady;
onReady = null;
} else if (typeof maxRaw === 'undefined') {
maxRaw = null;
}
values = values || [];
var names = [];
var $div;
if (!divId) {
$div = $('body');
} else {
$div = $('#' + divId);
}
var $add = $div.find('.table-button-add');
$add.data('raw', values.length);
if (maxRaw) {
$add.data('maxraw', maxRaw);
}
if (!$add.data('inited')) {
$add.data('inited', true);
var addText = $add.text();
if (!isMaterialize) {
$add.button({
icons: {primary: 'ui-icon-plus'},
text: !!addText,
label: addText ? _(addText) : undefined
});
}
$add.on('click', function () {
if (!$add.data('maxraw') || ($add.data('raw') < $add.data('maxraw'))) {
var $table = $div.find('.table-values');
var values = $table.data('values');
var names = $table.data('names');
var obj = {};
for (var i = 0; i < names.length; i++) {
if (!names[i]) continue;
obj[names[i].name] = names[i].def;
}
values.push(obj);
onChange && onChange();
setTimeout(function () {
values2table(divId, values, onChange, onReady);
}, 100);
$add.data('raw', $add.data('raw') + 1);
} else {
confirmMessage(_('maxTableRaw') + ': ' + $add.data('maxraw'), _('maxTableRawInfo'), 'alert', ['Ok']);
}
});
}
if (values) {
var buttons = [];
var $table = $div.find('.table-values');
$table.data('values', values);
// load rooms
if (!$table.data('rooms') && $table.find('th[data-name="room"]').length) {
getEnums('rooms', function (err, list) {
var result = {};
var trRooms = _('nonerooms');
if (trRooms !== 'nonerooms') {
result[_('none')] = trRooms;
} else {
result[_('none')] = '';
}
var nnames = [];
for (var n in list) {
if (list.hasOwnProperty(n)) {
nnames.push(n);
}
}
nnames.sort(function (a, b) {
a = a.toLowerCase();
b = b.toLowerCase();
if (a > b) return 1;
if (a < b) return -1;
return 0;
});
for (var l = 0; l < nnames.length; l++) {
result[nnames[l]] = list[nnames[l]].common.name || l;
if (typeof result[nnames[l]] === 'object') {
result[nnames[l]] = result[nnames[l]][systemLang] || result[nnames[l]].en;
}
}
$table.data('rooms', result);
values2table(divId, values, onChange, onReady);
});
return;
}
// load functions
if (!$table.data('functions') && $table.find('th[data-name="func"]').length) {
getEnums('functions', function (err, list) {
var result = {};
var trFuncs = _('nonefunctions');
if (trFuncs !== 'nonefunctions') {
result[_('none')] = trFuncs;
} else {
result[_('none')] = '';
}
var nnames = [];
for (var n in list) {
if (list.hasOwnProperty(n)) {
nnames.push(n);
}
}
nnames.sort(function (a, b) {
a = a.toLowerCase();
b = b.toLowerCase();
if (a > b) return 1;
if (a < b) return -1;
return 0;
});
for (var l = 0; l < nnames.length; l++) {
result[nnames[l]] = list[nnames[l]].common.name || l;
if (typeof result[nnames[l]] === 'object') {
result[nnames[l]] = result[nnames[l]][systemLang] || result[nnames[l]].en;
}
}
$table.data('functions', result);
values2table(divId, values, onChange, onReady);
});
return;
}
$table.find('th').each(function () {
var name = $(this).data('name');
if (name) {
var obj = {
name: name,
type: $(this).data('type') || 'text',
def: $(this).data('default'),
style: $(this).data('style'),
tdstyle: $(this).data('tdstyle')
};
if (obj.type === 'checkbox') {
if (obj.def === 'false') obj.def = false;
if (obj.def === 'true') obj.def = true;
obj.def = !!obj.def;
} else if (obj.type === 'select' || obj.type === 'select multiple') {
var vals = ($(this).data('options') || '').split(';');
obj.options = {};
for (var v = 0; v < vals.length; v++) {
var parts = vals[v].split('/');
obj.options[parts[0]] = _(parts[1] || parts[0]);
if (v === 0) obj.def = (obj.def === undefined) ? parts[0] : obj.def;
}
} else {
obj.def = obj.def || '';
}
names.push(obj);
} else {
names.push(null);
}
name = $(this).data('buttons');
if (name) {
var bs = name.split(' ');
buttons.push(bs);
} else {
buttons.push(null);
}
});
$table.data('names', names);
var text = '';
for (var v = 0; v < values.length; v++) {
var idName = values[v] && values[v].id;
if (!idName && values[v]) {
if (names[0] === '_index') {
idName = values[v][names[1]];
} else {
idName = values[v][names[0]];
}
}
text += '
';
for (var i = 0; i < names.length; i++) {
text += '
';
if (isMaterialize) {
line += '';
}
} else if (names[i].type.substring(0, 6) === 'select') {
line += (names[i].type.substring(7, 16) === 'multiple' ? '';
} else {
line += '';
}
}
if (buttons[i]) {
style = 'text-align: center; white-space: nowrap;';
for (var b = 0; b < buttons[i].length; b++) {
if ((!v && buttons[i][b] === 'up') || (v === values.length - 1 && buttons[i][b] === 'down')) {
if (isMaterialize) {
line += 'add';
} else {
line += '';
}
} else {
if (isMaterialize) {
line += 'add';
} else {
line += '';
}
}
}
}
if (style.length || tdstyle.length) {
text += ' style="' + style + tdstyle + '">' + line + '';
} else {
text += '>' + line + '';
}
}
text += '
';
}
var $lines = $div.find('.table-lines');
if (!$lines.length) {
$table.append('');
$lines = $div.find('.table-lines');
}
$lines.html(text);
$lines.find('.values-input').each(function () {
var $this = $(this);
var type = $this.attr('type');
var name = $this.data('name');
var id = $this.data('index');
$this.data('old-value', values[id][name]);
if (type === 'checkbox') {
$this.prop('checked', values[id][name]);
} else {
$this.val(values[id][name]);
}
});
$lines.find('.values-buttons').each(function () {
var command = $(this).data('command');
if (command === 'copy') {
if (!isMaterialize) {
$(this).button({
icons: {primary: 'ui-icon-copy'},
text: false
})
.css({width: '1em', height: '1em'});
} else {
$(this).find('i').html('content_copy');
}
$(this).on('click', function () {
if (!$add.data('maxraw') || ($add.data('raw') < $add.data('maxraw'))) {
var id = $(this).data('index');
var elem = JSON.parse(JSON.stringify(values[id]));
values.push(elem);
onChange && onChange();
setTimeout(function () {
if (typeof tableEvents === 'function') {
tableEvents(values.length - 1, elem, 'add');
}
values2table(divId, values, onChange, onReady);
}, 100);
if ($add.data('maxraw')) {
$add.data('raw', $add.data('raw') + 1);
}
}
});
} else
if (command === 'delete') {
if (!isMaterialize) {
$(this).button({
icons: {primary: 'ui-icon-trash'},
text: false
})
.css({width: '1em', height: '1em'});
} else {
$(this).addClass('red').find('i').html('delete');
}
$(this).on('click', function () {
var id = $(this).data('index');
var elem = values[id];
values.splice(id, 1);
onChange && onChange();
setTimeout(function () {
if (typeof tableEvents === 'function') {
tableEvents(id, elem, 'delete');
}
values2table(divId, values, onChange, onReady);
}, 100);
if ($add.data('maxraw')) {
$add.data('raw', $add.data('raw') - 1);
}
});
} else if (command === 'up') {
if (!isMaterialize) {
$(this).button({
icons: {primary: 'ui-icon-triangle-1-n'},
text: false
})
.css({width: '1em', height: '1em'})
} else {
$(this).find('i').html('arrow_upward');
}
$(this).on('click', function () {
var id = $(this).data('index');
var elem = values[id];
values.splice(id, 1);
values.splice(id - 1, 0, elem);
onChange && onChange();
setTimeout(function () {
values2table(divId, values, onChange, onReady);
}, 100);
});
} else if (command === 'down') {
if (!isMaterialize) {
$(this).button({
icons: {primary: 'ui-icon-triangle-1-s'},
text: false
})
.css({width: '1em', height: '1em'});
} else {
$(this).find('i').html('arrow_downward');
}
$(this).on('click', function () {
var id = $(this).data('index');
var elem = values[id];
values.splice(id, 1);
values.splice(id + 1, 0, elem);
onChange && onChange();
setTimeout(function () {
values2table(divId, values, onChange, onReady);
}, 100);
});
} else if (command === 'pair') {
if (!isMaterialize) {
$(this).button({
icons: {primary: 'ui-icon-transferthick-e-w'},
text: false
})
.css({width: '1em', height: '1em'});
} else {
$(this).find('i').html('leak_add');
}
$(this).on('click', function () {
if (typeof tableEvents === 'function') {
var id = $(this).data('index');
var elem = values[id];
tableEvents(id, elem, 'pair');
}
}).attr('title', _('pair'));
} else if (command === 'unpair') {
if (!isMaterialize) {
$(this).button({
icons: {primary: 'ui-icon-scissors'},
text: false
})
.css({width: '1em', height: '1em'});
} else {
$(this).find('i').html('leak_remove');
}
$(this).on('click', function () {
if (typeof tableEvents === 'function') {
var id = $(this).data('index');
var elem = values[id];
tableEvents(id, elem, 'unpair');
}
}).attr('title', _('unpair'));
} else if (command === 'edit') {
if (!isMaterialize) {
$(this).button({
icons: {primary: 'ui-icon-pencil'},
text: false
})
.css({width: '1em', height: '1em'});
} else {
$(this).find('i').html('edit');
}
$(this).on('click', function () {
var id = $(this).data('index');
if (typeof editLine === 'function') {
setTimeout(function () {
editLine(id, JSON.parse(JSON.stringify(values[id])), function (err, id, newValues) {
if (!err) {
if (JSON.stringify(values[id]) !== JSON.stringify(newValues)) {
onChange && onChange();
values[id] = newValues;
values2table(divId, values, onChange, onReady);
}
}
});
}, 100);
}
});
}
});
$lines.find('.values-input').on('change.adaptersettings', function () {
if ($(this).attr('type') === 'checkbox') {
if ($(this).prop('checked').toString() !== $(this).data('old-value')) onChange();
values[$(this).data('index')][$(this).data('name')] = $(this).prop('checked');
} else {
if ($(this).val() !== $(this).data('old-value')) onChange();
values[$(this).data('index')][$(this).data('name')] = $(this).val();
}
}).on('keyup', function () {
$(this).trigger('change.adaptersettings');
});
}
if (isMaterialize) {
if (!divId) {
M.updateTextFields();
$('select').select();
} else {
M.updateTextFields('#' + divId);
$('#' + divId).find('select').select();
}
// workaround for materialize checkbox problem
$div.find('input[type="checkbox"]+span').off('click').on('click', function () {
var $input = $(this).prev();
if (!$input.prop('disabled')) {
$input.prop('checked', !$input.prop('checked')).trigger('change');
}
});
}
if (typeof onReady === 'function') onReady();
}
/**
* Extract the values from table.
*
* This function extracts the values from edit table, that was generated with values2table function.
*
* @param {string} divId name of the html element (or nothing).
* @return {object} array with values
*/
function table2values(divId) {
var $div;
if (!divId) {
$div = $('body');
} else {
$div = $('#' + divId);
}
var names = [];
$div.find('.table-values th').each(function () {
var name = $(this).data('name');
if (name) {
names.push(name);
} else {
names.push('___ignore___');
}
});
var values = [];
var j = 0;
$div.find('.table-lines tr').each(function () {
values[j] = {};
$(this).find('td').each(function () {
var $input = $(this).find('input');
if ($input.length) {
var name = $input.data('name');
if (name) {
if ($input.attr('type') === 'checkbox') {
values[j][name] = $input.prop('checked');
} else {
values[j][name] = $input.val();
}
}
}
var $select = $(this).find('select');
if ($select.length) {
var name = $select.data('name');
values[j][name] = $select.val() || '';
}
});
j++;
});
return values;
}