autocomplete for attribute values, closes #31

This commit is contained in:
azivner 2018-02-04 19:43:11 -05:00
parent a3b31fab54
commit 52817504d1
3 changed files with 55 additions and 17 deletions

View File

@ -106,13 +106,13 @@ const attributesDialog = (function() {
async function showDialog() {
glob.activeDialog = dialogEl;
await attributesModel.loadAttributes();
dialogEl.dialog({
modal: true,
width: 800,
height: 500
});
attributesModel.loadAttributes();
}
$(document).bind('keydown', 'alt+a', e => {
@ -123,18 +123,50 @@ const attributesDialog = (function() {
ko.applyBindings(attributesModel, document.getElementById('attributes-dialog'));
$(document).on('focus', '.attribute-name:not(.ui-autocomplete-input)', function (e) {
$(this).autocomplete({
// shouldn't be required and autocomplete should just accept array of strings, but that fails
// because we have overriden filter() function in init.js
source: attributeNames.map(attr => {
return {
label: attr,
value: attr
}
}),
minLength: 0
});
$(document).on('focus', '.attribute-name', function (e) {
if (!$(this).hasClass("ui-autocomplete-input")) {
$(this).autocomplete({
// shouldn't be required and autocomplete should just accept array of strings, but that fails
// because we have overriden filter() function in init.js
source: attributeNames.map(attr => {
return {
label: attr,
value: attr
}
}),
minLength: 0
});
}
$(this).autocomplete("search", $(this).val());
});
$(document).on('focus', '.attribute-value', async function (e) {
if (!$(this).hasClass("ui-autocomplete-input")) {
const attributeName = $(this).parent().parent().find('.attribute-name').val();
if (attributeName.trim() === "") {
return;
}
const attributeValues = await server.get('attributes/values/' + encodeURIComponent(attributeName));
if (attributeValues.length === 0) {
return;
}
$(this).autocomplete({
// shouldn't be required and autocomplete should just accept array of strings, but that fails
// because we have overriden filter() function in init.js
source: attributeValues.map(attr => {
return {
label: attr,
value: attr
}
}),
minLength: 0
});
}
$(this).autocomplete("search", $(this).val());
});

View File

@ -47,8 +47,6 @@ router.put('/notes/:noteId/attributes', auth.checkApiAuth, wrap(async (req, res,
}));
router.get('/attributes/names', auth.checkApiAuth, wrap(async (req, res, next) => {
const noteId = req.params.noteId;
const names = await sql.getColumn("SELECT DISTINCT name FROM attributes");
for (const attr of attributes.BUILTIN_ATTRIBUTES) {
@ -62,4 +60,12 @@ router.get('/attributes/names', auth.checkApiAuth, wrap(async (req, res, next) =
res.send(names);
}));
router.get('/attributes/values/:attributeName', auth.checkApiAuth, wrap(async (req, res, next) => {
const attributeName = req.params.attributeName;
const values = await sql.getColumn("SELECT DISTINCT value FROM attributes WHERE name = ? ORDER BY value", [attributeName]);
res.send(values);
}));
module.exports = router;

View File

@ -406,7 +406,7 @@
<div style="color: red" data-bind="if: $parent.isEmptyName($index())">Attribute name can't be empty.</div>
</td>
<td>
<input type="text" data-bind="value: value, event: { change: $parent.attributeChanged }" style="width: 300px"/>
<input type="text" class="attribute-value" data-bind="value: value, event: { change: $parent.attributeChanged }" style="width: 300px"/>
</td>
</tr>
</tbody>