make table additions in DS settings clearer

This commit is contained in:
Stephen Birarda 2017-01-30 13:57:13 -08:00
parent c1834a033c
commit 015aafe0fb
2 changed files with 162 additions and 91 deletions

View file

@ -125,6 +125,10 @@ tr.new-row {
background-color: #dff0d8;
}
tr.invalid-input {
background-color: #f2dede;
}
.graphable-stat {
text-align: center;
color: #5286BC;

View file

@ -38,14 +38,15 @@ var Settings = {
DOMAIN_ID_SELECTOR: '[name="metaverse.id"]',
ACCESS_TOKEN_SELECTOR: '[name="metaverse.access_token"]',
PLACES_TABLE_ID: 'places-table',
FORM_ID: 'settings-form'
FORM_ID: 'settings-form',
INVALID_ROW_CLASS: 'invalid-input'
};
var viewHelpers = {
getFormGroup: function(keypath, setting, values, isAdvanced) {
form_group = "<div class='form-group " +
(isAdvanced ? Settings.ADVANCED_CLASS : "") + " " +
(setting.deprecated ? Settings.DEPRECATED_CLASS : "" ) + "' " +
(setting.deprecated ? Settings.DEPRECATED_CLASS : "" ) + "' " +
"data-keypath='" + keypath + "'>";
setting_value = _(values).valueForKeyPath(keypath);
@ -891,23 +892,105 @@ function reloadSettings(callback) {
});
}
function validateInputs() {
// check if any new values are bad
var tables = $('table');
var inputsValid = true;
var tables = $('table');
// clear any current invalid rows
$('tr.' + Settings.INVALID_ROW_CLASS).removeClass(Settings.INVALID_ROW_CLASS);
function markParentRowInvalid(rowChild) {
$(rowChild).closest('tr').addClass(Settings.INVALID_ROW_CLASS);
}
_.each(tables, function(table) {
var inputs = $(table).find('tr.' + Settings.NEW_ROW_CLASS + ' input[data-changed="true"]');
var empty = false;
_.each(inputs, function(input){
var inputVal = $(input).val();
if (inputVal.length === 0) {
empty = true
markParentRowInvalid(input);
return;
}
});
if (empty) {
showErrorMessage("Error", "Empty field(s)");
inputsValid = false;
return
}
// validate keys specificially for spaces and equality to an existing key
var newKeys = $(table).find('tr.' + Settings.NEW_ROW_CLASS + ' td.key');
var keyWithSpaces = false;
var duplicateKey = false;
_.each(newKeys, function(keyCell) {
var keyVal = $(keyCell).children('input').val();
if (keyVal.indexOf(' ') !== -1) {
keyWithSpaces = true;
markParentRowInvalid(keyCell);
return;
}
// make sure we don't have duplicate keys in the table
var otherKeys = $(table).find('td.key').not(keyCell);
_.each(otherKeys, function(otherKeyCell) {
var keyInput = $(otherKeyCell).children('input');
if (keyInput.length) {
if ($(keyInput).val() == keyVal) {
duplicateKey = true;
}
} else if ($(otherKeyCell).html() == keyVal) {
duplicateKey = true;
}
if (duplicateKey) {
markParentRowInvalid(keyCell);
return;
}
});
});
if (keyWithSpaces) {
showErrorMessage("Error", "Key contains spaces");
inputsValid = false;
return
}
if (duplicateKey) {
showErrorMessage("Error", "Two keys cannot be identical");
inputsValid = false;
return;
}
});
return inputsValid;
}
var SETTINGS_ERROR_MESSAGE = "There was a problem saving domain settings. Please try again!";
function saveSettings() {
// disable any inputs not changed
$("input:not([data-changed])").each(function(){
$(this).prop('disabled', true);
});
// grab a JSON representation of the form via form2js
var formJSON = form2js('settings-form', ".", false, cleanupFormValues, true);
// check if we've set the basic http password - if so convert it to base64
// verify that the password and confirmation match before saving
var canPost = true;
if (formJSON["security"]) {
var password = formJSON["security"]["http_password"];
var verify_password = formJSON["security"]["verify_http_password"];
if (password && password.length > 0) {
if (password != verify_password) {
bootbox.alert({"message": "Passwords must match!", "title":"Password Error"});
@ -919,23 +1002,46 @@ function saveSettings() {
}
}
console.log("----- SAVING ------");
console.log(formJSON);
if (canPost && validateInputs()) {
// POST the form JSON to the domain-server settings.json endpoint so the settings are saved
// re-enable all inputs
$("input").each(function(){
$(this).prop('disabled', false);
});
// disable any inputs not changed
$("input:not([data-changed])").each(function(){
$(this).prop('disabled', true);
});
// remove focus from the button
$(this).blur();
// grab a JSON representation of the form via form2js
var formJSON = form2js('settings-form', ".", false, cleanupFormValues, true);
// POST the form JSON to the domain-server settings.json endpoint so the settings are saved
if (canPost) {
// check if we've set the basic http password - if so convert it to base64
if (formJSON["security"]) {
var password = formJSON["security"]["http_password"];
if (password && password.length > 0) {
formJSON["security"]["http_password"] = sha256_digest(password);
}
}
console.log("----- SAVING ------");
console.log(formJSON);
// re-enable all inputs
$("input").each(function(){
$(this).prop('disabled', false);
});
// remove focus from the button
$(this).blur();
// POST the form JSON to the domain-server settings.json endpoint so the settings are saved
postSettings(formJSON);
}
}
// disable any inputs not changed
$("input:not([data-changed])").each(function(){
$(this).prop('disabled', true);
});
$('body').on('click', '.save-button', function(e){
saveSettings();
return false;
@ -1110,8 +1216,9 @@ function makeTable(setting, keypath, setting_value) {
if (setting.can_add_new_categories) {
html += makeTableCategoryInput(setting, numVisibleColumns);
}
if (setting.can_add_new_rows || setting.can_add_new_categories) {
html += makeTableInputs(setting, {}, "");
html += makeTableHiddenInputs(setting, {}, "");
}
}
html += "</table>"
@ -1137,7 +1244,7 @@ function makeTableCategoryHeader(categoryKey, categoryValue, numVisibleColumns,
return html;
}
function makeTableInputs(setting, initialValues, categoryValue) {
function makeTableHiddenInputs(setting, initialValues, categoryValue) {
var html = "<tr class='inputs'" + (setting.can_add_new_categories && !categoryValue ? " hidden" : "") + " " +
(categoryValue ? ("data-category='" + categoryValue + "'") : "") + " " +
(setting.categorize_by_key ? ("data-keep-field='" + setting.categorize_by_key + "'") : "") + ">";
@ -1148,7 +1255,7 @@ function makeTableInputs(setting, initialValues, categoryValue) {
if (setting.key) {
html += "<td class='key' name='" + setting.key.name + "'>\
<input type='text' class='form-control' placeholder='" + (_.has(setting.key, 'placeholder') ? setting.key.placeholder : "") + "' value=''>\
<input type='text' style='display: none;' class='form-control' placeholder='" + (_.has(setting.key, 'placeholder') ? setting.key.placeholder : "") + "' value=''>\
</td>"
}
@ -1157,14 +1264,14 @@ function makeTableInputs(setting, initialValues, categoryValue) {
if (col.type === "checkbox") {
html +=
"<td class='" + Settings.DATA_COL_CLASS + "'name='" + col.name + "'>" +
"<input type='checkbox' class='form-control table-checkbox' " +
"<input type='checkbox' style='display: none;' class='form-control table-checkbox' " +
"name='" + col.name + "'" + (defaultValue ? " checked" : "") + "/>" +
"</td>";
} else {
html +=
"<td " + (col.hidden ? "style='display: none;'" : "") + " class='" + Settings.DATA_COL_CLASS + "' " +
"name='" + col.name + "'>" +
"<input type='text' class='form-control' placeholder='" + (col.placeholder ? col.placeholder : "") + "' " +
"<input type='text' style='display: none;' class='form-control' placeholder='" + (col.placeholder ? col.placeholder : "") + "' " +
"value='" + (defaultValue || "") + "' data-default='" + (defaultValue || "") + "'" +
(col.readonly ? " readonly" : "") + ">" +
"</td>";
@ -1244,49 +1351,17 @@ function addTableRow(row) {
var columns = row.parent().children('.' + Settings.DATA_ROW_CLASS);
var input_clone = row.clone();
if (!isArray) {
// Check key spaces
var key = row.children(".key").children("input").val()
if (key.indexOf(' ') !== -1) {
showErrorMessage("Error", "Key contains spaces")
return
}
// Check keys with the same name
var equals = false;
_.each(columns.children(".key"), function(element) {
if ($(element).text() === key) {
equals = true
return
}
})
if (equals) {
showErrorMessage("Error", "Two keys cannot be identical")
return
}
// show the key input
var keyInput = row.children(".key").children("input");
}
// Check empty fields
var empty = false;
_.each(row.children('.' + Settings.DATA_COL_CLASS + ' input'), function(element) {
if ($(element).val().length === 0) {
empty = true
return
}
})
if (empty) {
showErrorMessage("Error", "Empty field(s)")
return
}
var input_clone = row.clone()
// Change input row to data row
var table = row.parents("table")
var setting_name = table.attr("name")
var full_name = setting_name + "." + key
row.addClass(Settings.DATA_ROW_CLASS + " " + Settings.NEW_ROW_CLASS)
row.removeClass("inputs")
var table = row.parents("table");
var setting_name = table.attr("name");
row.addClass(Settings.DATA_ROW_CLASS + " " + Settings.NEW_ROW_CLASS);
_.each(row.children(), function(element) {
if ($(element).hasClass("numbered")) {
@ -1308,34 +1383,17 @@ function addTableRow(row) {
anchor.addClass(Settings.DEL_ROW_SPAN_CLASSES)
} else if ($(element).hasClass("key")) {
var input = $(element).children("input")
$(element).html(input.val())
input.remove()
input.show();
} else if ($(element).hasClass(Settings.DATA_COL_CLASS)) {
// Hide inputs
var input = $(element).find("input")
var isCheckbox = false;
var isTime = false;
if (input.hasClass("table-checkbox")) {
input = $(input).parent();
isCheckbox = true;
} else if (input.hasClass("table-time")) {
input = $(input).parent();
isTime = true;
}
// show inputs
var input = $(element).find("input");
input.show();
var val = input.val();
if (isCheckbox) {
// don't hide the checkbox
val = $(input).find("input").is(':checked');
} else if (isTime) {
// don't hide the time
} else {
input.attr("type", "hidden")
}
var isCheckbox = input.hasClass("table-checkbox");
if (isArray) {
var row_index = row.siblings('.' + Settings.DATA_ROW_CLASS).length
var key = $(element).attr('name')
var key = $(element).attr('name');
// are there multiple columns or just one?
// with multiple we have an array of Objects, with one we have an array of whatever the value type is
@ -1347,17 +1405,21 @@ function addTableRow(row) {
input.attr("name", setting_name + "[" + row_index + "]" + (num_columns > 1 ? "." + key : ""))
}
} else {
input.attr("name", full_name + "." + $(element).attr("name"))
// because the name of the setting in question requires the key
// setup a hook to change the HTML name of the element whenever the key changes
var colName = $(element).attr("name");
keyInput.on('change', function(){
input.attr("name", setting_name + "." + $(this).val() + "." + colName);
});
}
if (isCheckbox) {
$(input).find("input").attr("data-changed", "true");
} else {
input.attr("data-changed", "true");
$(element).append(val);
}
} else {
console.log("Unknown table element")
console.log("Unknown table element");
}
});
@ -1387,7 +1449,12 @@ function deleteTableRow($row) {
$row.empty();
if (!isArray) {
$row.html("<input type='hidden' class='form-control' name='" + $row.attr('name') + "' data-changed='true' value=''>");
if ($row.attr('name')) {
$row.html("<input type='hidden' class='form-control' name='" + $row.attr('name') + "' data-changed='true' value=''>");
} else {
// for rows that didn't have a key, simply remove the row
$row.remove();
}
} else {
if ($table.find('.' + Settings.DATA_ROW_CLASS + "[data-category='" + categoryName + "']").length <= 1) {
// This is the last row of the category, so delete the header