/** * Create edit table from javascript array. * * This function creates a html edit table. * *

 *   
* *
* * * * * * * * * * * *
ContextContextRoomRoomEnabled
*
*
*
* * @param {string} divId name of the html element (or empty). * @param {string} values data array * @param {object} options settings *

 *      {
 *          onChange: this function will be called if something changed. function (attr, index) {}
 *          onReady: called, when the table is ready (may be to modify some elements of it),
 *          maxRaw: maximal number of rows
 *      }
 *  
* @return {object} array with values */ function values2table(divId, values, options) { if (typeof divId === 'object') { options = values; values = divId; divId = ''; } var maxRaw = (options && options.maxRaw) || null; var onChange = (options && options.onChange) || null; var onReady = (options && options.onReady) || 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(); $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 maxRaw = $table.data('maxRaw'); 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, maxRaw); }, 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; } $table.data('rooms', result); values2table(divId, values, onChange, onReady, maxRaw); }); 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; } $table.data('functions', result); values2table(divId, values, onChange, onReady, maxRaw); }); 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'), 'class': ($(this).attr('class') || '').replace('translate', ''), style: $(this).data('style'), readOnly: $(this).data('readOnly'), 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) { buttons.push({ btn: name.split(' '), 'class': ($(this).attr('class') || '').replace('translate', ''), style: $(this).data('style'), tdstyle: $(this).data('tdstyle') }); } 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 += ''; } 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; ' + (buttons[i].style || '') + (buttons[i].tdstyle || ''); for (var b = 0; b < buttons[i].btn.length; b++) { if ((!v && buttons[i].btn[b] === 'up') || v === values.length - 1 && buttons[i].btn[b] === 'down') { line += ''; continue; } line += ''; } if (buttons[i]['class']) { text += ' class="' + buttons[i]['class'] + '" '; } } if (style.length || tdstyle.length) { text += ' style="' + style + tdstyle + '">' + line + ''; } else { text += '>' + line + ''; } } text += ''; } var $lines = $table.find('.table-lines'); if (!$lines.length) { $table.append(''); $lines = $table.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('a[data-command]').each(function () { var command = $(this).data('command'); if (command === '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, maxRaw); }, 100); if ($add.data('maxRaw')) { $add.data('raw', $add.data('raw') - 1); } }) .addClass('red') .find('.material-icons') .html('delete'); } else if (command === 'up') { $(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(id, values, onChange, onReady, maxRaw); }, 100); }).find('i').html('arrow_upward'); } else if (command === 'down') { $(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(id, values, onChange, onReady, maxRaw); }, 100); }).find('i').html('arrow_downward'); } else if (command === 'pair') { $(this).on('click', function () { if (typeof tableEvents === 'function') { var id = $(this).data('index'); var elem = values[id]; tableEvents(id, elem, 'pair'); } }).attr('title', _('pair')).find('i').html('insert_link'); } else if (command === 'unpair') { $(this).on('click', function () { if (typeof tableEvents === 'function') { var id = $(this).data('index'); var elem = values[id]; tableEvents(id, elem, 'unpair'); } }).attr('title', _('unpair')).find('i').html('not_interested'); } }); $lines.find('.values-input').on('change.adaptersettings', function () { var index = $(this).data('index'); var name = $(this).data('name'); if ($(this).attr('type') === 'checkbox') { if ($(this).prop('checked').toString() !== $(this).data('old-value') && onChange) onChange(name, index); values[index][name] = $(this).prop('checked'); } else { if ($(this).val() !== $(this).data('old-value') && onChange) onChange(name, index); values[index][name] = $(this).val(); } }).on('keyup', function () { $(this).trigger('change.adaptersettings'); }); } 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 ($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; }