This blog is about applying filter selection across multiple applications from a mashup. This is essential in scenarios where we have apps that share common data fields. For example, HR system and project management systems may have different data and for some reason this need to be separate, we can merge them together in the mashup and apply filters together.
In this example, for simplicity, a copy of Helpdesk app, that is part of the example apps that comes along with
Qliksense desktop implementation, is created and a chart title is renamed for explanatory purpose.
You can download the working source code of this mashup from GITHUB.
One main objective of this approach is to NOT use any custom filters as that would require additional development and maintenance efforts. Also, if not implemented correctly it may lead to performance degrade.
Technically, one may encounter two scenarios where filter needs to be applied on more than one app.
Secnario 1: A single page that renders visualization from more than one app to the user
Scenario 2: Two separate modules (pages) exist and user goes from one module (page) to another and the context (filter selection) needs to be preserved between the modules. Or there is a need to preserve selection between two different sessions.
Scenario 1: Single page that renders visualization from more than one app to the user
- Identify one of the apps as the primary apps.
- Create filter pane from this app to have the common fields
- Render the filter pane in the mashup
- Use the following function to capture selection change and apply it to the second app.Downside of this is that the selections made in the charts of the secondary app may not reflect in the filter. In this case you can disable selection on the charts. If you do not want the selection on the charts disabled, then you will have to create custom filter and apply selections to both apps together.
var selState = app.selectionState( );
var listener = function() {
app2.clearAll();
var selFields = selState.selections;
if (selFields!=null){
$.each(selFields, function(key, value) {
var valArray=[];
$.each(value.selectedValues, function(key,value){
valArray.push(value.qName);
})
app2.field(value.fieldName).selectValues(valArray);
});
}
};
selState.OnData.bind( listener );
Scenario 2: Applying filters across pages or preserving selection between two sessions of the same page
The implementation is similar to the above except that filter selections are transferred only on the page load. In the example, I have used this to retain the filter selection between multiple sessions.
- Create filter panes on the apps
- Render them in the respective mashup page
- Use the following function to capture the selection change and store the selection in the browser cache
cacheString=cacheString + '@' + value.fieldName +"~" + value.qSelected;
}
- When the respective mashup page loads, read the local storage and apply the filters accordingly.
function retrieveSelectionfromCache()
{
var cacheString= localStorage.getItem("QlikFilter");
if (cacheString!=null && cacheString !=""){
app.clearAll();
var selFields=cacheString.split("@");</li>
</ul>
$.each(selFields, function(key, value) {
if (value!=null && value!=""){
var valArray=[];
var s = value.split("~");
var fieldName=s[0];
valArray = s[1].split(", ");
app.field(fieldName).selectValues(valArray);
}
});
}
else{
app.clearAll();
}
}
Hi, this code don´t work for filters with number values.. U know how we can improve to consider number and strings?
Thanks!
Hi Mauricio
Thank you, for the feedback. Can you please list some of the values being selected to isolate the issue? Also, is it when on the same page or when moving from one page to another.
Thanks!!
Hi Mauricio,
Please replace valArray.push(value.qName); inside the listener function to isNaN(value.qName) ? valArray.push(value.qName):valArray.push(Number(value.qName));
Thank you, for spotting this!!
You also may want to convert the valArray values into numbers if its a number dimension in the retrieveSelectionfromCache() if you are using filter across pages.
Hi Nivedha,
First of all thanks for the quickly reply!
I replaced the “valArray.push(value.qName);” line inside the listener function and at first it worked.
But if i select a text and then i select a number the filter seems dont recognize the number. Or if i select a number and then a text, the filter dont recognize the text. This also happens when i make two text filters in a row.
If i go to code line, change something(can be a comma) and save, the app starts to recognize the filters…
Do u know what could be?
Hi, I have the same erratic behaviour as Mauricio. Any sugestion? Thanks.
This works phenomenally. Really helped me out with a customer.
My only stumbling block was that I used a filter panel that had a DIMENSION in it instead of the “real field” name. I can have numerous filter fields and they all work great.
Thank you for such a great job on this and sharing the code.
Glad that this helped.
Another issue regards to Month(adate) dimension as a filter.
It simply doesn’t work!
I think this code is essential to use multiple apps in a mashup, but it is a surprise that it is so cumbersome to achieve a good result.
I hope someone can help.
Regards.
Why does one app have to be considered secondary and have its filters disabled? I might be missing something, but I don’t see any reason why we can’t just have a listener for each app that applies selections to the other app.
Hi
Thank you for the question. Yes we can do it. But i did not want to use a separate UI component. The idea is to use the native filter component of one app and then pass it on to the other app. But we can also have a new component that can send the selection to one or more apps.
I tried it but application started to loop. Do you have any advice
Hi
I seem to have issue when the field is date datatype in Qlik datamodel. My selection in primary app if the field is date datatype in qlik then it is not getting selected in the secondary apps.
do you aware of any solutions?
var valArray[]= {
0:”Jan 2020″
1:”Feb 2020″
2:”Mar 2020″
}
Var FieldName = “Month_Year”; // field in datamodel script : Date#(Month_Year,’MMM YYYY’) AS Month_Year
app.Field(FieldName ).selectValues(valArray);