Jump to content
  • JavaScript Popup for Spotfire


    A small floating draggable window that appears when clicking on a trigger that can hold Spotfire controls and other html elements.

    Introduction

    A popup is a small window that it is display on top of other windows. The JavaScript Popup for Spotfire can hold Spotfire controls such as Action Controls, Filters, Property Controls and Dynamic Items. Examples of these can be buttons, dropdowns, input boxes, filters, calculated values, Sparklines, etc. It can also hold or any other HTML element supported by the Text Area. 

    Popups are great way to save on valuable dashboard space and help make a better experience for the analyst. 
     

    jspopup.thumb.gif.e0781eed112d6de747fc5deb2f53cfd8.gif

    How it works

    The popup consists in html code and some JavaScript code. The html must follow a specific structure that defines the popup elements so the script can render the popup. To have multiple triggers and multiple popups, you need multiple html and javascript sets for each popup.

    Popup elements

    These parts are the popup container, popup trigger, the popup title and the popup contents. The popup container is an html tag element that enclose these element in sequence.
    image.png.5d59b5395614b0313e7c89893a02c13a.png

    Popup container

    The main container has 3 children, one for each popup component (trigger, title and contents). It should have a unique id attribute to identify the popup. This id is passed as a parameter for the popup script.

    Popup trigger

    The first popup container child is the trigger. The trigger is responsible to show or hide the popup. This can be an image, text or icon. It can hold Spotfire controls but it is not recommended, unless you use a label or calculated value without any click event handlers.  

    Popup title

    This is the title of the popup, and can only take text. The second child of the popup container is defined as the popup title. If the popup title ends with *** the default popup visibility will be opened by default.


    Popup contents

    The third child of the popup container holds the contents of the popup and can include any Spotfire control or html tag. 

    Example with one popup

    html

    <div id="myPopup" class="JSPopup">
    	<div>Open popup A</div>
    	<div>This is popup A</div>
    	<div>
            Popup contents goes <b>here</b>
        </div>
    </div>
     

    script

    The script takes the id as the input parameter. To test without this parameter, uncomment the second that reads id="popup2";

    /*
    usage:
    <div class="JSPopup" id="myPopup">
        <div>click to open popup (trigger)</div> 
        <div>Popup title (pullable)</div>
        <div>Popup contents</div>
    </div>
    then run script
    */
    
    //script params
    id="myPopup"
    
    function createPopout(popup, i) {
      let id = "JSPopup_" + i;
      let popupElements = popup.children;
      let popupTrigger = popupElements[0];
      let popupTitle = popupElements[1].innerText;
      let popupContents = popupElements[2];
      let isOpened = false; /*show all popup on start? If not, popup opens if title ends with "***" */
    
      popupTrigger.style.cursor = "default";
    
      //add dragging library
    
      let template = `
    
    <div id="${id}" class="pullable ${isOpened ? "" : "hidden"}" >
      <span class="close"></span>
      <div class="contents"></div>
    </div>
    
    
    <style>
    .hidden{
        left:-1000px !important;
    }
    
    #${id}{
      border:1px solid darkgray;
      position:fixed;
      padding:5px 5px 5px 5px;
      background:${popup.style.background || "whitesmoke"};
      Xcolor:${popup.style.color};
      Xfont-size:${popup.style.fontSize};
      Xfont-family:${popup.style.fontFamily};
      box-shadow: 0 3px 11px 0 rgba(0,0,0,.16),0 3px 6px 0 rgba(0,0,0,.16);
      border-radius: 6px;
      cursor:default;
      min-width:200px;
    }
      
    #${id} .close::after{
      content:"✖";
      color:darkgray;
      float:right;
      margin-top:-15px;
      cursor:default;
    }
    
    #${id} .close:hover::after{
      color:gray;
    }
    
    #${id} .contents{
      border:0px solid darkgray;
      background:${popupContents.style.background || "#FFF"};
      margin-top:3px;
      padding:5px;
      min-height:100px;
    }
    
    .DropdownListContainer.sf-element-styled-dialog.sfc-style-root.prevent-flyout-close {
        z-index: 999;
    }
    
    </style>
    `;
      popup.innerHTML = template;
      let popupBody = document.getElementById(id);
    
      //add trigger
      popup.appendChild(popupTrigger);
    
      //add title to hidden popup template
      if (popupTitle.endsWith("***")) {
        popupTitle = popupTitle.slice(0, popupTitle.length - 3);
        popupBody.classList.remove("hidden");
      }
      handle = document.createElement("div");
      handle.className = "handle";
      textNode = document.createTextNode(popupTitle);
      handle.prepend(textNode);
      popupBody.prepend(handle);
    
      //add contents to hidden popup template
      let templateContents = document.querySelector(`#${id} .contents`);
      templateContents.style = popupContents.style.cssText;
      popupBody.style = popup.style.cssText;
      popup.removeAttribute("style");
    
      templateContents.append(...popupContents.childNodes);
    
      //make target open dialog
      popupTrigger.onclick = (x) => {
        pp = document.getElementById(id);
        pp.classList.toggle("hidden");
    
        [...document.querySelectorAll(".pullable")].forEach((d) => {
          d.style.zIndex = 0;
        });
        pp.style.zIndex = 10;
      };
    
      //make dialog close button close
      document.querySelectorAll("#" + id + " .close").forEach((x) => {
        x.onclick = () => {
          x.parentNode.classList.add("hidden");
        };
      });
    
      //make dialogs draggable
      document.querySelectorAll(".pullable").forEach((aPopup) => {
        new Draggabilly(aPopup, { handle: ".handle" });
      });
    }
    
    // Add dragging library
    draggingLibraryUrl =
      'https://unpkg.com/draggabilly@3/dist/draggabilly.pkgd.min.js';
    script = document.createElement("script");
    script.src = draggingLibraryUrl;
    ph = document.getElementById(id);
    ph.appendChild(script);
    
    //parse popups after dragging library loads
    script.onload = () => {
      //create a popup for every JSPopup class
      [...document.querySelectorAll(".JSPopup")].forEach((rawPopup, i) =>
        createPopout(rawPopup, i)
      );
    };
     

    Making the Popups draggable when Internet is unreliable

    You need to install this library in case there are internet restrictions to go fetch draggabilly, a third party JavaScript library that allows the popups to be draggable. From https://unpkg.com/draggabilly@3/dist/draggabilly.pkgd.min.js, just copy the code from the last link from this sentence into your JavaScript and you are done. Remember, this an optional step if we cannot assure connection to the draggabilly.min.js file.

    Changing the look and feel of the popup

    The style of the popup is embedded in the script. The best way is to override the styles with a separate script. To change the default look and feel for all the popups, then change the main script. Here is an example of that

    popup_blueberry.css

    //requires: popup.js
    
    //script params
    //id="myPopup"
    
    const popupColors={
     c1:"lightgray",//background
     c2:"#003C84",  //border
     c3:"navy",     //title background
     c4:"#0E0E0E",  //text 
     c5:"#FFF"      //title
    } 
    
    //default style. Override with popup_yourtheme.css
    css =`<style>
    
    #${id} .popup-jsc {
        width: min-content !important;
        background-color: #eaeaea !important;
        border-radius: 0.5em;
        border: 1px solid whitesmoke;
        box-shadow: rgb(187 187 187) 5px 4px 9px 1px;
    }
    
    #${id} .flt.drag {
        border: none;
        margin: 0;
        padding: 5px;
    	color:${popupColors.c5};
        background: ${popupColors.c3};
    }
    
    #${id} .popupContents {
      display: inline-block;
      padding: 6px 10px;
      font: 1em arial, helvetica, sans-serif;
      color: ${popupColors.c4};;
      background-color: ${popupColors.c1};
      border:1px outset ${popupColors.c2};
      border-radius:.5em;
      border-top: none;
      border-top-left-radius: 0;
      border-top-right-radius: 0;
    }
    
    </style>`
    
    document.getElementById(id).insertAdjacentHTML("beforeend", css);
     


    Popup_greendish.js

    //requires: popup.js
    
    //script params
    //id="myPopup"
    
    const popupColors={
     c1:"green",      //contents
     c2:"darkGreen",  //border contents
     c3:"lightgray",  //title background
     c4:"whitesmoke", //contents color
     c5:"navy"        //title color
    } 
    
    
    //default style. Override with popup_yourtheme.css
    css =`<style>
    
    #${id} .popup-jsc {
        width: min-content !important;
        background-color: #eaeaea !important;
        border-radius: 0.5em;
        border: 1px solid whitesmoke;
        box-shadow: rgb(187 187 187) 5px 4px 9px 1px;
    }
    
    #${id} .flt.drag {
        border: none;
        margin: 0;
        padding: 5px;
    	color:${popupColors.c5};
        background: ${popupColors.c3};
    }
    
    #${id} .popupContents {
      display: inline-block;
      padding: 6px 10px;
      font: 1em arial, helvetica, sans-serif;
      color: ${popupColors.c4};;
      background-color: ${popupColors.c1};
      border:1px outset ${popupColors.c2};
      border-radius:.5em;
      border-top: none;
      border-top-left-radius: 0;
      border-top-right-radius: 0;}
    
    </style>`
    
    document.getElementById(id).insertAdjacentHTML("beforeend", css);
     


    Back to the JavaScript Component Hub for Spotfire
     


    User Feedback

    Recommended Comments

    There are no comments to display.


×
×
  • Create New...