nice UI for attributes with validation

This commit is contained in:
azivner 2018-02-04 17:22:21 -05:00
parent 2c5115003b
commit 873ea67e9c
2 changed files with 85 additions and 16 deletions

View File

@ -14,26 +14,94 @@ const attributesDialog = (function() {
const attributes = await server.get('notes/' + noteId + '/attributes'); const attributes = await server.get('notes/' + noteId + '/attributes');
this.attributes(attributes); self.attributes(attributes.map(ko.observable));
addLastEmptyRow();
}; };
this.addNewRow = function() { function isValid() {
self.attributes.push({ for (let attrs = self.attributes(), i = 0; i < attrs.length; i++) {
attributeId: '', if (self.isEmptyName(i) || self.isNotUnique(i)) {
name: '', return false;
value: '' }
}); }
};
return true;
}
this.save = async function() { this.save = async function() {
if (!isValid()) {
alert("Please fix all validation errors and try saving again.");
return;
}
const noteId = noteEditor.getCurrentNoteId(); const noteId = noteEditor.getCurrentNoteId();
const attributes = await server.put('notes/' + noteId + '/attributes', this.attributes()); const attributesToSave = self.attributes()
.map(attr => attr())
.filter(attr => attr.attributeId !== "" || attr.name !== "");
self.attributes(attributes); const attributes = await server.put('notes/' + noteId + '/attributes', attributesToSave);
self.attributes(attributes.map(ko.observable));
addLastEmptyRow();
showMessage("Attributes have been saved."); showMessage("Attributes have been saved.");
}; };
function addLastEmptyRow() {
const attrs = self.attributes();
const last = attrs[attrs.length - 1]();
// console.log("last", attrs.map(attr => attr()));
if (last.name.trim() !== "" || last.value !== "") {
console.log("Adding new row");
self.attributes.push(ko.observable({
attributeId: '',
name: '',
value: ''
}));
}
}
this.attributeChanged = function (row) {
console.log(row);
addLastEmptyRow();
for (const attr of self.attributes()) {
if (row.attributeId === attr().attributeId) {
attr.valueHasMutated();
}
}
};
this.isNotUnique = function(index) {
const cur = self.attributes()[index]();
if (cur.name.trim() === "") {
return false;
}
for (let attrs = self.attributes(), i = 0; i < attrs.length; i++) {
const attr = attrs[i]();
if (index !== i && cur.name === attr.name) {
return true;
}
}
return false;
};
this.isEmptyName = function(index) {
const cur = self.attributes()[index]();
return cur.name.trim() === "" && (cur.attributeId !== "" || cur.value !== "");
}
} }
async function showDialog() { async function showDialog() {

View File

@ -383,10 +383,8 @@
<div id="attributes-dialog" title="Note attributes" style="display: none; padding: 20px;"> <div id="attributes-dialog" title="Note attributes" style="display: none; padding: 20px;">
<form data-bind="submit: save"> <form data-bind="submit: save">
<div style="display: flex; justify-content: space-between; padding: 15px; padding-top: 0;"> <div style="text-align: center">
<button class="btn-default" type="button" data-bind="click: addNewRow">Add new attribute</button> <button class="btn-primary btn-large" type="submit">Save</button>
<button class="btn-primary" type="submit">Save</button>
</div> </div>
<div style="height: 97%; overflow: auto"> <div style="height: 97%; overflow: auto">
@ -402,10 +400,13 @@
<tr> <tr>
<td data-bind="text: attributeId"></td> <td data-bind="text: attributeId"></td>
<td> <td>
<input type="text" data-bind="value: name"/> <input type="text" data-bind="value: name, event: { change: $parent.attributeChanged }"/>
<div style="color: red" data-bind="if: $parent.isNotUnique($index())">Attribute name must be unique per note.</div>
<div style="color: red" data-bind="if: $parent.isEmptyName($index())">Attribute name can't be empty.</div>
</td> </td>
<td> <td>
<input type="text" data-bind="value: value" style="width: 300px"/> <input type="text" data-bind="value: value, event: { change: $parent.attributeChanged }" style="width: 300px"/>
</td> </td>
</tr> </tr>
</tbody> </tbody>