I've been making various minor improvements to my simple Kotlin web app. Most recently I added a little bit of JQuery and Ajax to display a confirmation dialog when deleting an entry from the database. As always, I've tried to come up with a generic solution rather than a case-specific one. It would be easy to attach a JQuery modal dialog to my delete button and call it a day. Instead, I've created a Javascript function which can call any kotlin-spark route to render any given Thymeleaf template inside a modal dialog.
Javascript
My least-favourite programming language!
Getting the Javascript call working inside Thymeleaf was a bit of a bugger, as I had to escape all sorts of characters like '
and /
. Urgh. Here's a calling function (I hope Wordpress doesn't mangle it further):
<a class="secondary-content"
th:onclick="'openModal(\'ajax\/delete\/' + ${u.id} + '\',
\'#userToDelete\',
\'#confirmDeleteContainer\'
);'"><i class="material-icons">delete</i></a>
Clicking on the delete icon (handily provided by Google's Material Icons calls the Javascript openModal(...)
function, passing in the path of the Spark route (ajax/delete
), the ID of the HTML DIV tag whose content will be rendered, and the ID of the containing DIV tag which contains the empty modal. The Javascript function is simply this:
function openModal(sparkPath, dataDiv, containerDiv) {
$.ajax({
url: sparkPath,
success: function(data) {
$(dataDiv).html(data);
$(containerDiv).modal('open')
}
})
}
As always, the running application should be available at kotlin-spark-routes.
Now What?
It's not an exciting application. Now that I have got the basic framework in place, I've been scratching my head to come up with a more compelling project. The difficulty is that all the basic database-driven web applications have already been done. If you want to catalogue your books or your music or your stamp collection, there's probably a website or 12 which can do it all for you. I love books, but I don't want to recreate LibraryThing. If I want to record my running times at the gym, then that's already captured and stored by my Garmin fitness watch and available online. And so on.
I've always been interested in architecture, engineering and particularly bridges. I was never good enough at maths to be a civil engineer, sadly!
I've decided to create an online database of bridges, in part because I'm struggling to find one online. There's a very technical catalogue of American bridges, but I'm looking for something a bit more friendly, and a lot more Europe focused.
I'm going to start sketching out a basic data model for my bridges - let's start with Name, Country, Type, Build Date, Length, Height - but sourcing the data is going to be tricky. While hunting for sources of information I've been exploring WikiData, the Wikipedia for data. I've been learing its query language, SPARQL, to help me find information.
It's not an ideal source; the data is fairly unstructured, with duplicate entries, missing information, inconsistencies abound. But it's a start. I was hoping to find a list of bridges in Scotland, but WikiData doesn't quite know how to handle Scotland - it's a country, it's an administrative region, it's a kingdom... So for now I'll start with the UK. The WikiData query tool is quite clever, and can create maps and timelines from its data.
Here's a SPARQL query to find bridges in the UK whose name starts with "Forth":
SELECT DISTINCT ?bridge ?bridgeLabel ?countryLabel ?coord WHERE {
?bridge wdt:P31/wdt:P279* wd:Q12280.
?bridge wdt:P17 ?country .
?bridge wdt:P625 ?coord.
?bridge rdfs:label ?bridgeName .
?country wdt:P17 wd:Q145 .
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
##FILTER (lang(?itemLabel) = "en") .
FILTER(STRSTARTS (?bridgeName, "Forth")).
}
And its result:
And as a map:
Which is all rather cool!
Writing SPARQL isn't much fun, so I'm going to look for a Java or Kotlin library which can help. I'll also need to find a way of getting JSON data from WikiData, or some way of parsing WikiData's native RDF format.