Qlik Sense mashups can be quite simple at first. The dev hub lets you create the files you need, connect to and app and drop in charts.
Here’s a simple example on how load three charts (hide two) then toggle between them using CSS and JavaScript.
<!doctype html>
<html><head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Qlik Sense Mashup</title>
<meta charset="utf-8">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta http-equiv="cleartype" content="on">
<link rel="stylesheet" href="../../resources/autogenerated/qlik-styles.css">
<script src="../../resources/assets/external/requirejs/require.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script>
var prefix = window.location.pathname.substr( 0, window.location.pathname.toLowerCase().lastIndexOf( "/extensions" ) + 1 );
var config = {
host: window.location.hostname,
prefix: prefix,
port: window.location.port,
isSecure: window.location.protocol === "https:"
};
require.config( {
baseUrl: ( config.isSecure ? "https://" : "http://" ) + config.host + (config.port ? ":" + config.port : "") + config.prefix + "resources"
} );
require( ["js/qlik"], function ( qlik ) {
console.log("Internal Script")
qlik.setOnError(function(error) {
alert(error.message);
});
var appName = 'YOURDASHBORD.qvf'; // Update to your Dashboard name
console.log("App Script")
app = qlik.openApp (appName , config);
$(".qlik_resize").click(function() { qlik.resize();});
app.getObject('QV01','BYyyYB'); // Update to your object ID
app.getObject('QV02','BsCae'); // Update to your object ID
app.getObject('QV03','aZAYGg'); // Update to your object ID's
myToggleShowHide('QV01'); // This shows the first chart and hides the second two
});
function myToggleShowHide(myID) {
// Sure this can be improved so it more reusable but its good enough for now
console.log(myID) ;
if (myID === "QV03") {
document.getElementById("QV04").style.display = "none"
document.getElementById("QV05").style.display = "none"
document.getElementById("QV03").style.display = "block"
} else if (myID === "QV04") {
document.getElementById("QV03").style.display = "none"
document.getElementById("QV05").style.display = "none"
document.getElementById("QV04").style.display = "block"
} else if (myID === "QV05") {
document.getElementById("QV03").style.display = "none"
document.getElementById("QV04").style.display = "none"
document.getElementById("QV05").style.display = "block"
}
};
</script>
</head>
<body style="overflow: auto">
<div class="row">
<div class="btn-group" role="group" aria-label="Basic radio toggle button group">
<input onclick="myToggleShowHide('QV01')" type="radio" class="btn-check" name="btnradio" id="btnradio1" autocomplete="off" checked>
<label class="btn btn-outline-primary qlik_resize" for="btnradio1">Radio 1</label>
<input onclick="myToggleShowHide('QV02')" type="radio" class="btn-check" name="btnradio" id="btnradio2" autocomplete="off">
<label class="btn btn-outline-primary qlik_resize" for="btnradio2">Radio 2</label>
<input onclick="myToggleShowHide('QV03')" type="radio" class="btn-check" name="btnradio" id="btnradio3" autocomplete="off">
<label class="btn btn-outline-primary qlik_resize" for="btnradio3">Radio 3</label>
</div>
</div>
<div class="row my-row">
<div id="QV03" class="qvobject"></div>
<div id="QV02" class="qvobject"></div>
<div id="QV03" class="qvobject"></div>
</div>
</div>
<!--Error Popup-->
<div id="popup">
<button type="button" class="close" data-dismiss="modal" aria-label="Close" id="closePopup"><span aria-hidden="true">×</span></button>
<p id="popupText"></p>
</div>
</body>
Lots going on here so lets break it down… in the main Qlik function we get three objects (charts) which we display in the HTML (below):
<div class="row my-row"> <div id="QV03" class="qvobject"></div> <div id="QV02" class="qvobject"></div> <div id="QV03" class="qvobject"></div> </div>
We also have three buttons (bootstrap). Each button calls the same function and passes the ID of the Qlik object to it:
<input onclick="myToggleShowHide('QV01')" type="radio" class="btn-check" name="btnradio" id="btnradio1" autocomplete="off" checked> <label class="btn btn-outline-primary qlik_resize" for="btnradio1">Radio 1</label>
The function picks up the ID then by changing the CSS style display property shows (block) or hides (none) the object…
function myToggleShowHide(myID) {
// Sure this can be improved so it more reusable but its good enough for now
console.log(myID) ;
if (myID === "QV01") {
document.getElementById("QV01").style.display = "block"
document.getElementById("QV02").style.display = "none"
document.getElementById("QV03").style.display = "none"
} else if (myID === "QV02") {
document.getElementById("QV01").style.display = "none"
document.getElementById("QV02").style.display = "block"
document.getElementById("QV03").style.display = "none"
} else if (myID === "QV03") {
document.getElementById("QV01").style.display = "none"
document.getElementById("QV02").style.display = "none"
document.getElementById("QV03").style.display = "block" } };
Finally in order for Qlik to recalculate the charts when they become visible you need to resize them, this is done using a callback in the main Qlik function which listens to the class of “qlik_resize” each button shares (highlighted in green above).
$(".qlik_resize").click(function() { qlik.resize();});