Adding DSpace search forms in WordPress or any web application

Just the other day, just when I thought the DSpace search form I did for a WordPress project works perfectly, it actually wasn’t! So I had to inspect and investigate more on how DSpace search works. You can actually create search forms in your content management system or any system that accepts any web-based technologies (HTML, css, javascript, jquery) just like these search forms in De La Salle University Library‘s home page

We can see in the home page the following tabs: Search, Classic Catalog, Encore and Kids Online. The Search tab is the main Search tab which utilizes EBSCO Discovery Service. The second tab is for the Millenium ILS Library Catalog. The third tab is for the Millenium ILS Encore while the fourth is for “Kids Online”. These search forms were actually done by yours truly while still working as Systems Services Librarian with the De La Salle University Library. I’m not gonna go in detail but those who wanted to achieve similar search forms should look into html forms and this nicely published blog by Birmingham Young University on Understanding HTML Forms and GET and POST methods as well as this w3schools post on HTTP Request Methods. The main ingredients for such are the following:

  1. form tag with the corresponding action value or a javascript function that will further process the input into the form;
  2. select options that will act as delimiters for your search;
  3. Optional hidden inputs that has name value pair that you can inject into your form;
  4. input for the text/query to search;
  5. The submit button/input that will process the form.

To put it simply:

<form action="https://urlofapplication/">
<select>
<option value="">Keyword</option>
<option value="title">Title</option>
<option value="author">Author</option>
</option>
<input name="inputfilter" type="hidden" value="value"/>
<input value="SEARCH" type="submit">
</form>

Now we go to DSpace. Keyword search in DSpace can be executed site-wide in the search box located in the upper right hand side of the DSpace Institutional Repository. Site-wide meaning all collections will be search in this search box. And please also note that this use case is for DSpace that utilized Mirage2.

If we dig deeper on our search and search a particular Community (in my case E-Reserve).

DSpace Search filter by Community

We can see that the URL fragment for my Community (e-reserve) is like below: https://urlofmydspace/ir/discover/?scope=12345678%2F6&query=web&submit.

Let us dissect the URL fragment one by one.

  • https://urlofmydspace – This is the Domain name of my DSpace.
  • ir – This is the directory DSpace under the domain https://urlof mydspace
  • /discover – Together the two abovementioned in direct order, this is the link for the DSpace search.
  • ? – The question mark is the start of the query string of our GET request (form)
  • scope=12345678%2F6 – name/value pair for our collection.Name here is “scope” and the value is 12345678%2F6, %2F here is the special character “/”, “thus 12345678/6”
  • & – separators for our name/value pairs
  • query=web – This is the name/value pair for our query.
  • submit – This last part can actually be omitted when constructing our search form

So when constructing our search form we take into consideration the abovementioned “name/value” pairs. But we will have a problem if we further filter our search to Title and Author. If we search for title by clicking the Show Advanced Filter in the DSpace interface like below.

DSpace search filter

By choosing Title in the dropdown and add our search term in the search box, leaving the default “Contains” filter, and clicking the “Apply” button, we will get the following search result.

And we will see here a more complicated URL fragment: https://urlofmydspace/ir/discover?filtertype_1=title&filter_relational_operator_1=contains&filter_1=web&submit_apply_filter=&query=web&scope=123456789%2F6

Let us dissect the URL fragment for search filtered by “Title”. But let’s focus on this string ” filtertype_1=title&filter_relational_operator_1=contains&filter_1=web&submit_apply_filter=&query=web&scope=123456789%2F “

  • filtertype_1=title – This is the name/value pair for filtertype_1 “title”. For author filter, this will become filtertype_1=author
  • filter_relational_operator_1=contains – This is the “Contains” filter, the dropdown after our filtertype_1
  • filter_1=web – This is our query and in this case we searched for the term “web”
  • submit_apply_filter= – Name/value pair for submit_apply_filter but this time this does not have a value which we can see after the equals sign (=), we see the character ampersand (&)
  • query=web – Name/value pair for “query” which he had from our keyword search
  • scope=123456789%2F6 – name/value pair for our collection.

Conversely, we can omit query=web and submit_apply_filter= from our name/value pairs like so: https://urlofmydspace/ir/discover?filtertype_1=title&filter_relational_operator_1=contains&filter_1=web&scope=123456789%2F6 and we still get the same search result.

Now for our search form, below is my search form for DSpace that will put in WordPress or any other application/software that accepts html and javascript.

