feat: Improve search experience by syncing URL with search query
This commit is contained in:
parent
802b2f2f87
commit
eb26279c5a
@ -8,7 +8,7 @@ const originalTitle = document.title;
|
|||||||
|
|
||||||
function getURLP(name) {
|
function getURLP(name) {
|
||||||
const elements = new RegExp(`[?|&]${name}=([^&;]+?)(&|#|;|$)`).exec(
|
const elements = new RegExp(`[?|&]${name}=([^&;]+?)(&|#|;|$)`).exec(
|
||||||
window.location.search,
|
window.location.search
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -39,8 +39,6 @@ class SearchEngine {
|
|||||||
|
|
||||||
loadData() {
|
loadData() {
|
||||||
if (!this.loadingPromise) {
|
if (!this.loadingPromise) {
|
||||||
// We do this as jsonp instead of an XHR or fetch request
|
|
||||||
// to be compatible with usage from filesystem
|
|
||||||
const po = document.createElement("script");
|
const po = document.createElement("script");
|
||||||
po.type = "text/javascript";
|
po.type = "text/javascript";
|
||||||
po.async = true;
|
po.async = true;
|
||||||
@ -62,11 +60,10 @@ class SearchEngine {
|
|||||||
|
|
||||||
let pages = json.pages;
|
let pages = json.pages;
|
||||||
|
|
||||||
// Only keep the pages related to the current language
|
|
||||||
if (window.searchLanguage) {
|
if (window.searchLanguage) {
|
||||||
const pagePrefix = `${window.searchLanguage}/`;
|
const pagePrefix = `${window.searchLanguage}/`;
|
||||||
pages = pages.filter(
|
pages = pages.filter(
|
||||||
(item) => item.url.indexOf(pagePrefix) === 0,
|
(item) => item.url.indexOf(pagePrefix) === 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,36 +77,61 @@ class SearchEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
run() {
|
run() {
|
||||||
if (getURLP("q")) {
|
const query = getURLP("q");
|
||||||
this.settings.field.value = getURLP("q");
|
if (query) {
|
||||||
|
this.settings.field.value = query;
|
||||||
|
|
||||||
this.loadData().then(() => {
|
this.loadData().then(() => {
|
||||||
this.displaySearch();
|
this.displaySearch();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.settings.field.addEventListener("keyup", (event) => {
|
window.addEventListener("popstate", () => {
|
||||||
// Start loading index once the user types text in the field, not before
|
const query = getURLP("q");
|
||||||
this.loadData();
|
if (query) {
|
||||||
|
this.settings.field.value = query;
|
||||||
|
|
||||||
if (parseInt(event.keyCode, 10) === 13) {
|
|
||||||
this.loadData().then(() => {
|
this.loadData().then(() => {
|
||||||
this.displaySearch();
|
this.displaySearch();
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
this.handleClose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.settings.field.addEventListener("keyup", (event) => {
|
||||||
|
this.loadData();
|
||||||
|
|
||||||
|
if (parseInt(event.keyCode, 10) === 13) {
|
||||||
|
const query = this.settings.field.value.trim();
|
||||||
|
if (query.length >= this.settings.minimumLength) {
|
||||||
|
history.pushState(
|
||||||
|
null,
|
||||||
|
"",
|
||||||
|
`?q=${encodeURIComponent(query)}`
|
||||||
|
);
|
||||||
|
this.loadData().then(() => {
|
||||||
|
this.displaySearch();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.settings.form.addEventListener("submit", (event) => {
|
this.settings.form.addEventListener("submit", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.loadData().then(() => {
|
|
||||||
this.displaySearch();
|
const query = this.settings.field.value.trim();
|
||||||
});
|
if (query.length >= this.settings.minimumLength) {
|
||||||
|
history.pushState(null, "", `?q=${encodeURIComponent(query)}`);
|
||||||
|
this.loadData().then(() => {
|
||||||
|
this.displaySearch();
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
keyUpHandler = (e) => {
|
keyUpHandler = (e) => {
|
||||||
if (e.which === 27) {
|
if (e.which === 27) {
|
||||||
//escape
|
|
||||||
this.handleClose();
|
this.handleClose();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -122,6 +144,9 @@ class SearchEngine {
|
|||||||
document.body.classList.remove("with-search");
|
document.body.classList.remove("with-search");
|
||||||
preact.render(null, this.resultContainer);
|
preact.render(null, this.resultContainer);
|
||||||
this.resultContainer = null;
|
this.resultContainer = null;
|
||||||
|
|
||||||
|
this.settings.field.value = "";
|
||||||
|
history.pushState(null, "", window.location.pathname);
|
||||||
};
|
};
|
||||||
|
|
||||||
displaySearch() {
|
displaySearch() {
|
||||||
@ -132,6 +157,8 @@ class SearchEngine {
|
|||||||
|
|
||||||
document.addEventListener("keyup", this.keyUpHandler);
|
document.addEventListener("keyup", this.keyUpHandler);
|
||||||
|
|
||||||
|
const searchTerm = this.settings.field.value;
|
||||||
|
|
||||||
preact.render(
|
preact.render(
|
||||||
<Search
|
<Search
|
||||||
onSearch={(term) =>
|
onSearch={(term) =>
|
||||||
@ -142,8 +169,9 @@ class SearchEngine {
|
|||||||
document.title = `${title} ${originalTitle}`;
|
document.title = `${title} ${originalTitle}`;
|
||||||
}}
|
}}
|
||||||
settings={this.settings}
|
settings={this.settings}
|
||||||
|
searchTerm={searchTerm}
|
||||||
/>,
|
/>,
|
||||||
this.resultContainer,
|
this.resultContainer
|
||||||
);
|
);
|
||||||
|
|
||||||
document.body.classList.add("with-search");
|
document.body.classList.add("with-search");
|
||||||
@ -151,12 +179,9 @@ class SearchEngine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main containers
|
|
||||||
|
|
||||||
function search(options) {
|
function search(options) {
|
||||||
const instance = new SearchEngine(options);
|
const instance = new SearchEngine(options);
|
||||||
instance.run();
|
instance.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declare globally
|
|
||||||
window.search = search;
|
window.search = search;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user