var path = location.pathname; var parts = path.split('/'); parts.splice(-3); if (location.pathname.match(/^\/admin\//)) { parts = []; } var systemConfig; var socket = io.connect('/', {path: parts.join('/') + '/socket.io'}); var instance = window.location.search.slice(1); var common = null; // common information of adapter var host = null; // host object on which the adapter runs var changed = false; var certs = []; var adapter = ''; var onChangeSupported = false; var isMaterialize = false; var ___onChange = null; function preInit () { 'use strict'; var tmp = window.location.pathname.split('/'); adapter = tmp[tmp.length - 2]; var id = 'system.adapter.' + adapter + '.' + instance; // Extend dictionary with standard words for adapter if (typeof systemDictionary === 'undefined') systemDictionary = {}; systemDictionary.save = {"en": "Save", "cn": "保存"}, systemDictionary.saveclose = {"en": "Save and close", "cn": "保存并退出"}, systemDictionary.none = {"en": "none", "cn": "none"}, systemDictionary.nonerooms = {"en": "", "cn": ""}, systemDictionary.nonefunctions = {"en": "", "cn": ""}, systemDictionary.all = {"en": "all", "cn": "全部"}, systemDictionary['Device list'] = {"en": "Device list", "cn": "设备列表"}, systemDictionary['new device'] = {"en": "new device", "cn": "新设备"}, systemDictionary.edit = {"en": "edit", "cn": "编辑"}, systemDictionary.delete = {"en": "delete", "cn": "删除"}, systemDictionary.pair = {"en": "pair", "cn": "配对"}, systemDictionary.unpair = {"en": "unpair", "cn": "解除配对"}, systemDictionary.ok = {"en": "Ok", "cn": "确认"}, systemDictionary.cancel = {"en": "Cancel", "cn": "取消"}, systemDictionary.Message = {"en": "Message", "cn": "信息"}, systemDictionary.close = {"en": "Close", "cn": "关闭"}, systemDictionary.htooltip = {"en": "Click for help", "cn": "帮助"}, systemDictionary.saveConfig = { "en": "Save configuration to file", "cn": "导出配置信息" }; systemDictionary.loadConfig = { "en": "Load configuration from file", "cn": "从JSON文件导入" }; systemDictionary.otherConfig = { "en": "Configuration from other adapter %s", "cn": "Configuration from other adapter %s" }; systemDictionary.invalidConfig = { "en": "Invalid JSON file" }; systemDictionary.configLoaded = { "en": "Configuration was successfully loaded", "cn": "Configuration was successfully loaded" }; systemDictionary.maxTableRaw = { "en": "Maximum number of allowed raws", "cn": "Maximum number of allowed raws" }; systemDictionary.maxTableRawInfo = {"en": "Warning", "cn": "提示"}; systemDictionary["Main settings"] = { "en": "Main settings", "cn": "基本设置" }; systemDictionary["Let's Encrypt SSL"] = { "en": "Let's Encrypt Certificates", "cn": "Let's Encrypt Certificates" }; systemDictionary["Please activate secure communication"] = { "en": "Please activate secure communication", "cn": "Please activate secure communication" }; //socket.on('connection', function () { loadSystemConfig(function () { if (typeof translateAll === 'function') translateAll(); loadSettings(prepareTooltips); }); //}); var $body = $('body'); $body.wrapInner('
'); /*$body.prepend(''); */ $body.append( ''); var $navButtons = $('.dialog-config-buttons'); $navButtons.find('.btn-save').on('click', function () { if (typeof save === 'undefined') { alert('Please implement save function in your admin/index.html'); return; } save(function (obj, common, redirect) { if (redirect && parent && parent.adapterRedirect) { parent.adapterRedirect(redirect); } saveSettings(obj, common); }); }); $navButtons.find('.btn-save-close').on('click', function () { if (typeof save === 'undefined') { alert('Please implement save function in your admin/index.html'); return; } save(function (obj, common, redirect) { if (redirect && parent && parent.adapterRedirect) { parent.adapterRedirect(redirect); } saveSettings(obj, common, function () { // window.close(); if (typeof parent !== 'undefined' && parent && parent.$iframeDialog && typeof parent.$iframeDialog.close === 'function') { parent.$iframeDialog.close(); } }); }); }); $navButtons.find('.btn-cancel').on('click', function () { if (typeof parent !== 'undefined' && parent && parent.$iframeDialog && typeof parent.$iframeDialog.close === 'function') { parent.$iframeDialog.close(); } }); function saveSettings(native, common, callback) { if (typeof common === 'function') { callback = common; common = null; } socket.emit('getObject', id, function (err, oldObj) { if (!oldObj) oldObj = {}; for (var a in native) { if (native.hasOwnProperty(a)) { oldObj.native[a] = native[a]; } } if (common) { for (var b in common) { if (common.hasOwnProperty(b)) { oldObj.common[b] = common[b]; } } } if (onChangeSupported) { $navButtons.find('.btn-save').addClass('disabled'); $navButtons.find('.btn-save-close').addClass('disabled'); $navButtons.find('.btn-cancel').find('span').html(_('close')); } socket.emit('setObject', id, oldObj, function (err) { if (err) { showMessage(err, _('Error'), 'alert'); return; } changed = false; if (callback) callback(); }); }); } // Read language settings function loadSystemConfig(callback) { socket.emit('getObject', 'system.config', function (err, res) { if (!err && res && res.common) { systemLang = res.common.language || systemLang; systemConfig = res; } socket.emit('getObject', 'system.certificates', function (err, res) { if (!err && res) { if (res.native && res.native.certificates) { certs = []; for (var c in res.native.certificates) { if (!res.native.certificates.hasOwnProperty(c) || !res.native.certificates[c]) continue; // If it is filename, it could be everything if (res.native.certificates[c].length < 700 && (res.native.certificates[c].indexOf('/') !== -1 || res.native.certificates[c].indexOf('\\') !== -1)) { var __cert = { name: c, type: '' }; if (c.toLowerCase().indexOf('private') !== -1) { __cert.type = 'private'; } else if (res.native.certificates[c].toLowerCase().indexOf('private') !== -1) { __cert.type = 'private'; } else if (c.toLowerCase().indexOf('public') !== -1) { __cert.type = 'public'; } else if (res.native.certificates[c].toLowerCase().indexOf('public') !== -1) { __cert.type = 'public'; } certs.push(__cert); continue; } var _cert = { name: c, type: (res.native.certificates[c].substring(0, '-----BEGIN RSA PRIVATE KEY'.length) === '-----BEGIN RSA PRIVATE KEY' || res.native.certificates[c].substring(0, '-----BEGIN PRIVATE KEY'.length) === '-----BEGIN PRIVATE KEY') ? 'private' : 'public' }; if (_cert.type === 'public') { var m = res.native.certificates[c].split('-----END CERTIFICATE-----'); var count = 0; for (var _m = 0; _m < m.length; _m++) { if (m[_m].replace(/\r\n|\r|\n/, '').trim()) count++; } if (count > 1) _cert.type = 'chained'; } certs.push(_cert); } } } if (callback) callback(); }); }); } // callback if something changed function onChange(isChanged) { onChangeSupported = true; if (typeof isChanged === 'boolean' && isChanged === false) { changed = false; $navButtons.find('.btn-save').addClass('disabled'); $navButtons.find('.btn-save-close').addClass('disabled'); $navButtons.find('.btn-cancel').find('span').html(_('close')); } else { changed = true; $navButtons.find('.btn-save').removeClass('disabled'); $navButtons.find('.btn-save-close').removeClass('disabled'); $navButtons.find('.btn-cancel').find('span').html(_('cancel')); } } function loadSettings(callback) { socket.emit('getObject', id, function (err, res) { if (!err && res && res.native) { $('.adapter-instance').html(adapter + '.' + instance); $('.adapter-config').html('system.adapter.' + adapter + '.' + instance); common = res.common; if (res.common && res.common.name) $('.adapter-name').html(res.common.name); if (typeof load === 'undefined') { alert('Please implement save function in your admin/index.html'); } else { load(res.native, onChange); // init selects if (isMaterialize) { $('select').select(); M.updateTextFields(); // workaround for materialize checkbox problem $('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 callback === 'function') { callback(); } } else { if (typeof callback === 'function') { callback(); } alert('error loading settings for ' + id + '\n\n' + err); } }); } ___onChange = onChange; } $(document).ready(function () { 'use strict'; if (window.location.pathname.indexOf('/index_m.html') === -1) { // load materialize var cssLink = document.createElement('link'); cssLink.href = '../../lib/css/materialize.css'; cssLink.type = 'text/css'; cssLink.rel = 'stylesheet'; cssLink.media = 'screen,print'; document.getElementsByTagName('head')[0].appendChild(cssLink); // load materialize.js var jsLink = document.createElement('script'); jsLink.onload = preInit; jsLink.src = '../../lib/js/materialize.js'; document.head.appendChild(jsLink); } else { isMaterialize = true; preInit(); } }); function handleFileSelect(evt) { var f = evt.target.files[0]; if (f) { var r = new FileReader(); r.onload = function(e) { var contents = e.target.result; try { var json = JSON.parse(contents); if (json.native && json.common) { if (json.common.name !== common.name) { showError(_('otherConfig', json.common.name)); } else { load(json.native, ___onChange); // init selects if (isMaterialize) { $('select').select(); M.updateTextFields(); // workaround for materialize checkbox problem $('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'); } }); } ___onChange(); showToast(null, _('configLoaded')); } } else { showError(_('invalidConfig')); } } catch (e) { showError(e.toString()); } }; r.readAsText(f); } else { alert('Failed to open JSON File'); } } function generateFile(filename, obj) { var el = document.createElement('a'); el.setAttribute('href', 'data:application/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(obj, null, 2))); el.setAttribute('download', filename); el.style.display = 'none'; document.body.appendChild(el); el.click(); document.body.removeChild(el); } function prepareTooltips() { if (isMaterialize) { // init tabs $('.tabs').mtabs(); var buttonsText = ''; if (common && common.readme) { buttonsText += ' ' + ' live_help' + ' '; } buttonsText += ' ' + ' file_upload' + ' '; buttonsText += ' ' + ' file_download' + ' '; if (buttonsText) { // add help link after logo var $logo = $('.logo').first().parent(); if ($logo.length) { $('
';
} else if (tooltip) {
icon += '
';
}
if (icon) {
$(this).html(icon);
}
});
$('.admin-text').each(function () {
var id = $(this).data('id');
if (!id) {
var $prev = $(this).prev();
var $input = $prev.find('input');
if (!$input.length) $input = $prev.find('select');
if (!$input.length) $input = $prev.find('textarea');
if (!$input.length) {
$prev = $prev.parent();
$input = $prev.find('input');
if (!$input.length) $input = $prev.find('select');
if (!$input.length) $input = $prev.find('textarea');
}
if ($input.length) id = $input.attr('id');
}
if (!id) return;
// check if translation for this exist
if (systemDictionary['info_' + id]) {
$(this).html('' + (systemDictionary['info_' + id][systemLang] || systemDictionary['info_' + id].en) + '');
}
});
}
}
function showMessageJQ(message, title, icon, width) {
var $dialogMessage = $('#dialog-message-settings');
if (!$dialogMessage.length) {
$('body').append('');
$dialogMessage = $('#dialog-message-settings');
$dialogMessage.dialog({
autoOpen: false,
modal: true,
buttons: [
{
text: _('Ok'),
click: function () {
$(this).dialog('close');
}
}
]
});
}
$dialogMessage.dialog('option', 'width', width + 500);
if (typeof _ !== 'undefined') {
$dialogMessage.dialog('option', 'title', title || _('Message'));
} else {
$dialogMessage.dialog('option', 'title', title || 'Message');
}
$('#dialog-message-text-settings').html(message);
if (icon) {
$('#dialog-message-icon-settings')
.show()
.attr('class', '')
.addClass('ui-icon ui-icon-' + icon);
} else {
$('#dialog-message-icon-settings').hide();
}
$dialogMessage.dialog('open');
}
function showMessage(message, title, icon) {
if (!isMaterialize) {
return showMessageJQ(message, title, icon);
}
var $dialogMessage;
// noinspection JSJQueryEfficiency
$dialogMessage = $('#dialog-message');
if (!$dialogMessage.length) {
$('body').append(
'| Context | Room | Room | Enabled |
|---|
*
*
*
*
*
*
* 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;
}