<div class="search-form">
<div style="background-color: rgba(255,255,255,0.85);">
<div class="form-group"><b>Search:</b>
<form id="dspacecustomsearchbox" class="form-inline" style="overflow: auto;" action="https://library.econ.upd.edu.ph/ir/discover" method="get" target="_blank">
<input id="scope" name="scope" type="hidden" value="123456789/6" />
<select id="selectid" class="delimiterselect" style="width: 120px; border: 1px solid #540000;" name="query" size="1" >
<option id="keyword" selected="selected" value="keyword">Keyword</option>
<option id="title" value="title">Title</option>
<option id="author"value="author">Author</option>
</select>
</div>

<div class="form-group">
<input id="dspacecustomsearchtext" class="form-control" style="border: 1px solid #540000;" name="query" size="50" type="text" placeholder="Search for books, articles, databases and more" /></div>

<div class="form-group">
<input class="search" style="border: 1px solid #540000;" type="submit" value="SEARCH" onclick="submitbutton();" />
</div>
</form>
</div>
</div>

Notice here that I have put a javascript function submitbutton that calls below javascript function I have put before the HTML code.

<script>

const filters = {
  "title": "filtertype_1=title&filter_relational_operator_1=contains&filter_1",
  "author": "filtertype_1=author&filter_relational_operator_1=contains&filter_1",
  "keyword": ""
}

//jquery: function for submitbutton: 
function submitbutton(){	

	//jquery: e.preventDefault()
	event.preventDefault();
	
	const q = $("#dspacecustomsearchtext").val().trim();
	if (q === "") return;
	
    const searchType = $("#selectid").val()
    const isKeyword = searchType === "keyword";

	//in jquery: let url = this.action;	
	let url = document.getElementById('dspacecustomsearchbox').action
	
    url += "?scope=" + (isKeyword ? "123456789/6" : "123456789/6");
    url += isKeyword ? "&query=" : `&filtertype_1=${searchType}&filter_relational_operator_1=contains&filter_1=` 
    url += encodeURIComponent(q);
    window.location.href = url;
}
</script>

The meat of the javascript function is appending the name/value pair to the corresponding search filter, for keyword, it’s a simple “scope=123456789/6&query=web” while for the title or author, appending this filtertype_1=title&filter_relational_operator_1=contains&filter_1 and omitting &query=. We instead put that search term/query to filter_1 such that the URL fragment for “title” filter becomes: filtertype_1=title&filter_relational_operator_1=contains&filter_1=web while for the “author” filter filtertype_1=author&filter_relational_operator_1=contains&filter_1=web

.

Here is the complete code for this search form, stylize it accordingly.

<h2 style="color: #540000;">Search E-Reserve Collection</h2>
<script>

const filters = {
  "title": "filtertype_1=title&filter_relational_operator_1=contains&filter_1",
  "author": "filtertype_1=author&filter_relational_operator_1=contains&filter_1",
  "keyword": ""
}

//jquery: function for submitbutton: 
function submitbutton(){	

	//jquery: e.preventDefault()
	event.preventDefault();
	
	const q = $("#dspacecustomsearchtext").val().trim();
	if (q === "") return;
	
    const searchType = $("#selectid").val()
    const isKeyword = searchType === "keyword";

	//in jquery: let url = this.action;	
	let url = document.getElementById('dspacecustomsearchbox').action
	
    url += "?scope=" + (isKeyword ? "123456789/6" : "123456789/6");
    url += isKeyword ? "&query=" : `&filtertype_1=${searchType}&filter_relational_operator_1=contains&filter_1=` 
    url += encodeURIComponent(q);
    window.location.href = url;
}
</script>

<hr />

<div class="search-form">
<div style="background-color: rgba(255,255,255,0.85);">
<div class="form-group"><b>Search:</b>
<form id="dspacecustomsearchbox" class="form-inline" style="overflow: auto;" action="https://library.econ.upd.edu.ph/ir/discover" method="get" target="_blank">
<input id="scope" name="scope" type="hidden" value="123456789/6" />
<select id="selectid" class="delimiterselect" style="width: 120px; border: 1px solid #540000;" name="query" size="1" >
<option id="keyword" selected="selected" value="keyword">Keyword</option>
<option id="title" value="title">Title</option>
<option id="author"value="author">Author</option>
</select>
</div>

<div class="form-group">
<input id="dspacecustomsearchtext" class="form-control" style="border: 1px solid #540000;" name="query" size="50" type="text" placeholder="Search for books, articles, databases and more" /></div>

<div class="form-group">
<input class="search" style="border: 1px solid #540000;" type="submit" value="SEARCH" onclick="submitbutton();" />
</div>
</form>
</div>
</div>

Before I end this blog post, I’m thankful for the answers I got from this Stackoverflow question especially from user mplungjan. For fellow IT and/or librarians who have similar use case, I hope this blog post will be of help!