mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-11-04 15:11:31 +08:00 
			
		
		
		
	autocomplete for attribute values, closes #31
This commit is contained in:
		
							parent
							
								
									a3b31fab54
								
							
						
					
					
						commit
						52817504d1
					
				@ -106,13 +106,13 @@ const attributesDialog = (function() {
 | 
				
			|||||||
    async function showDialog() {
 | 
					    async function showDialog() {
 | 
				
			||||||
        glob.activeDialog = dialogEl;
 | 
					        glob.activeDialog = dialogEl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        await attributesModel.loadAttributes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        dialogEl.dialog({
 | 
					        dialogEl.dialog({
 | 
				
			||||||
            modal: true,
 | 
					            modal: true,
 | 
				
			||||||
            width: 800,
 | 
					            width: 800,
 | 
				
			||||||
            height: 500
 | 
					            height: 500
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					 | 
				
			||||||
        attributesModel.loadAttributes();
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $(document).bind('keydown', 'alt+a', e => {
 | 
					    $(document).bind('keydown', 'alt+a', e => {
 | 
				
			||||||
@ -123,18 +123,50 @@ const attributesDialog = (function() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    ko.applyBindings(attributesModel, document.getElementById('attributes-dialog'));
 | 
					    ko.applyBindings(attributesModel, document.getElementById('attributes-dialog'));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $(document).on('focus', '.attribute-name:not(.ui-autocomplete-input)', function (e) {
 | 
					    $(document).on('focus', '.attribute-name', function (e) {
 | 
				
			||||||
        $(this).autocomplete({
 | 
					        if (!$(this).hasClass("ui-autocomplete-input")) {
 | 
				
			||||||
            // shouldn't be required and autocomplete should just accept array of strings, but that fails
 | 
					            $(this).autocomplete({
 | 
				
			||||||
            // because we have overriden filter() function in init.js
 | 
					                // shouldn't be required and autocomplete should just accept array of strings, but that fails
 | 
				
			||||||
            source: attributeNames.map(attr => {
 | 
					                // because we have overriden filter() function in init.js
 | 
				
			||||||
                return {
 | 
					                source: attributeNames.map(attr => {
 | 
				
			||||||
                    label: attr,
 | 
					                    return {
 | 
				
			||||||
                    value: attr
 | 
					                        label: attr,
 | 
				
			||||||
                }
 | 
					                        value: attr
 | 
				
			||||||
            }),
 | 
					                    }
 | 
				
			||||||
            minLength: 0
 | 
					                }),
 | 
				
			||||||
        });
 | 
					                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());
 | 
					        $(this).autocomplete("search", $(this).val());
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
				
			|||||||
@ -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) => {
 | 
					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");
 | 
					    const names = await sql.getColumn("SELECT DISTINCT name FROM attributes");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (const attr of attributes.BUILTIN_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);
 | 
					    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;
 | 
					module.exports = router;
 | 
				
			||||||
@ -406,7 +406,7 @@
 | 
				
			|||||||
                <div style="color: red" data-bind="if: $parent.isEmptyName($index())">Attribute name can't be empty.</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, 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>
 | 
					              </td>
 | 
				
			||||||
            </tr>
 | 
					            </tr>
 | 
				
			||||||
          </tbody>
 | 
					          </tbody>
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user