mirror of
https://github.com/zadam/trilium.git
synced 2025-03-01 14:22:32 +01:00
autocomplete for add link dialog, #203
This commit is contained in:
parent
a0f362457e
commit
90dbe637ed
@ -15,7 +15,6 @@ const $prefixFormGroup = $("#add-link-prefix-form-group");
|
||||
const $linkTypeDiv = $("#add-link-type-div");
|
||||
const $linkTypes = $("input[name='add-link-type']");
|
||||
const $linkTypeHtml = $linkTypes.filter('input[value="html"]');
|
||||
const $showRecentNotesButton = $dialog.find(".show-recent-notes-button");
|
||||
|
||||
function setLinkType(linkType) {
|
||||
$linkTypes.each(function () {
|
||||
@ -51,50 +50,31 @@ async function showDialog() {
|
||||
$linkTitle.val(noteTitle);
|
||||
}
|
||||
|
||||
await $autoComplete.autocomplete({
|
||||
source: noteAutocompleteService.autocompleteSource,
|
||||
minLength: 0,
|
||||
change: async (event, ui) => {
|
||||
if (!ui.item) {
|
||||
return;
|
||||
}
|
||||
noteAutocompleteService.initNoteAutocomplete($autoComplete);
|
||||
|
||||
const notePath = linkService.getNotePathFromLabel(ui.item.value);
|
||||
$autoComplete.on('autocomplete:selected', function(event, suggestion, dataset) {
|
||||
if (!suggestion.path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!notePath) {
|
||||
return;
|
||||
}
|
||||
const noteId = treeUtils.getNoteIdFromNotePath(suggestion.path);
|
||||
|
||||
const noteId = treeUtils.getNoteIdFromNotePath(notePath);
|
||||
|
||||
if (noteId) {
|
||||
await setDefaultLinkTitle(noteId);
|
||||
}
|
||||
},
|
||||
select: function (event, ui) {
|
||||
if (ui.item.value === 'No results') {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
// this is called when user goes through autocomplete list with keyboard
|
||||
// at this point the item isn't selected yet so we use supplied ui.item to see WHERE the cursor is
|
||||
focus: async (event, ui) => {
|
||||
const notePath = linkService.getNotePathFromLabel(ui.item.value);
|
||||
const noteId = treeUtils.getNoteIdFromNotePath(notePath);
|
||||
|
||||
await setDefaultLinkTitle(noteId);
|
||||
|
||||
event.preventDefault();
|
||||
if (noteId) {
|
||||
setDefaultLinkTitle(noteId);
|
||||
}
|
||||
});
|
||||
|
||||
showRecentNotes();
|
||||
$autoComplete.on('autocomplete:cursorchanged', function(event, suggestion, dataset) {
|
||||
const noteId = treeUtils.getNoteIdFromNotePath(suggestion.path);
|
||||
|
||||
setDefaultLinkTitle(noteId);
|
||||
});
|
||||
|
||||
noteAutocompleteService.showRecentNotes($autoComplete);
|
||||
}
|
||||
|
||||
$form.submit(() => {
|
||||
const value = $autoComplete.val();
|
||||
|
||||
const notePath = linkService.getNotePathFromLabel(value);
|
||||
const notePath = $autoComplete.getSelectedPath();
|
||||
const noteId = treeUtils.getNoteIdFromNotePath(notePath);
|
||||
|
||||
if (notePath) {
|
||||
@ -131,6 +111,9 @@ $form.submit(() => {
|
||||
$dialog.modal('hide');
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.error("No path to add link.");
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
@ -152,14 +135,8 @@ function linkTypeChanged() {
|
||||
$linkTypeDiv.toggle(!hasSelection());
|
||||
}
|
||||
|
||||
function showRecentNotes() {
|
||||
$autoComplete.autocomplete("search", "");
|
||||
}
|
||||
|
||||
$linkTypes.change(linkTypeChanged);
|
||||
|
||||
$showRecentNotesButton.click(showRecentNotes);
|
||||
|
||||
export default {
|
||||
showDialog
|
||||
};
|
@ -5,7 +5,6 @@ import noteAutocompleteService from '../services/note_autocomplete.js';
|
||||
const $dialog = $("#jump-to-note-dialog");
|
||||
const $autoComplete = $("#jump-to-note-autocomplete");
|
||||
const $showInFullTextButton = $("#show-in-full-text-button");
|
||||
const $showRecentNotesButton = $dialog.find(".show-recent-notes-button");
|
||||
|
||||
$dialog.on("shown.bs.modal", e => $autoComplete.focus());
|
||||
|
||||
@ -45,11 +44,8 @@ function showInFullText(e) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
$showInFullTextButton.click(showInFullText);
|
||||
|
||||
$showRecentNotesButton.click(noteAutocompleteService.showRecentNotes);
|
||||
|
||||
$dialog.bind('keydown', 'ctrl+return', showInFullText);
|
||||
|
||||
export default {
|
||||
|
@ -44,11 +44,17 @@ function initNoteAutocomplete($el) {
|
||||
displayKey: 'title',
|
||||
templates: {
|
||||
suggestion: function(suggestion) {
|
||||
return suggestion.title;
|
||||
return suggestion.highlighted;
|
||||
}
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
||||
$el.on('autocomplete:selected', function(event, suggestion, dataset) {
|
||||
$el.prop("data-selected-path", suggestion.path);
|
||||
});
|
||||
|
||||
$el.getSelectedPath = () => $el.prop("data-selected-path");
|
||||
}
|
||||
|
||||
return $el;
|
||||
|
@ -44,9 +44,12 @@ async function getRecentNotes(currentNoteId) {
|
||||
LIMIT 200`, [currentNoteId]);
|
||||
|
||||
return recentNotes.map(rn => {
|
||||
const title = noteCacheService.getNoteTitleForPath(rn.notePath.split('/'));
|
||||
|
||||
return {
|
||||
path: rn.notePath,
|
||||
title: noteCacheService.getNoteTitleForPath(rn.notePath.split('/'))
|
||||
title: title,
|
||||
highlighted: title
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@ -43,11 +43,15 @@ function highlightResults(results, allTokens) {
|
||||
// sort by the longest so we first highlight longest matches
|
||||
allTokens.sort((a, b) => a.length > b.length ? -1 : 1);
|
||||
|
||||
for (const result of results) {
|
||||
result.highlighted = result.title;
|
||||
}
|
||||
|
||||
for (const token of allTokens) {
|
||||
const tokenRegex = new RegExp("(" + utils.escapeRegExp(token) + ")", "gi");
|
||||
|
||||
for (const result of results) {
|
||||
result.title = result.title.replace(tokenRegex, "<b>$1</b>");
|
||||
result.highlighted = result.highlighted.replace(tokenRegex, "<b>$1</b>");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -58,7 +62,8 @@ function findNotes(query) {
|
||||
}
|
||||
|
||||
// trim is necessary because even with .split() trailing spaces are tokens which causes havoc
|
||||
const allTokens = query.trim().toLowerCase().split(" ");
|
||||
// filtering '/' because it's used as separator
|
||||
const allTokens = query.trim().toLowerCase().split(" ").filter(token => token !== '/');
|
||||
const tokens = allTokens.slice();
|
||||
const results = [];
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<div id="add-link-dialog" class="modal fade mx-auto" tabindex="-1" role="dialog">
|
||||
<div id="add-link-dialog" class="modal mx-auto" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-lg" style="max-width: 1000px" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
@ -28,10 +28,6 @@
|
||||
|
||||
<div class="input-group">
|
||||
<input id="note-autocomplete" class="form-control" placeholder="search for note by its name">
|
||||
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text show-recent-notes-button" title="Show recent notes"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -46,7 +42,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer" style="display: flex; justify-content: space-between;">
|
||||
<button class="btn btn-primary">Add note link <kbd>enter</kbd></button>
|
||||
<button type="submit" class="btn btn-primary">Add note link <kbd>enter</kbd></button>
|
||||
|
||||
<button class="btn btn-sm" type="button" data-help-page="Links">
|
||||
<i class="glyphicon glyphicon-info-sign"></i> Help
|
||||
|
Loading…
x
Reference in New Issue
Block a user