Modifying header search bar #2757

Closed
opened 2026-02-05 05:02:53 +03:00 by OVERLORD · 15 comments
Owner

Originally created by @xfivesao on GitHub (Apr 19, 2022).

Attempted Debugging

  • I have read the debugging page

Searched GitHub Issues

  • I have searched GitHub for the issue.

Describe the Scenario

Is it possible to adjust the search in the header so that it works the same way as the search for the individual books (sidebar).

I use Bookstack for sporting rules, which are completely identical in many parts and so I get most of the results twice when searching in the header bar.

But I ALWAYS only need one book.

Unfortunately, I'm not a programmer and can't find a way to change the search.

Thanks!

Exact BookStack Version

v22.03.1

Log Content

No response

PHP Version

7.4.29

Hosting Environment

Ubuntu 20.04 IAAS-System (like dedicated server)

Originally created by @xfivesao on GitHub (Apr 19, 2022). ### Attempted Debugging - [X] I have read the debugging page ### Searched GitHub Issues - [X] I have searched GitHub for the issue. ### Describe the Scenario Is it possible to adjust the search in the header so that it works the same way as the search for the individual books (sidebar). I use Bookstack for sporting rules, which are completely identical in many parts and so I get most of the results twice when searching in the header bar. But I ALWAYS only need one book. Unfortunately, I'm not a programmer and can't find a way to change the search. Thanks! ### Exact BookStack Version v22.03.1 ### Log Content _No response_ ### PHP Version 7.4.29 ### Hosting Environment Ubuntu 20.04 IAAS-System (like dedicated server)
OVERLORD added the 🐕 Support label 2026-02-05 05:02:53 +03:00
Author
Owner

@ssddanbrown commented on GitHub (Apr 19, 2022):

Hi @xfivesao,
Just to confirm, the functionality you want is to limit the main search to only show results from a single book?

@ssddanbrown commented on GitHub (Apr 19, 2022): Hi @xfivesao, Just to confirm, the functionality you want is to limit the main search to only show results from a single book?
Author
Owner

@xfivesao commented on GitHub (Apr 19, 2022):

Hi @ssddanbrown,

yes, that is totally correct for my specific use case (referee).
We want to use Bookstack in active competition for referees and we want the search to be as accurate as possible.

I have 4 sets of rules (books) that are exactly the same in many parts and when I use the main search I always get 4 hits, although I'm only really looking for one.

The side search ist perfect, but not comfortable to use in stressing moments with a smartphone. Perfect would be a script or switch in the 'Custom HTML head content' section, but unfortunately I am not able to implement it myself.

Bookstack is so fantastic for our purposes and I have been looking for something like this for a very long time.

Thanks for your assistance!

@xfivesao commented on GitHub (Apr 19, 2022): Hi @ssddanbrown, yes, that is totally correct for my specific use case (referee). We want to use Bookstack in active competition for referees and we want the search to be as accurate as possible. I have 4 sets of rules (books) that are exactly the same in many parts and when I use the main search I always get 4 hits, although I'm only really looking for one. The side search ist perfect, but not comfortable to use in stressing moments with a smartphone. Perfect would be a script or switch in the 'Custom HTML head content' section, but unfortunately I am not able to implement it myself. Bookstack is so fantastic for our purposes and I have been looking for something like this for a very long time. Thanks for your assistance!
Author
Owner

@xfivesao commented on GitHub (Apr 19, 2022):

In case of a competition, the referee chooses BEFOREhand the book he wants to work with for the next hours.

He then definitely does not need the other books or can select another one manually. Never 2 books are searched at the same time.

@xfivesao commented on GitHub (Apr 19, 2022): In case of a competition, the referee chooses BEFOREhand the book he wants to work with for the next hours. He then definitely does not need the other books or can select another one manually. Never 2 books are searched at the same time.
Author
Owner

@ssddanbrown commented on GitHub (Apr 19, 2022):

@xfivesao Okay, Thanks for confirming.

There is no in-built way to limit this search to a specific Book, Nor can I see a workaround that can be applied without editor core application files.

@ssddanbrown commented on GitHub (Apr 19, 2022): @xfivesao Okay, Thanks for confirming. There is no in-built way to limit this search to a specific Book, Nor can I see a workaround that can be applied without editor core application files.
Author
Owner

@xfivesao commented on GitHub (Apr 19, 2022):

@ssddanbrown

