finished jump to autocomplete, now with token highlighting, #203

This commit is contained in:
azivner 2018-11-07 09:35:29 +01:00
parent 3c23d7085e
commit 1febf5136c
6 changed files with 46 additions and 52 deletions

View File

@ -21,51 +21,29 @@ async function showDialog() {
appendTo: document.querySelector('body'),
hint: false,
autoselect: true,
openOnFocus: true
openOnFocus: true,
minLength: 0
}, [
{
source: noteautocompleteService.autocompleteSource,
displayKey: 'label',
displayKey: 'title',
templates: {
suggestion: function(suggestion) {
return suggestion.label;
return suggestion.title;
}
}
}
]).on('autocomplete:selected', function(event, suggestion, dataset) {
console.log("selected: ", event, suggestion, dataset);
return;
if (ui.item.value === 'No results') {
if (!suggestion.path) {
return false;
}
const notePath = linkService.getNotePathFromLabel(ui.item.value);
treeService.activateNote(notePath);
treeService.activateNote(suggestion.path);
$dialog.modal('hide');
});
// await $autoComplete.autocomplete({
// source: noteautocompleteService.autocompleteSource,
// focus: event => event.preventDefault(),
// minLength: 0,
// autoFocus: true,
// select: function (event, ui) {
// if (ui.item.value === 'No results') {
// return false;
// }
//
// const notePath = linkService.getNotePathFromLabel(ui.item.value);
//
// treeService.activateNote(notePath);
//
// $dialog.modal('hide');
// }
// });
//showRecentNotes();
showRecentNotes();
}
function showInFullText(e) {
@ -83,7 +61,8 @@ function showInFullText(e) {
}
function showRecentNotes() {
$autoComplete.autocomplete("search", "");
$autoComplete.autocomplete("val", "");
$autoComplete.autocomplete("open");
}
$showInFullTextButton.click(showInFullText);

View File

@ -6,20 +6,14 @@ async function autocompleteSource(term, cb) {
+ '?query=' + encodeURIComponent(term)
+ '&currentNoteId=' + noteDetailService.getCurrentNoteId());
if (result.length > 0) {
cb(result.map(row => {
return {
label: row.label,
value: row.label + ' (' + row.value + ')'
}
}));
}
else {
cb([{
label: "No results",
value: "No results"
}]);
if (result.length === 0) {
result.push({
title: "No results",
path: ""
});
}
cb(result);
}
async function initNoteAutocomplete($el) {

View File

@ -25,12 +25,7 @@ async function getAutocomplete(req) {
log.info(`Slow autocomplete took ${msTaken}ms`);
}
return results.map(res => {
return {
value: res.path,
label: res.title
}
});
return results;
}
async function getRecentNotes(currentNoteId) {

View File

@ -35,12 +35,31 @@ async function load() {
loaded = true;
}
function highlightResults(results, allTokens) {
// we remove < signs because they can cause trouble in matching and overwriting existing highlighted chunks
// which would make the resulting HTML string invalid.
allTokens = allTokens.map(token => token.replace('/</g', ''));
// sort by the longest so we first highlight longest matches
allTokens.sort((a, b) => a.length > b.length ? -1 : 1);
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>");
}
}
}
function findNotes(query) {
if (!noteTitles || !query.length) {
return [];
}
const tokens = query.toLowerCase().split(" ");
// trim is necessary because even with .split() trailing spaces are tokens which causes havoc
const allTokens = query.trim().toLowerCase().split(" ");
const tokens = allTokens.slice();
const results = [];
let noteIds = Object.keys(noteTitles);
@ -91,6 +110,8 @@ function findNotes(query) {
results.sort((a, b) => a.title < b.title ? -1 : 1);
highlightResults(results, allTokens);
return results;
}

View File

@ -114,6 +114,10 @@ function union(a, b) {
return res;
}
function escapeRegExp(str) {
return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}
module.exports = {
randomSecureToken,
randomString,
@ -132,5 +136,6 @@ module.exports = {
toObject,
stripTags,
intersection,
union
union,
escapeRegExp
};

View File

@ -1,4 +1,4 @@
<div id="jump-to-note-dialog" class="modal fade mx-auto" tabindex="-1" role="dialog">
<div id="jump-to-note-dialog" class="modal mx-auto" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">