Modifying Device State Block Urls on the fly in Experience View Dashboard

Hi,

The Device State block in Losant Dashboard can have urls that point to a details page based on a context variable. For example, the url can be of the form:
https://app.losant.com/dashboards/5xxxxxxxxxxxxxf?ctx[selectedDeviceId]=5xxxxxxxxxxxx0

When the block is rendered in an Experience Dashboard page, it is currently not possible to render different urls; urls that point to the Experience Details page.
Ex. https://xxxxxxxxxxxxxx.onlosant.com/dashboard?deviceId=yyyyyyy

I read through the forums for a solution and saw that others had asked this before and that there is no straightforward solution other than to clone the dashboard and render it.

After reading client-side solutions, I decided to hack it using the MutationObserver WebAPI in the Experience Dashboard page. It is a hack, but I thought others might find it interesting for niche circumstances. The code will break if the class name selectors that I chose changes in Losant backend.

$(document).ready(function(){
    var config = { 
        attributes: true, 
        childList: true, 
        characterData: true,
        subtree: true     // subtree is required to drill down through dynamically added nodes. 
    };

    var target = document;

    // Create an observer instance
    var observer = new MutationObserver(function( mutations ) {
        mutations.forEach(function( mutation ) {
            var newNodes = mutation.addedNodes; // DOM NodeList
            if( newNodes !== null ) { // If there are new nodes added
                var $nodes = $( newNodes ); // jQuery set
                $nodes.each(function() {
                    var $node = $( this );
                    //console.log("Tag name: "+ this.tagName);      Check the tags
                    //console.log("Class name: "+ this.className);  Check the class
                    if(this.className == "markdown device-state-table-block-markdown") {  //Class for the div container I selected by inspecting dom
                        var atem = $node.find("a");
                        if(atem[0] && atem[0].className=="sc-cSHVUG hjcDfm"){ 
                            //console.log("Text: " + atem.text());  Print the link text, which is the device name in my case
                            var url = "https://xxxxxxxxxxxxxx.onlosant.com/dashboard?deviceId=";

                            //Current URL is like https://app.losant.com/dashboards/xxxx?ctx[selectedDeviceId]=yyyyyyyyyy
                            var currentUrl= atem.attr('href');  
                            url += currentUrl.split("=")[1];
                            
                            atem.attr('href', url);
                        }
                    }                      
                });
            }
        });    
    });

    // Pass in the target node, as well as the observer options
    observer.observe(target, config); 
});

@Anaz_Zubair,

Just to help, that entire field is a templatable. You can actually make the URL itself a context variable itself and use it within the block.

1 Like

Hey,

I changed it to use a url context variable and it worked fine. Thanks again. This option is the correct way to do it.

1 Like