my first idea (as a non-programmer) was that the header main search simply works like the side bar search after selecting a book (not restricted later to chapters or pages - only on every page the first selected book), and that I can assign with "a hack" of one file or the 'Custom HTML head content' that function to the top search box.

I am aware that I would have to change this again after each update, but it would definitely be worth it to me.

Unfortunately I'm too old an stupid to do so... ;-)

@xfivesao commented on GitHub (Apr 19, 2022): @ssddanbrown my first idea (as a non-programmer) was that the header main search simply works like the side bar search after selecting a book (not restricted later to chapters or pages - only on every page the first selected book), and that I can assign with "a hack" of one file or the 'Custom HTML head content' that function to the top search box. I am aware that I would have to change this again after each update, but it would definitely be worth it to me. Unfortunately I'm too old an stupid to do so... ;-)
Author
Owner

@ssddanbrown commented on GitHub (Apr 19, 2022):

@xfivesao Okay, This is a massive sketchy bodge, but this kind of does what you specified above:

<script>
window.addEventListener('DOMContentLoaded', (event) => {

	const bookSlugRegex = /\/books\/(.+?)([\/?#]|$)/;
	const url = window.location.href;

	// Redirect global search box to specific book page if we're in a book
	if (bookSlugRegex.test(url)) {
		const bookSlugToSearch = url.match(bookSlugRegex)[1];
		const headerSearchForm = document.querySelector('header form.search-box');
		headerSearchForm.action = window.baseUrl(`/books/${bookSlugToSearch}`);
	}

	// If we're on a book page, check for a search term and attempt to fill book search
	// Wrap this in a setTimeout to ensure our book page search would be active.
	setTimeout(function() {
		const parsedUrl = new URL(url);
		const entitySearchForm = document.querySelector('.tri-layout-left-contents form.search-box');
		if (entitySearchForm && parsedUrl.searchParams.get('term')) {
			const input = entitySearchForm.querySelector('input[type=text]');
			input.value = parsedUrl.searchParams.get('term');
			entitySearchForm.dispatchEvent(new CustomEvent('submit', {bubbles:true, cancelable:true}));
		}
	}, 100);

});
</script>

This will check the URL to see if you're in a book and, if so, pass around and use the search term in the book search.
Of course this is not official and could break upon BookStack changes.

@ssddanbrown commented on GitHub (Apr 19, 2022): @xfivesao Okay, This is a massive sketchy bodge, but this kind of does what you specified above: ```html <script> window.addEventListener('DOMContentLoaded', (event) => { const bookSlugRegex = /\/books\/(.+?)([\/?#]|$)/; const url = window.location.href; // Redirect global search box to specific book page if we're in a book if (bookSlugRegex.test(url)) { const bookSlugToSearch = url.match(bookSlugRegex)[1]; const headerSearchForm = document.querySelector('header form.search-box'); headerSearchForm.action = window.baseUrl(`/books/${bookSlugToSearch}`); } // If we're on a book page, check for a search term and attempt to fill book search // Wrap this in a setTimeout to ensure our book page search would be active. setTimeout(function() { const parsedUrl = new URL(url); const entitySearchForm = document.querySelector('.tri-layout-left-contents form.search-box'); if (entitySearchForm && parsedUrl.searchParams.get('term')) { const input = entitySearchForm.querySelector('input[type=text]'); input.value = parsedUrl.searchParams.get('term'); entitySearchForm.dispatchEvent(new CustomEvent('submit', {bubbles:true, cancelable:true})); } }, 100); }); </script> ``` This will check the URL to see if you're in a book and, if so, pass around and use the search term in the book search. Of course this is not official and could break upon BookStack changes.
Author
Owner

@xfivesao commented on GitHub (Apr 19, 2022):

@ssddanbrown

Wow, this is really much more complicated than I thought. Thank you very much!

It works perfectly on PC and is exactly what I need. This improves usability many times over (in my particular case).

On smartphone, however, it does not work as expected. Here, after selecting the book and then selecting the search in the header bar (3 points menu), all results are displayed again.

This seems to work differently with the responsive display. But maybe I can at least fix that on my own.

Thanks a lot for your help!

@xfivesao commented on GitHub (Apr 19, 2022): @ssddanbrown Wow, this is really much more complicated than I thought. Thank you very much! It works perfectly on PC and is exactly what I need. This improves usability many times over (in my particular case). On smartphone, however, it does not work as expected. Here, after selecting the book and then selecting the search in the header bar (3 points menu), all results are displayed again. This seems to work differently with the responsive display. But maybe I can at least fix that on my own. Thanks a lot for your help!
Author
Owner

@ssddanbrown commented on GitHub (Apr 19, 2022):

@xfivesao Ah, yeah, the mobile flow is quite different and searches via a different form/page. Here's an adapted script:

<script>
window.addEventListener('DOMContentLoaded', (event) => {

	const bookSlugRegex = /\/books\/(.+?)([\/?#]|$)/;
	const url = window.location.href;
	const lastBook = window.localStorage.getItem('lastBook') || null;
	const inBook = bookSlugRegex.test(url);

	// Redirect global search box to specific book page if we're in a book
	if (inBook || lastBook) {
		const bookSlugToSearch = inBook ? url.match(bookSlugRegex)[1] : lastBook;
		const searchForms = document.querySelectorAll('form[action$="/search"].search-box');
		for (const form of searchForms) {
			form.action = window.baseUrl(`/books/${bookSlugToSearch}`);
		}
		window.localStorage.setItem('lastBook', bookSlugToSearch);
	}


	// If we're on a book page, check for a search term and attempt to fill book search
	// Wrap this in a setTimeout to ensure our book page search would be active.
	setTimeout(function() {
		const parsedUrl = new URL(url);
		const entitySearchForm = document.querySelector('.tri-layout-left-contents form.search-box');
		if (entitySearchForm && parsedUrl.searchParams.get('term')) {
			const input = entitySearchForm.querySelector('input[type=text]');
			input.value = parsedUrl.searchParams.get('term');
			entitySearchForm.dispatchEvent(new CustomEvent('submit', {bubbles:true, cancelable:true}));
		}
	}, 100);

});
</script>

This version will "remember" the last viewed book and use that detail to override both the header search input and the search page search input.

@ssddanbrown commented on GitHub (Apr 19, 2022): @xfivesao Ah, yeah, the mobile flow is quite different and searches via a different form/page. Here's an adapted script: ```html <script> window.addEventListener('DOMContentLoaded', (event) => { const bookSlugRegex = /\/books\/(.+?)([\/?#]|$)/; const url = window.location.href; const lastBook = window.localStorage.getItem('lastBook') || null; const inBook = bookSlugRegex.test(url); // Redirect global search box to specific book page if we're in a book if (inBook || lastBook) { const bookSlugToSearch = inBook ? url.match(bookSlugRegex)[1] : lastBook; const searchForms = document.querySelectorAll('form[action$="/search"].search-box'); for (const form of searchForms) { form.action = window.baseUrl(`/books/${bookSlugToSearch}`); } window.localStorage.setItem('lastBook', bookSlugToSearch); } // If we're on a book page, check for a search term and attempt to fill book search // Wrap this in a setTimeout to ensure our book page search would be active. setTimeout(function() { const parsedUrl = new URL(url); const entitySearchForm = document.querySelector('.tri-layout-left-contents form.search-box'); if (entitySearchForm && parsedUrl.searchParams.get('term')) { const input = entitySearchForm.querySelector('input[type=text]'); input.value = parsedUrl.searchParams.get('term'); entitySearchForm.dispatchEvent(new CustomEvent('submit', {bubbles:true, cancelable:true})); } }, 100); }); </script> ``` This version will "remember" the last viewed book and use that detail to override both the header search input and the search page search input.
Author
Owner

@xfivesao commented on GitHub (Apr 19, 2022):

@ssddanbrown

Dear Dan,

I spent hours trying to get this to work myself, because of course I didn't realize the problem until after I added the 2nd book.

You fixed it perfectly in an hour!

Thank you very much for this - not self-evident - help!

Maybe there will be a version in the future where you can simply select this option in the settings menu. ;-)

Anyway, it works great and is a great added value for me.

Best regards
Ingo

@xfivesao commented on GitHub (Apr 19, 2022): @ssddanbrown Dear Dan, I spent hours trying to get this to work myself, because of course I didn't realize the problem until after I added the 2nd book. You fixed it perfectly in an hour! Thank you very much for this - not self-evident - help! Maybe there will be a version in the future where you can simply select this option in the settings menu. ;-) Anyway, it works great and is a great added value for me. Best regards Ingo
Author
Owner

@ssddanbrown commented on GitHub (Apr 19, 2022):

Glad I could help!

Maybe there will be a version in the future where you can simply select this option in the settings menu. ;-)

To be honest, probably not. This is very specific functionality that would probably be tricky to even just communicate as an option if added as one. Maybe we could make it easier in the future by adding book-scoping filters to the main search, but there's been little other request around this.

I'll therefore close this issue off but feel free to @ me here or chat on our discord server if you need future assistance with the above.

@ssddanbrown commented on GitHub (Apr 19, 2022): Glad I could help! > Maybe there will be a version in the future where you can simply select this option in the settings menu. ;-) To be honest, probably not. This is very specific functionality that would probably be tricky to even just communicate as an option if added as one. Maybe we could make it easier in the future by adding book-scoping filters to the main search, but there's been little other request around this. I'll therefore close this issue off but feel free to `@` me here or chat on [our discord server](https://discord.gg/ztkBqR2) if you need future assistance with the above.
Author
Owner

@xfivesao commented on GitHub (Apr 19, 2022):

Your app is really fantastic the way it is!
And you have made my special application for the hobby of many of my friends now just perfect!

Thanks again!

@xfivesao commented on GitHub (Apr 19, 2022): Your app is really fantastic the way it is! And you have made my special application for the hobby of many of my friends now just perfect! Thanks again!
Author
Owner

@xfivesao commented on GitHub (May 1, 2022):

@ssddanbrown

Hi, we have used your modified app last weekend in a match and your search hack works fantastic with 3 rule books! Thanks again.

My teammates had only one suggestion. Would it be possible to display the results of the modified header search in the same way as in the detail search?

Also with highlighted text of the search term and - especially - with the existing individual tags?

Best regards!

@xfivesao commented on GitHub (May 1, 2022): @ssddanbrown Hi, we have used your modified app last weekend in a match and your search hack works fantastic with 3 rule books! Thanks again. My teammates had only one suggestion. Would it be possible to display the results of the modified header search in the same way as in the detail search? Also with highlighted text of the search term and - especially - with the existing individual tags? Best regards!
Author
Owner

@ssddanbrown commented on GitHub (May 2, 2022):

Hi @xfivesao,

My teammates had only one suggestion. Would it be possible to display the results of the modified header search in the same way as in the detail search?
Also with highlighted text of the search term and - especially - with the existing individual tags?

Those will take a lot more complexing hacking to do within the context of your existing workaround, I can't really spend that time right now to support this one-off hack.

There's a case to be made for generally bringing in tags and search term highlighting to the book (and chapter) level search functionality. Would be happy for that to be raised as an additional feature request to be added to core.

@ssddanbrown commented on GitHub (May 2, 2022): Hi @xfivesao, > My teammates had only one suggestion. Would it be possible to display the results of the modified header search in the same way as in the detail search? > Also with highlighted text of the search term and - especially - with the existing individual tags? Those will take a lot more complexing hacking to do within the context of your existing workaround, I can't really spend that time right now to support this one-off hack. There's a case to be made for generally bringing in tags and search term highlighting to the book (and chapter) level search functionality. Would be happy for that to be raised as an additional feature request to be added to core.
Author
Owner

@xfivesao commented on GitHub (May 2, 2022):

Hi @ssddanbrown,

unfortunately, I can't estimate the amount of work my questions will cause.
I apologize for that. It is less than a nice-to-have! Everything works exemplary!

I'm not sure I understood your last sentence correctly. Should I open this as a feature request?

@xfivesao commented on GitHub (May 2, 2022): Hi @ssddanbrown, unfortunately, I can't estimate the amount of work my questions will cause. I apologize for that. It is less than a nice-to-have! Everything works exemplary! I'm not sure I understood your last sentence correctly. Should I open this as a feature request?
Author
Owner

@ssddanbrown commented on GitHub (May 2, 2022):

unfortunately, I can't estimate the amount of work my questions will cause.
I apologize for that. It is less than a nice-to-have! Everything works exemplary!

Ah, no need to apologize, didn't mean for my comment to sound too harsh.

I'm not sure I understood your last sentence correctly. Should I open this as a feature request?

Yeah, specifically for "Adding tags and search term highlighting to the book (and chapter) level search", since that probably makes sense to add as an improvement to the core project, and is not limited in scope to your specific workaround.

@ssddanbrown commented on GitHub (May 2, 2022): > unfortunately, I can't estimate the amount of work my questions will cause. > I apologize for that. It is less than a nice-to-have! Everything works exemplary! Ah, no need to apologize, didn't mean for my comment to sound too harsh. > I'm not sure I understood your last sentence correctly. Should I open this as a feature request? Yeah, specifically for "Adding tags and search term highlighting to the book (and chapter) level search", since that probably makes sense to add as an improvement to the core project, and is not limited in scope to your specific workaround.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/BookStack#2757