I’m trying to implement something similar to LMFDB’s knowls: blobs of information toggled by clicking on a link.
I have this json file, knowls.json:
{ "example" : "something to show that this works.",
"secondary" : "another example, basically."}
and another file, index.html:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css"/>
<link rel="icon" type="image/x-icon" href="favicon.ico"/>
</head>
<body>
<p>
This page is my attempt to recreate LMFDB's knowls.
</p>
<p class="knowlink">
Click on this <a knowl="example">example</a>.
Or this <a knowl="secondary">other one</a>.
</p>
<div class="knowlbody" style="display: none">
</div>
<script src="jquery.js"></script>
<script>
$("a").click(function() {
$.getJSON("knowls.json", function(json) {
var title = $("a").attr("knowl");
var knowl = json[title];
$("div.knowlbody").html(knowl);
$("div.knowlbody").toggle();
});
});
</script>
</body>
</html>
But when I run it in the browser, clicking on either link only brings up the contents of the first link. The desired behavior is for the example knowl to display the first line of knowls.json, and for the secondary knowl to display the second line. I’m not sure what I’m doing wrong here.
>Solution :
The problem os that $(‘a’) in your getJSON handler return all items and you if get attr it will return the first item.
This is what you need to do:
$("a").click(function() {
var $a = $(this);
$.getJSON("knowls.json", function(json) {
var title = $a.attr("knowl");
var knowl = json[title];
$("div.knowlbody").html(knowl);
$("div.knowlbody").toggle();
});
});
but you can optimize this by fetching the JSON once and saving the values from JSON in the data.
$.getJSON("knowls.json", function(json) {
$('a').each(function() {
var $a = $(this);
var title = $a.attr("knowl");
var knowl = json[title];
$a.data('knowlbody', knowl);
});
});
$("a").click(function() {
var title = $(this).data('knowlbody');
$("div.knowlbody").html(knowl);
$("div.knowlbody").toggle();
});