Introduction
This template is the most complete template. Supports the following components:
- masthead-logo - text or image for the logo
- masthead-ittle - text for the analysis title
- masthead-nav - links for navigation or any other page action
- masthead-nav-icons - comma separated font-awesome icon name for masthead-nav
- masthead-options - any Spotfire control or html element for the options button content popup
- masthead-options-trigger - text for the options trigger and popup title
- masthead-options-trigger-icon - icon for the options popup and trigger
- masthead-filters - Spotfire control or any other element can go here
html
<DIV id="masthead" style="FONT-SIZE: 15px; BACKGROUND: #3498db; COLOR: white"></DIV> <div id="masthead-logo" style="color:#3498db; background:black;position:relative"> LOGO </div> <h1 id="masthead-title" >JavaScript Masthead-popup for Spotfire</h1> <h3 id="masthead-nav" style="text-align:center;font-size:20px"> <a>page 1</a> <a>page 2</a> <a>page 3</a> </h3> <div id="masthead-nav-icons" hidden>circle,globe,bell</div> <span id="masthead-options-trigger">options</span> <div id="masthead-options-trigger-icon">bell</div> <div id="masthead-options" style="background:rgba(0,255,0,0.1);border:2px solid lime;margin:10px;padding:10px;font-size:20px"> replace with spotifre control<br>or any other element </div> <div id="masthead-filters" style="border:1px solid black;background:orange"> <div>Filters 1</div> <div>Filters 1 contents</div> <div>Filters 2</div> <div>Filters 2 contents</div> <div>Filters 3</div> <div>Filters 4 contents</div> </div>
masthead-popups.js
masthead = document.getElementById("masthead"); hasFeathers = typeof feather!="undefined"; triggerTitle = document.getElementById('masthead-options-trigger')?.innerText || "options" triggerIcon = document.getElementById('masthead-options-trigger-icon')?.innerText || "chevron-down" if (triggerIcon && hasFeathers) triggerIcon = `<i class="icon" data-feather="${triggerIcon}"></i>`; if (triggerIcon && !hasFeathers) triggerIcon = `<i class="icon fa-solid fa-${triggerIcon}"></i>`; if(triggerIcon=="chevron-down") triggerIcon=="▼"; template = ` <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" /> <div class="masthead"> <div> <table border=0 width=333> <tr align="center"><td width=1 class="masthead-logo"></td><td width=100 rowspan=2><b id="mastheadNav">STOCK</b><br><i>Analysis</i></td></tr> <tr align="center"><td class="masthead-title"></td></tr> </table> </div> <div class="masthead-filters"></div> <div class="masthead-nav"> <li id="mastheadPopupTrigger"><a>${triggerTitle} ${triggerIcon}</a></li> </div> </div> <div id="mastheadPopup" class="draggable dialog" hidden > ${triggerTitle} <span class="close"></span> <div class="contents masthead-options"></div> </div> <style> /*masthead*/ .masthead { display: grid; width: 100%; grid-template-columns: 5fr 60fr 25fr; grid-gap: 0px; background:rgba(0,0,0,0.1); } .masthead-filters { display: flex; align-items: center; justify-content: center; color:${masthead.style.background}; } .masthead > div { background-color: ${window.getComputedStyle(masthead).getPropertyValue("background-color")}; } .masthead-title{ font-size:${parseInt(window.getComputedStyle(masthead).getPropertyValue("font-size").replace("px",""))-5+"px"}; } .masthead-nav { display: grid; grid-auto-flow: column; align-content: center; list-style: none; grid-gap: 6px; text-align:center; cursor:default; } .masthead-nav a{ color:${masthead.style.color} !important; text-decoration:none !important; } .icon { margin-right: 15px; } .masthead-nav li:hover { background: rgba(255,255,255,.1); } /*popup*/ .dialog{ border:1px solid rgba(0,0,0,.2); position:fixed; padding:5px 5px 5px 5px; background:${masthead.style.background}; z-index:10; border-radius:5px; cursor:default; right:23px; } .dialog .close::after{ content:"✖"; color:${masthead.style.color}; float:right; margin-top:-2px; } .dialog .close:hover::after{ color:gray; } .dialog .contents{ border:1px solid darkgray; background:${masthead.style.color}; margin-top:3px; padding:5px; min-height:100px; display:grid; color:${masthead.style.background}; } /*logo*/ .svg_logo, .logo { fill:${masthead.style.color} !important; width:50px; padding-right:15px; display:inline-block; vertical-align: middle; } /*accordion*/ .accordion__trigger[aria-expanded="true"]::after { transform: unset; content:"?"; } .accordion__trigger:hover, .accordion__trigger:focus { background: ${masthead.style.background}; } .accordion__trigger::after{ content:"?"; border:none; right: 10px; font-size: 12px; border-right: 10px solid transparent; /*triangle color*/ transition:none; } /*border colors*/ .accordion__trigger{ padding: 0.3rem; font-size: 13px; background: ${masthead.style.background}; color: ${masthead.style.color}; border-bottom: 1px solid ${masthead.style.background}; } .accordion__panel--open { border-bottom: 1px solid ${masthead.style.background}; } .accordion__panel{ border-right: 1px solid ${masthead.style.background}; border-left: 1px solid ${masthead.style.background}; } /*popup filters*/ .dropdown-el { text-align: center; background: #ebf4fb; min-height: 95vh; margin: 0; max-width: 18em; padding: 0; font-family: "Myriad Pro", "Arial", sans; font-size: 12px; position: relative; display: inline-block; margin-right: 1em; min-height: 2em; max-height: 2em; overflow: hidden; top: 0.5em; cursor: default; text-align: left; white-space: nowrap; color: #444; outline: none; border: 1px oustet transparent; border-radius: 1em; transition: 0.3s all ease-in-out; } .dropdown-el input:focus + label { background: #def; } .dropdown-el input { width: 1px; height: 1px; display: inline-block; position: absolute; opacity: 0.01; } .dropdown-el label { border-top: 0.06em solid #d9d9d9; display: block; height: 2em; line-height: 2em; padding-left: 1em; padding-right: 3em; cursor: default; position: relative; transition: 0.3s color ease-in-out; } .dropdown-el label:nth-child(2) { margin-top: 2em; border-top: 0.06em solid #d9d9d9; } .dropdown-el input:checked + label { display: block; border-top: none; position: absolute; top: 0; width: 100%; } .dropdown-el input:checked + label:nth-child(2) { margin-top: 0; position: relative; } .icon::after { content: ""; position: absolute; right: 0.8em; top: 0.9em; border: 0.3em solid #3694d7; border-color: #3694d7 transparent transparent transparent; transition: 0.4s all ease-in-out; } .pop{ border: 0.06em solid #3694d7; background: #fff; border-radius: 0.25em; padding: 0; box-shadow: rgba(0, 0, 0, 0.1) 3px 3px 5px 0px; min-height: 50px; overflow-y:auto; position:fixed; padding:2px; transition: 0.4s all ease-in-out; z-index:1; display: flex; align-items: center; justify-content: center; } </style>` masthead.innerHTML = template; //move elements function function moveElement(from,to){ if(to!=undefined){ if (from.id == "masthead-nav"){ icons = document.querySelector("#masthead-nav-icons"); if (hasFeathers && icons) icons = icons.innerText.split(",").map(x=>`<i class="icon" data-feather="${x}"></i>`); if (!hasFeathers && icons) icons = icons.innerText.split(",").map(x=>`<i class="icon fa-solid fa-${x}"></i>`); let i=0; [...document.querySelectorAll("#masthead-nav a")].reverse().forEach(x=>{ if(x.innerText.endsWith("***")) { x.innerText = x.innerText.replace("***","") document.getElementById("mastheadNav").innerText = x.innerText.toUpperCase() } li = document.createElement("li"); li.append(x); if (icons[i]) x.insertAdjacentHTML("afterbegin",icons[i++]); document.querySelector(".masthead-nav").prepend(li) }) } if(from.id=="masthead-filters"){ let filters = [...document.querySelectorAll("#masthead-filters > *")] for (i=0;i<filters.length;i+=2){ div = document.createElement("div") div.className="nowrap" spn = document.createElement("span") spn.className="dropdown-el icon" lbl = document.createElement("label") spn.append(lbl) lbl.append(...filters[i].childNodes) br = document.createElement("br") pop = document.createElement("span") pop.className="pop" pop.append(...filters[i+1].childNodes) div.append(spn) div.append(br) div.append(pop) to.append(div) console.log(to) } } to.append(...from.childNodes); } from.remove() if (!to) console.log(`⚠️ class ".${from.id}" does not exists on template!`) } //move elements var imports = "nav,title,logo,options,nav-icons,filters,options-trigger,options-trigger-icon"; imports = imports.split(",").map(x=>{return "#masthead-"+x}).join(", "); [...document.querySelectorAll(imports)].forEach(e=>{t="."+e.id;moveElement(e,document.querySelector(t)) }); iconSize = parseInt(window.getComputedStyle(masthead).getPropertyValue("font-size").replace("px",""))+13+"px"; if (typeof feather!="undefined") try{feather.replace({width:iconSize,height:iconSize})}catch(err){alert("one or more feather icon was not found. Check feathericons.com and masthead-hav-icons masthead component")} /*popup*/ //script parameters var popupId = "mastheadPopup" //globals var draggables = document.querySelectorAll('.draggable'); var draggableRuntime = {} var startDrag = (e) => { draggableRuntime.x =e.offsetX; draggableRuntime.y= e.offsetY; draggableRuntime.canMove = true; draggableRuntime.srcElement = e.srcElement }; var doDrag = (e) => { //allow selection on the resulting top right window if(e.srcElement.id=="overlayStatus") {e.stopPropagation(); return} //compute positions if(draggableRuntime.canMove ) { draggableRuntime.srcElement.style.left = (e.clientX - draggableRuntime.x )/window.innerWidth*100 + "%"; draggableRuntime.srcElement.style.top = (e.clientY - draggableRuntime.y)/window.innerHeight*100 + "%"; } }; var endDrag =(e) => { draggableRuntime.canMove = false; } //make target open dialog document.getElementById(popupId+"Trigger").onclick=x=>{ document.getElementById(popupId).hidden=!document.getElementById(popupId).hidden; } //make dialgo close button close document.querySelectorAll(".dialog .close").forEach(x => { x.onclick = function(){x.parentNode.hidden=true} }); //make dialog dragable document.addEventListener('mousemove', doDrag); // draggables[0].parentNode.addEventListener('mousemove', doDrag); draggables.forEach(d => { d.addEventListener('mousedown', startDrag); d.addEventListener('mouseup', endDrag); }); /**popup filters*/ //bind events var x=[...document.querySelectorAll(".dropdown-el.icon")] x.forEach(el=>{ el.addEventListener('click',(ev)=>{ let pop = el.parentNode.lastElementChild hideAll(pop) pop.style.zIndex=pop.style.zIndex=="-1"?"auto":"-1" }) }) //hides all except el function hideAll(el){ [...document.getElementsByClassName("pop")] .map((e,i)=>{ if(el!=e){ e.style.zIndex = "-1" } }) } hideAll()
This template supports both, font-awesome and feather icons. If you cannot see the font-awesome icons or your organization prevents from fetching resources from external sites, you can either add the font-awesone-all.min.js as a new script from cdnjs.com/font-awesome or feather icons by copying the JavaScript code from either of those as a new script. For example, To install the latest version of feather icons, copy the code from https://unpkg.com/feather-icons and add a new script called feather-icons@x.xx.x.js. The version shows up at the url after the file loads.
Place the URL as the description of your scripts. It's a good practice!
To make this script fixed at the top of the screen, try the JavaScript Fixed Masthead for Spotfire
◄ Back to JavaScript Masthead for Spotfire
Recommended Comments
There are no comments to display.