Hi Nick,
I'm back again with another rather complex dashboard requirement. To simplify things, let me first lay-out the hierarchy for the troublesome section:
<module name="Search"> ...
<module name="HTML / Table">...
<module name="Search2">...
<module name="Table/Chart/etc..">
1) the first Search-module is essentially the populating-search - for 4 single-values, which are to be displayed using the enclosed HTML-module (this part is OK, I have no difficulties displaying the data nor any issues with styling)
2) the second Search-module (here is the issue/problem I can't seem to wrap my head around) - needs to search based on upstream-context, for example, which of the 4 single-values were clicked - something like a drill-down behavior for the HTML-module
Naturally, my initial instinct tells me I need a drill-down behavior; something like what a Table-module has - so initially I have a Table instead of the HTML-module, and some cleaver css-styles to make it look like single-values... however with this direction, I fear I'll hit a wall when defining the second Search-module search string due to the complex downstream variables I need to pass....
Which is why I thought of using an HTML-module instead.
Very comfortable using custom-css and customBehavior - already have my .js and .css files on stand-by; if things need to get as tricky as REST/Python API/custom-command - I'm up for that too; just hoping there might be something I'm overlooking.
Any tips or pointers greatly appreciated
(edit: just read this, and it seems I'm not the only person looking for something in this direction; very interested in the solutions provided, especially the one involving customBehavior - in my case however, I am happy to dispatch all 4 searches and use [css] display: show/hide based on the clicked-HTML-div)
(2nd edit: lol... I just stumbled on the SideView Tabs-module - and I think it might just work for what I'm trying to do... a little css-styling and I might be able to make it look just right)
For those wonder what I ended up doing... here it is:
<module name="Search"> ...
<module name="HTML"> ...
<module name="Search"> ...
<module name="Table"><param name="cssClass">...</module></module>
<module name="Search">...
<module name="Table"><param name="cssClass">...</module></module>
<module name="Search">...
<module name="Table"><param name="cssClass">...</module></module>
<module name="Search">...
<module name="Table"><param name="cssClass">...</module></module>
1) the first search-module populates the first html-module - which essentially contains the 4 items to be clicked; inside css, changed the cursor to "pointer" for each of the <div> tags, added a :hover style so that the div looks like a button; and added an 'onclick' attribute to the <div> - that way, when the div is clicked, I can respond to it from js
2) the subsequent 4 blocks of Search/Table modules will dispatch immediately, but are hidden from view using js/css - essentially, onload - adds a css-class (ie. display: none;) to each of the blocks
3) from the function responding to the onclick-event, I just pass in additional arguments so I know which of the blocks to display
I guess it might be a little hard to understand from my vague explanation, so here is some sample code:
in my .js file
Sideview.utils.declareCustomBehavior("qm_customKPIresults", function(htmlModule) {
var methodReference = htmlModule.onContextChange.bind(htmlModule);
htmlModule.onContextChange = function() {
console.log("hello customBehavior [qm_customKPIresults]");
// hide results-table
$(".panel_row15_col").css("display", "none");
$(".customKPItable").addClass("hideResults");
return methodReference();
}
});
function customKPIresults_clicked(e, s)
{
console.log("hello function [customKPIresults_clicked]");
// make sure the panel is visible
$(".panel_row15_col").css("display", "block");
// figure out which of the 4 single-values to highlight
$(".customKPIresults").removeClass("customKPIresults_selected");
$("." + e.classList[1]).addClass("customKPIresults_selected");
// hide all results-table
$(".customKPItable").addClass("hideResults");
// show only the result-table for associated clicked-item
$("." + s).removeClass("hideResults");
}
the css part
.customKPIresults
{
border-color: rgba(0, 0, 0, 0.3); border-radius: 5px; border-style: solid; border-width: 1px;
cursor: pointer; float: left; margin: 0px 10px; padding: 0px 5px;
width: 150px;
}
.customKPIresults:hover { background: gainsboro; }
.customKPIresults label { font-size: 15px; font-weight: bold; }
.customKPIresults p { font-size: 20px; margin: 5px 0px; text-align: center; }
.customKPIresults_selected { background: yellow; }
.panel_row15_col { min-height: 300px; }
.hideResults { display: none !important; }
sample html for 1 of the 4 click-items:
<div class="customKPIresults kpi_ap_count" onclick="customKPIresults_clicked(this, 'my_css_class1')">
<label>my label text</label>
<p>$some-result-from-upstream-search$</p>
1 of the 4 Search/Table result blocks
<module name="Search" layoutPanel="panel_row15_col1">
<param name="search">some SPL here</param>
<module name="Table">
<param name="cssClass">customKPItable my_css_class1</param>
</module>
</module>
</div>
questions and comments welcome.
sorry for the escaped html tags... can't figure out why I got it to display properly in the question, but its messed up in the answer
I'm glad you figured it out before I made it back to answer.
This is a bit of a hard road that you took. Kudos for sure!
As you later figured out for yourself, the Tabs module is a decent alternative here, particularly if you can hit it with the CSS stick a bit.
But another one that you might not have thought of, is to use Link modules instead of your HTML modules, and Gate modules.
Gate is a little terrifying, but it's very powerful. You could have each Link contain a ValueSetter, and then a Gate. The Gate modules act as little teleporters and in spirit they allow a set of drilldown config to have more than one chain of upstream modules.
Specifically, each of the 4 valueSetters would set the same differentiating token to a different value, and each of the 4 Gate's would have <param name="to">downstreamBlock</param>
. then all the stuff "downstream" from these four link blocks wouldn't actually be downstream at all technically. Rather you'd have a fifth Gate module with <param name="id">downstreamBlock</param>
at the top level of the hierarchy, but in a dashboard panel lower down on the page. There are examples of this sort of config in Sideview Utils - start with the Gate docs and examples. You might find a hidden testcase view as well to rummage around in.
Thanks Nick for the insights.
I didn't know the Link-module can be used in this way. I am already very familiar with the Gate-module as it was used extensively in one of my previous requirement - not sure if you remember, but you helped me out in that one too..
So what you are saying is, the Link-module can be used to set context; instead of navigating to another page? I always just assumed that was what a "Link" was... I'll have to look into that. Thanks for the info
(edit: quick update, I just looked at the doc on my sv instance 3.3.2, and there really isn't much to see, probably because the doc is a little incomplete; a lot of TBD - also its labeled: Prototype module... am I too outdated? maybe I need to update my sv)