ScaDS Logo

CENTER FOR
SCALABLE DATA ANALYTICS
AND ARTIFICIAL INTELLIGENCE

Static Publications Site-Tutorial (ORC-Schlange) - Filter HTML Content with Javascript

Beitragsseiten

Filter HTML Content with Javascript

The filtering with javascript is possible but a pain  without any framework. So we use here a framework:

The jQuery framework provides functions that are much easier to use. For the tutorial, jQuery version 3.2.1 is used.

You need to download the .js file and put them beside your out.html. You need the jquery-3.2.1.min.js file.

When you downloaded the files we can start and change the content of our html file to work with them. For this we can use the extra body and head that we have created in our HtmlBackend. So we start by creating a simple head that imports the javascript file:

head = """
<script src="/jquery-3.2.1.min.js"></script>
<script type="text/javascript">
//empty
</script>
"""

There is also an empty inline javascript block that is field later.

We also create a simple body that creates a search input field that we then can use to filter the data:

body = """
<div class="cd-filter-content">
	<input type="search" placeholder="Try unicorn">
</div>
"""

We can now add a line to the main function to add them to the out.html:

if __name__ == "__main__":
	db = DB()
	orcs = [OrcID(*t) for t in db.getList()]
	db.close()
	alldocs = []
	api = API()
	for orc in orcs:
		alldocs += [d for d in api.getWorks(orc) if orc.start <= d.date <= orc.stop]
	alldocs.sort()
	uniqdocs = [doc for doc,_ in itertools.groupby(alldocs)]
	bib = BibliographyData()
	for d in uniqdocs:
		joinBibliography (bib,parse_string(api.getWork(d),"bibtex"))
	style = HtmlStyle()
	style.sort = lambda x: sorted(x, key = lambda e:-int(e.fields['year']))
	style.format_labels =  lambda x: [int(e.fields['year']) for e in x]
	formatbib = style.format_bibliography(bib)
	back = HtmlBackend()
	back.prepout(head, body)
	back.write_to_file(formatbib,"out.html")

Line 19 is added and add the head and body to the file.

The result looks the same with the difference that there is now an function less search input on the top. It can be downloaded here:

To add functionality to the search input, javascript needs to be written. All javascript code that is written is added to the head string in the inline javascript block. So everything that you see here must be insert there to check the functionality by yourself.

The first step binds an event to the input field. JavaScript  knows different events. Here, we want to use the keyup event. That means, every time a key is pressed and released, these event is called. To bind these event, we use the jQuery function keyup(). It gets as input an handler, i.e. a function that is called when the event is triggered. Here, we use an anonymous function that simple create an alert with the content of the search input. However, to make sure that the binding works, we must wait until the html is completely loaded and then bind the event. This can be done by the jQuery function ready(). We use the simplified form: $(function(){...}). Here is the complete javascript:

$(function(){
	search = $(".filter-input input[type='search']")
	search.keyup(function(){
		inputText = search.val().toLowerCase()
		alert(inputText)
	})
})

In line 2, we create a jQuery object called search that contain the input field. To identify these field. we search for an object of class "filter-input" and that is an input html tag of type "search". These is only true for our search input field so that we have an exact description of it. In line 3, the keyup event is bound. In line 4, the content is loaded from search and saved in inputText. The content is the value of the input and can be retrieved with the jQuery function val().  The resulting string is then transformed to lower case with a standard JavaSrcipt String function toLowerCase(). In line 5; this inputText is used to create an alert.

The result can be downloaded here.

The functionality is not very useful. We do not want to create alert, we want to filter the content with the input. We add these functionality in the following:

$(function(){
	search = $(".filter-input input[type='search']")
	search.keyup(function(){
		inputText = search.val().toLowerCase()
		$('.mix').each(function() {
			if($(this).text().toLowerCase().match(inputText) ) {
				$(this).show()
			}
			else {
				$(this).hide()
			}
		});
	})
})

In line 5, the jQuery each function is called that, for every element with the class "mix", calls a anonymous function. In these function, the element, for that it is called, is saved in the variable this.  So there function check in line 6, if the text have a match with the inputText. The jQuery function text() returns the combined text content of the element which contains: the title, the authors, and the journal. To make sure that the case of the characters do not matter these string is also changed toLowerCase. If they match, this element is marked as shown (line 7) with the jQuery function show(). If these is not the case, this element should be hidden. This is done in line 10 with the jQuery function hide.

The result can be downloaded here.

We have a working filter that hide entries that not contain the search input. However, that only applies for the bibliography entries. The years that are between them are not filtered. So that when the corresponding entries are hidden, they are displayed with no content under them. We want also to hide these years. This can be done with a simple jQuery each call in the right time:

$(function(){
	search = $(".filter-input input[type='search']")
	search.keyup(function(){
		inputText = search.val().toLowerCase()
		$('.mix').each(function() {
			if($(this).text().toLowerCase().match(inputText) ) {
				$(this).show()
			}
			else {
				$(this).hide()
			}
		});
		$('.year').each(function() {
			if ($("."+$(this).text()+ ".mix").is(":visible")) $(this).show()
			else $(this).hide()
		});
	})
})

The new javascript is in line 13-16 directly after the each function for the entries is finished. It again uses the jQuery function each to apply a function to every year element (line 13). These elements can be identified with the class "year". The function use the jQuery function is to check if any of the entries with this year is ":visible" (line 14). The entries with this year can be found because they have the year as class and also the class mix. If there is any entire left, then the year is shown (line 14), otherwise it is hidden (line 15).

The result can be downloaded here.

The complete result of this section can be downloaded here: