apreble Posted September 25 Share Posted September 25 Hello, I'm using information from the link I've attached... I really like the vertical menu option for ability for users to navigate to a page. However, when I apply my Spotfire action control links, the button labels will change. For example the "Action Control Link 1" now corresponds with the 2nd icon when the pop up happens. There seems to be no order here after the action control links are applied. How can this be fixed? Here's the HTML from the link with one of my action controls applied- <div class="iconMenu" style="background:yellow;color:blue;font-size:50px;"> <a><SpotfireControl id="65b85707c5bd4da3843ca67d153e45e4" /></a> //This one doesn't correspond to the button labeled "1" <a>Action Control Link 2</a> <a>Action Control Link 3</a> <a>Action Control Link 4</a> <a>Action Control Link 5</a> <a>Action Control Link 6</a> <a>Action Control Link 7</a> <a>Action Control Link 8</a> <a>Action Control Link 9</a> <a>Action Control Link 10</a> <a>Menu</a> </div> <img class="icons fa-solid fa-1, fa-solid fa-2,fa-solid fa-3,fa-solid fa-4,fa-solid fa-5,fa-solid fa-6,fa-solid fa-7,fa-solid fa-8,fa-solid fa-9, fa-solid fa-0, fa-solid fa-bars"/> Here's a visual of what happens when I apply my action control link (See how the link corresponds to button #2 and it should correspond to button #1)- Here's the Javascript from the link- spaceBetweenLayers = 40; itemsPerLayer = 1; startingAngle = 0 endingAngle= 120 canvasPos = document.querySelector('[class^="sfx_canvas"]').getBoundingClientRect() ; iconMenu = document.querySelector(".iconMenu").style backgroundColor= iconMenu.background || "#fff"; foregroundColor = iconMenu.color || "navy"; fontSize = iconMenu.fontSize || "20px"; style = ` <link href='https://cdnjs.cloudflare.com/ajax/libs/simple-line-icons/2.4.1/css/simple-line-icons.css' rel='stylesheet' ></link> <link href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css' rel='stylesheet'/> <style> .iconMenu { position: fixed; top:${canvasPos.y+15}px; left:${canvasPos.x+15}px; z-index:1; height:0px; } .iconMenu a { position: fixed; display: flex; justify-content: center; align-items: center; text-decoration:none !important; cursor: pointer; /*animation*/ transition-timing-function: cubic-bezier(0,0,0,1); transition-duration: .25s; /*size and shape*/ width: ${fontSize}; height: ${fontSize}; padding: calc(${fontSize}/3); border-radius: 100%; /*colors*/ color:#747880 !important; background-color: ${backgroundColor}; box-shadow: 0 4px 18px #0000001a,0 4px 5px #0000001a; } .iconMenu a:last-child{ opacity:100% } .iconMenu a:hover{ color: #8498fa !important; } </style>` document.querySelector(".iconMenu").insertAdjacentHTML("afterend",style); //script timeOutPID=0; boxShadow = document.querySelector(".iconMenu a").style.boxShadow; function hover() { let gap = spaceBetweenLayers; let elements = document.querySelectorAll(".iconMenu a"); elements.forEach((e, i) => { if(i==elements.length-1) return; let angle = (endingAngle / itemsPerLayer) * (i%itemsPerLayer) + startingAngle; i%itemsPerLayer||(gap+=spaceBetweenLayers) e.style.transform = `rotate(${angle}deg) translate(${gap}px) rotate(-${angle}deg)`; e.style.boxShadow=boxShadow; e.onmouseover = resetDelayClose; e.onmouseout = delayClose; }); resetDelayClose(); } function close(){ let elements = document.querySelectorAll(".iconMenu a"); elements.forEach((e, i) => { if (i==elements.length-1) return; e.style.transform = `translate(0px)`; e.style.boxShadow="unset"; }); } function delayClose(){ timeOutPID = setTimeout(close,1234) } function resetDelayClose(){ timeOutPID && clearTimeout(timeOutPID); } document.querySelector(".iconMenu a:last-child").onmouseover = hover; document.querySelector(".iconMenu a:last-child").onmouseout = delayClose; //setup icons on links icons = document.querySelector(".icons").classList.value.split(",") icons[0] = icons[0].replace("icons ",""); document.querySelectorAll(".iconMenu a").forEach((e,i)=>{ e.className = icons[i]; e.title = e.innerText; e.innerText="" }) hover(); delayClose(); Link to comment Share on other sites More sharing options...
Solution barchiel33 Posted September 25 Solution Share Posted September 25 Hmm, so it looks like the article's script doesn't take into account having nested links (ie. <a><SpotfireControls id=blahblahblah></a> where the Spotfire control is a Link action control). So what's happening is that it's moving the link action control up out of the parent <a>. So this HTML: <div class="iconMenu" style="background:yellow;color:blue;font-size:50px;"> <a><SpotfireControl id="7f4b2b132dc244a8b29b58297d16a13f" /></a> <a>Action Control Link 2</a> <a>Action Control Link 3</a> <a>Action Control Link 4</a> <a>Action Control Link 5</a> <a>Action Control Link 6</a> <a>Action Control Link 7</a> <a>Action Control Link 8</a> <a>Action Control Link 9</a> <a>Action Control Link 10</a> <a>Menu</a> </div> <img class="icons fa-solid fa-1, fa-solid fa-2,fa-solid fa-3,fa-solid fa-4,fa-solid fa-5,fa-solid fa-6,fa-solid fa-7,fa-solid fa-8,fa-solid fa-9, fa-solid fa-0, fa-solid fa-bars"/> Becomes this: <div class="iconMenu" style="background:yellow;color:blue;font-size:50px;"> <a class="fa-solid fa-1"></a> <a id="7f4b2b132dc244a8b29b58297d16a13f" href="javascript:void(0);" class="fa-solid fa-2" title="Home"> //This is the Spotfire Link action control. <a class="fa-solid fa-3">Action Control Link 2</a> <a class="fa-solid fa-4">Action Control Link 3</a> <a class="fa-solid fa-5">Action Control Link 4</a> <a class="fa-solid fa-6">Action Control Link 5</a> <a class="fa-solid fa-7">Action Control Link 6</a> <a class="fa-solid fa-8">Action Control Link 7</a> <a class="fa-solid fa-9">Action Control Link 8</a> <a class="fa-solid fa-0">Action Control Link 9</a> <a class="fa-solid fa-bars">Action Control Link 10</a> <a class="undefined">Menu</a> //Since the Spotfire control 'stole' one of the icons, this becomes undefined, since there are 12 elements and only 11 icon classes. </div> The easiest solution is to remove the container <a> around the Spotfire Link action control. However, there is some base styling applied to Link action controls, and, unfortunately, the styles are inline instead of in a style sheet. So you'd need to use !important to override them. The most notable is the font size, but there are a few others. A potential alternative would be to extract the action controls to their own hidden container and just use the icons as facades, but that would take a good bit more work. I went through and rewrote the code to implement the overriding the font-size but also to implement some general best practices (such as using var when setting variables, checking that elements exist, etc.): var spaceBetweenLayers = 100; var itemsPerLayer = 1; var startingAngle = 0 var endingAngle= 120 var canvasPos = document.querySelector('[class^="sfx_canvas"]').getBoundingClientRect() ; var iconMenu = document.querySelector(".iconMenu"); if (iconMenu) { var iconMenuStyle = iconMenu.style; var backgroundColor= iconMenuStyle.background || "#fff"; var foregroundColor = iconMenuStyle.color || "navy"; var fontSize = iconMenuStyle.fontSize || "20px"; var style = ` <link href='https://cdnjs.cloudflare.com/ajax/libs/simple-line-icons/2.4.1/css/simple-line-icons.css' rel='stylesheet' ></link> <link href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css' rel='stylesheet'/> <style> .iconMenu { position: fixed; top:${canvasPos.y+15}px; left:${canvasPos.x+15}px; z-index:1; height:0; } .iconMenu a { font-size: ${fontSize} !important; position: fixed; display: flex; justify-content: center; align-items: center; text-decoration:none !important; cursor: pointer; /*animation*/ transition-timing-function: cubic-bezier(0,0,0,1); transition-duration: .25s; /*size and shape*/ width: ${fontSize}; height: ${fontSize}; padding: calc(${fontSize}/3); border-radius: 100%; /*colors*/ color:#747880 !important; background-color: ${backgroundColor}; box-shadow: 0 4px 18px #0000001a,0 4px 5px #0000001a; } .iconMenu a:last-child{ opacity:100% } .iconMenu a:hover{ color: #8498fa !important; } </style> `; iconMenu.insertAdjacentHTML("afterend",style); //script var timeOutPID = 0; var menuLinks = document.querySelectorAll(".iconMenu a") if (menuLinks) { var boxShadow = document.querySelector(".iconMenu a").style.boxShadow; function hover() { let gap = spaceBetweenLayers; let elements = document.querySelectorAll(".iconMenu a"); if (elements) { elements.forEach((e, i) => { if(i==elements.length-1) return; let angle = (endingAngle / itemsPerLayer) * (i%itemsPerLayer) + startingAngle; i%itemsPerLayer||(gap+=spaceBetweenLayers); e.style.transform = `rotate(${angle}deg) translate(${gap}px) rotate(-${angle}deg)`; e.style.boxShadow=boxShadow; e.onmouseover = resetDelayClose; e.onmouseout = delayClose; }); resetDelayClose(); } } function close(){ let elements = document.querySelectorAll(".iconMenu a"); if (elements) { elements.forEach((e, i) => { if (i==elements.length-1) return; e.style.transform = `translate(0px)`; e.style.boxShadow = "unset"; }); } } function delayClose(){ timeOutPID = setTimeout(close,1234); } function resetDelayClose(){ timeOutPID && clearTimeout(timeOutPID); } document.querySelector(".iconMenu a:last-child").onmouseover = hover; document.querySelector(".iconMenu a:last-child").onmouseout = delayClose; //setup icons on links var icons = document.querySelector(".icons").classList.value.split(","); icons[0] = icons[0].replace("icons ",""); menuLinks.forEach((e,i)=>{ e.className = icons[i]; e.title = e.innerText; e.innerText = ""; }); hover(); delayClose(); }; }; The HTML for this method would look like this: <div class="iconMenu" style="background:yellow;color:blue;font-size:50px;"> <SpotfireControl id="7f4b2b132dc244a8b29b58297d16a13f" /> <a>Action Control Link 2</a> <a>Action Control Link 3</a> <a>Action Control Link 4</a> <a>Action Control Link 5</a> <a>Action Control Link 6</a> <a>Action Control Link 7</a> <a>Action Control Link 8</a> <a>Action Control Link 9</a> <a>Action Control Link 10</a> <a>Menu</a> </div> <img class="icons fa-solid fa-1, fa-solid fa-2,fa-solid fa-3,fa-solid fa-4,fa-solid fa-5,fa-solid fa-6,fa-solid fa-7,fa-solid fa-8,fa-solid fa-9, fa-solid fa-0, fa-solid fa-bars"/> You'd just replace each <a>Action Control Link #</a> with a Spotfire Link action control with the desired title. Link to comment Share on other sites More sharing options...
apreble Posted September 25 Author Share Posted September 25 @barchiel33 thank you so much for the help on this, this worked perfectly! The structure of the javascript looks much better and seems cleaner on your version too. Thanks again! 1 Link to comment Share on other sites More sharing options...
barchiel33 Posted September 26 Share Posted September 26 @apreble That's great to hear! I'm glad I was able to help :) The Spotfire articles section honestly needs some coding guidelines/standards, alot of the code there is either 1) outdated, 2) messily written, 3) contains syntax mistakes, or 4) some combination of the previous three, especially when it comes to the Javascripting/HTML. I hope they have plans to implement some kind of code review for articles. I know alot of people come to the articles thinking they can copy and paste the code with a few small tweaks, but they're more like case studies that tell you potential things you can do and give you an idea how to implement them. 1 Link to comment Share on other sites More sharing options...
Jose Leviaguirre Posted September 27 Share Posted September 27 (edited) Hello @barchiel33 We sincerely appreciate your thoughtful feedback on the Spotfire articles. Your points about code quality are well-received. We're actively working on improvements, including a possible code review process. Our articles aim to inspire, and we'll strive to communicate this more clearly. Thank you again for your valuable insights and we hope the articles are as valuable as your feedback. Thanks again. I made minor modification to the main article so it is clear to replace the entire <a> placeholder with the link action control. The font size and other attributes can be overridden directly on the markup itself: <div class="iconMenu" style="background:yellow;color:blue;font-size:50px;"> Edited September 27 by Jose Leviaguirre 1 Link to comment Share on other sites More sharing options...
barchiel33 Posted October 1 Share Posted October 1 Hello @Jose Leviaguirre! Thank you for the response, I appreciate the information. Also thank you for making the modification to the article! However, the font size and other attributes can't be overridden using the snippet you show in your comment (at least it doesn't work for me). Applying the style to the parent element only affects elements that don't have their own styles applied. When you insert a Spotfire action control, the Spotfire javascripting seems to apply it's own styles directly to that control, overriding the parent element's styling. I suppose you could individually style each action control using the "Format..." interface, but that's fairly limited in what you're able to do and would require doing it for each control. I've attached a screenshot showing how, even with the styling snippet, the action control's icon's text is a different size. Link to comment Share on other sites More sharing options...
Jose Leviaguirre Posted October 3 Share Posted October 3 @barchiel33 Thanks for the feedback! I did not publish the latest version! Pease try again. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now