How to apply color to only part of a SVG icon with CSS? - javascript

Here I have this font color picker icon using a svg icon. When a specific color is selected, I want to change the bottom rectangle (not the A letter) to match the selected color, so I am wondering if there is a way to only render the bottom part of the svg icon with specific color?
Below is the SVG code:
<svg class="svgIcon---svg---3eBcz" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M8 1c.2 0 .38.12.46.3l3 7a.5.5 0 01-.92.4L9.81 7H6.2l-.73 1.7a.5.5 0 11-.92-.4l3-7A.5.5 0 018 1zM6.62 6h2.76L8 2.77 6.62 6zM2 11.5c0-.83.67-1.5 1.5-1.5h9c.83 0 1.5.67 1.5 1.5v2c0 .83-.67 1.5-1.5 1.5h-9A1.5 1.5 0 012 13.5v-2z"></path></svg>
Is it possible to change some numbers in the svg path or add a specific fill-rule so that only the bottom part could be filled with color, or, is there another way to do that with only CSS change?
Below is how it looks like with the outer HTML document. I am only given the option to modify the css styles on the i (icon) element.
<i data-icon-name="TextColorFilled" aria-hidden="true" class="Button-icon icon-518"><span role="presentation" aria-hidden="true" class="svgIcon---root---V-j2a" style="vertical-align: top; height: 100%; width: 100%;">
<svg class="svgIcon---svg---3eBcz" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<path d="M8 1c.2 0 .38.12.46.3l3 7a.5.5 0 01-.92.4L9.81 7H6.2l-.73 1.7a.5.5 0 11-.92-.4l3-7A.5.5 0 018 1zM6.62 6h2.76L8 2.77 6.62 6zM2 11.5c0-.83.67-1.5 1.5-1.5h9c.83 0 1.5.67 1.5 1.5v2c0 .83-.67 1.5-1.5 1.5h-9A1.5 1.5 0 012 13.5v-2z"></path>
</svg>
</span>
</i>

If you split the svg into two paths you can select the second one and color just that using fill and CSS.
<style>
path:nth-child(2) {
fill: red;
}
</style>
<svg class="svgIcon---svg---3eBcz" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M8 1c.2 0 .38.12.46.3l3 7a.5.5 0 01-.92.4L9.81 7H6.2l-.73 1.7a.5.5 0 11-.92-.4l3-7A.5.5 0 018 1zM6.62 6h2.76L8 2.77 6.62 6z"></path>
<path d="M2 11.5c0-.83.67-1.5 1.5-1.5h9c.83 0 1.5.67 1.5 1.5v2c0 .83-.67 1.5-1.5 1.5h-9A1.5 1.5 0 012 13.5v-2z"></path></svg>

Related

How to fill an svg image with specific length color

I need to implement star ratings in my app. But the designer only provided a border star image as attached. Now i need to repeat the svg and at the same time fill it according to the ratings as shown in second attached image. But I am not sure if filling the svg with specific width color is possible or not. I don't need full solution, any reference or concept answer is also welcome.
the provided star svg
and
the implementation needeed
The provided SVG code
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M9.177 7.72a.5.5 0 0 1-.376.273l-5.309.771a.5.5 0 0 0-.277.853l3.841 3.745a.5.5 0 0 1 .144.442l-.907 5.288a.5.5 0 0 0 .726.527l4.748-2.497a.5.5 0 0 1 .466 0l4.748 2.497a.5.5 0 0 0 .726-.527l-.907-5.288a.5.5 0 0 1 .143-.442l3.842-3.745a.5.5 0 0 0-.277-.853l-5.309-.771a.5.5 0 0 1-.376-.274l-2.375-4.81a.5.5 0 0 0-.896 0l-2.375 4.81zM12 6.52l-1.03 2.084a2.5 2.5 0 0 1-1.88 1.368l-2.302.334 1.665 1.624a2.5 2.5 0 0 1 .72 2.212l-.394 2.292 2.059-1.082a2.5 2.5 0 0 1 2.326 0l2.059 1.082-.393-2.292a2.5 2.5 0 0 1 .718-2.212l1.666-1.624-2.302-.334a2.5 2.5 0 0 1-1.882-1.368L12 6.52z" clip-rule="evenodd"/></svg>
Here are two quick hack solutions, both of which require modification of the SVG (and both of which could be modified in a more efficient way), and both of which use a gradient fill, the same basic idea that Robert Longson suggested above.
1. duplicate the path, fill with gradient
Duplicate the path so you have one copy for the border and one copy for the fill.
Remove the fill-rule="evenodd" from the first path so the interior isn't subtracted, thus getting filled too.
Fill the first path (the "back" one) with a gradient that uses hard stops to achieve your partial fill. (I've used orange here just so you can see which is which.)
You could fiddle with the specifics of the gradient to get it exactly where you want it of course. This is just a proof of concept.
svg {
max-width: 200px; /* not relevant */
}
.stop1 {
stop-color: orange;
}
.stop2 {
stop-opacity: 0;
}
path.fill {
fill: url(#gradient-fill);
}
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
<defs>
<linearGradient id="gradient-fill" x1="0" x2="1" y1="1" y2="0.5">
<stop class="stop1" offset="70%"/>
<stop class="stop2" offset="70%"/>
</linearGradient>
</defs>
<path class="fill" d="M9.177 7.72a.5.5 0 0 1-.376.273l-5.309.771a.5.5 0 0 0-.277.853l3.841 3.745a.5.5 0 0 1 .144.442l-.907 5.288a.5.5 0 0 0 .726.527l4.748-2.497a.5.5 0 0 1 .466 0l4.748 2.497a.5.5 0 0 0 .726-.527l-.907-5.288a.5.5 0 0 1 .143-.442l3.842-3.745a.5.5 0 0 0-.277-.853l-5.309-.771a.5.5 0 0 1-.376-.274l-2.375-4.81a.5.5 0 0 0-.896 0l-2.375 4.81zM12 6.52l-1.03 2.084a2.5 2.5 0 0 1-1.88 1.368l-2.302.334 1.665 1.624a2.5 2.5 0 0 1 .72 2.212l-.394 2.292 2.059-1.082a2.5 2.5 0 0 1 2.326 0l2.059 1.082-.393-2.292a2.5 2.5 0 0 1 .718-2.212l1.666-1.624-2.302-.334a2.5 2.5 0 0 1-1.882-1.368L12 6.52z"/>
<path fill-rule="evenodd" d="M9.177 7.72a.5.5 0 0 1-.376.273l-5.309.771a.5.5 0 0 0-.277.853l3.841 3.745a.5.5 0 0 1 .144.442l-.907 5.288a.5.5 0 0 0 .726.527l4.748-2.497a.5.5 0 0 1 .466 0l4.748 2.497a.5.5 0 0 0 .726-.527l-.907-5.288a.5.5 0 0 1 .143-.442l3.842-3.745a.5.5 0 0 0-.277-.853l-5.309-.771a.5.5 0 0 1-.376-.274l-2.375-4.81a.5.5 0 0 0-.896 0l-2.375 4.81zM12 6.52l-1.03 2.084a2.5 2.5 0 0 1-1.88 1.368l-2.302.334 1.665 1.624a2.5 2.5 0 0 1 .72 2.212l-.394 2.292 2.059-1.082a2.5 2.5 0 0 1 2.326 0l2.059 1.082-.393-2.292a2.5 2.5 0 0 1 .718-2.212l1.666-1.624-2.302-.334a2.5 2.5 0 0 1-1.882-1.368L12 6.52z"/>
</svg>
2. Same idea but with the inner and outer paths separated.
(If you're going to go this route you could just as easily create a path to define the shape of the fill.)
svg {
max-width: 200px; /* not relevant */
}
.stop1 {
stop-color: orange;
}
.stop2 {
stop-color: white;
}
path.inner {
fill: url(#gradient-fill);
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<defs>
<linearGradient id="gradient-fill" x1="0" x2="1" y1="1" y2="0.5">
<stop class="stop1" offset="70%"/>
<stop class="stop2" offset="70%"/>
</linearGradient>
</defs>
<path class="outer" d="M9.18,8.57C9.1,8.71,8.96,8.82,8.8,8.84L3.49,9.61C3.22,9.65,3.03,9.9,3.07,10.18
c0.02,0.11,0.07,0.21,0.15,0.29l3.84,3.74c0.12,0.11,0.17,0.28,0.14,0.44l-0.91,5.29c-0.05,0.27,0.14,0.53,0.41,0.58
c0.11,0.02,0.22,0,0.32-0.05l4.75-2.5c0.15-0.08,0.32-0.08,0.47,0l4.75,2.5c0.24,0.13,0.55,0.04,0.68-0.21
c0.05-0.1,0.07-0.21,0.05-0.32l-0.91-5.29c-0.03-0.16,0.03-0.33,0.14-0.44l3.84-3.74c0.2-0.19,0.2-0.51,0.01-0.71
c-0.08-0.08-0.18-0.13-0.29-0.15L15.2,8.84c-0.16-0.02-0.3-0.13-0.38-0.27l-2.38-4.81c-0.12-0.25-0.42-0.35-0.67-0.23
c-0.1,0.05-0.18,0.13-0.23,0.23L9.18,8.57L9.18,8.57z"/>
<path class="inner" d="M12,7.37l-1.03,2.08c-0.36,0.74-1.07,1.25-1.88,1.37l-2.3,0.33l1.66,1.62c0.59,0.57,0.86,1.4,0.72,2.21
l-0.39,2.29l2.06-1.08c0.73-0.38,1.6-0.38,2.33,0l2.06,1.08l-0.39-2.29c-0.14-0.81,0.13-1.64,0.72-2.21l1.67-1.62l-2.3-0.33
c-0.81-0.12-1.52-0.63-1.88-1.37L12,7.37z"/>
</svg>

Most practical way of loading svg icons into a html page without repetition? / Should i use <use href>?

My current bad implementation of icons
I am currently working on a new Angular project, and I am not happy with my SVG-icon implementation in my other project (using #ngneat/svg-icon). It requires SVG files to be in a folder, then registered in Typescript and then compiled into (iconName).ts files with a script that has to be run.
An easier Way
In my current project i am using Bootstrap and while studying the docs i stumbled upon the following svg implementation:
Source: https://getbootstrap.com/docs/5.0/components/alerts/
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="check-circle-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
</symbol>
<symbol id="info-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</symbol>
<symbol id="exclamation-triangle-fill" fill="currentColor" viewBox="0 0 16 16">
<path d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"/>
</symbol>
</svg>
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Info:"><use xlink:href="#info-fill"/></svg>
<svg class="bi flex-shrink-0 me-2" width="24" height="24" role="img" aria-label="Success:"><use xlink:href="#check-circle-fill"/></svg>
This usage would have me only paste the svg icons in the Symbols, and have all the icons in a hidden element that i load somewhere on the page. Giving them an appropriate id, this would allow me to use SVG icons anywhere on the page using xlink:href.
Too good to be true
According to MDN the xlink:href attribute is deprecated (Source). But since bootstrap is using it and i found many posts saying that it will never be removed because so many sites are using it, i am tempted to stil use it
A non-deprecated alternative
On the MDN Page of SVG <use> (Source) I found the following example not usin xlink:href but only href instead. At first i though this could only be used to reference another path within the same SVG but upon trying it on my site it worked.
<svg viewBox="0 0 30 10" xmlns="http://www.w3.org/2000/svg">
<circle id="myCircle" cx="5" cy="5" r="4" stroke="blue"/>
<use href="#myCircle" x="10" fill="blue"/>
<use href="#myCircle" x="20" fill="white" stroke="red"/>
<!--
stroke="red" will be ignored here, as stroke was already set on myCircle.
Most attributes (except for x, y, width, height and (xlink:)href)
do not override those set in the ancestor.
That's why the circles have different x positions, but the same stroke value.
-->
</svg>
The Question
So the tl:dr question is "how should i implement my icons?", but here are the questions leading to that:
Would you still reccommend xlink:href since bootstrap is using it?
Is <use href> a valid alternative or is it intendet to be different?
Do Paths with display none have any bad impact like performance or page load, since all of the above mentioned possibilities would include all of my svg icons (even if not used on a specific page) in the html?
a modern <svg-icon> W3C standard Web Component can create the SVG client-side
If you define the Web Component (including icon path info) inside a <script> in the <head> of your HTML document, there are zero extra downloads and icons are displayed instantly when used.
All HTML code required, to display 3 icons
<svg-icon is="menu"></svg-icon>
<svg-icon is="settings"></svg-icon>
<svg-icon is="renew" rotate=45 fill=blue stroke=white></svg-icon>
All script:
<script>
((t,e={path:(t,e="")=>`<path d='${t}' ${e}/>`},r={v1:"",v2:"",v3:"",is:"",img:1,box:9,rect:"<rect width='100%' height='100%' fill='{tile}' {border}/>"
,border:"",filter:"",tile:"none",fill:"none",width:1,scale:1,opacity:1,rotate:0,stroke:"#000",xy:0,w:0,h:0,top:"",api:[t,e]})=>{
customElements.define("svg-icon",class extends HTMLElement{static get observedAttributes(){return Object.keys(r)}attributeChangedCallback(){this.svg()}svg(i=this,s=i.A||Object.keys(i.A={...r}).map((t=>Object.defineProperty(i,t,{set:e=>i.setAttribute(t,e),get:()=>i.getAttribute(t)||getComputedStyle(i).getPropertyValue("--svg-icon-"+t).replace(/"/g,"").trim()||i.A[t]},e[t]=e=>(i.A[t]=e,"")))),l,a=(t[i.is]||"").split`;`.map((t=>([s,l]=t.trim().split`:`,e[s]?e[s].apply(i,l.split`,`):t))).join``,o=i.box/2,
c=`<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 ${i.w||i.box} ${i.h||i.box}'>${i.rect}<g stroke-width='{width}' stroke='{stroke}' fill='{fill}' opacity='{opacity}' filter='{filter}' transform='translate({xy}) matrix({scale} 0 0 {scale} ${o-o*i.scale} ${o-o*i.scale}) rotate({rotate} ${o} ${o})'>${a}</g>${i.top}</svg>`.replace(/{\s?([^{}\s]*)\s?}/g,((t,e)=>i[e]))){return i.innerHTML=1==i.img?
`<img src="data:image/svg+xml,${c.replace(/#/g,"%23")}">`:c}})})(
{
menu:"box:9;path:m1.5 2.8h6m0 2h-6m0 2h6,stroke-linecap='round'",
settings:"box:96;<circle stroke-width='12' cx='48' cy='50' r='26'/><circle stroke-width='12' cx='48' cy='50' r='36' stroke-dasharray='14'/>",
renew:"box:96;fill:black;path:M48 24v12l16-16-16-16v12c-18 0-32 14-32 32 0 6 2 12 5 17L27 60A23 23 0 0 1 24 48c0-13 11-24 24-24zm26 6L69 37c2 3 3 7 3 11 0 13-11 24-24 24v-12l-16 16 16 16v-12c18 0 32-14 32-32 0-6-2-12-5-16z"
});
</script>
<style>
svg-icon {
width: 80px;
display: inline-block;
background: grey;
}
svg-icon:hover { background: lightgrey; cursor:pointer }
</style>
<svg-icon is="menu"></svg-icon>
<svg-icon is="settings"></svg-icon>
<svg-icon is="renew" rotate=45 fill=gold stroke=white></svg-icon>
IconMeister
The <svg-icon> Web Component is fully documented at: https://iconmeister.github.io
Including 7347 icons extracted, and processed to JSON format, from all major Icon Sets:
Bootstrap, Feather, FontAwesome, Google Material, Eva, Radix, IBM Carbon, Linear, Vaadin and Clarity
So the site loads a bit slow, processing 7347 icons...
All <svg-icon> icons are configurable with attributes, properties and CSS properties
Web Component JavaScript code (excluding icons) by itself is only 800 GZipped Bytes.
But that will be less, because your whole HTML document is GZipped.
iconmeister

Add tooltip via JavaScript in Bootstrap 5

How do add a tooltip in Bootstrap v5 via Javascript? I'm tying to add a tooltip and popover to the same element and it seems the best route is to enable both them via JS.
The tooltip added via html works as expected:
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta2/dist/js/bootstrap.bundle.min.js"></script>
<span class="input-group-text mb-3" id="basic-addon2" title="If you want us">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
<path d="M8.93 6.588l-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/>
</svg>
</span>
Next I tried to add the tooltip via JS:
var options =
{
title : "If you want us",
};
var responseTeamMemberSpanElm = document.getElementById("basic-addon2");
var tooltipResponseTeamMember = new bootstrap.Tooltip(responseTeamMemberSpanElm,options );
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta2/dist/js/bootstrap.bundle.min.js"></script>
<span class="input-group-text mb-3" id="basic-addon2" >
<!-- info icon with circle around: from https://icons.getbootstrap.com/icons/info-circle/ -->
<svg "basic-addon2-svg" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
<path d="M8.93 6.588l-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/>
</svg>
</span>
The look of the tooltip looks different. Also, I can put my cursor on the grey background, the tooltip works as expected but when I hover over the circle "i", the tooltip stops working. After I hover over the circle "i", I see the tooltip get moved to the bottom of the screen and the tooltip doesn't work even if I hover elsewhere and come back to the background.
All the older answers I found are using the JQuery version of bootstrap.
Is this a bug or am I doing something wrong?
If you define css propertry pointer-events: none; in all child of tooltip element then its working fine but this may be create a problems on click, hover, focus and other events listener.
So re-initialize tooltip method when hide tooltip by hide.bs.tooltip method in Bootstrap-v5.
Source: https://getbootstrap.com/docs/5.0/components/tooltips/#events
Try below snippet.
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
this.addEventListener('hide.bs.tooltip', function () {
new bootstrap.Tooltip(tooltipTriggerEl)
})
return new bootstrap.Tooltip(tooltipTriggerEl)
});
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta2/dist/js/bootstrap.bundle.min.js" integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" crossorigin="anonymous"></script>
<div class="container mt-5">
<div class="row">
<div class="col-sm-12">
<span class="input-group-text border position-relative" id="basic-addon2" data-bs-toggle="tooltip" data-bs-placement="top" title="If you want us">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle"
viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
<path
d="M8.93 6.588l-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z" />
</svg>
</span>
</div>
<div class="col-sm-12 my-3">
<span class="input-group-text border position-relative" id="basic-addon3" data-bs-toggle="tooltip" data-bs-placement="top" title="If you want us">
<input type="text" class="form-control me-2" placeholder="First Name">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle"
viewBox="0 0 16 16">
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
<path
d="M8.93 6.588l-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z" />
</svg>
</span>
</div>
</div>
</div>

Add Event listener is not working in js inside wordpress theme environement

I am trying to add addEventListener in one of the span tag inside my header.php file but its not working I don't know why. I tried several times. I am working on wordpress theme. I am successfully imported the file. when i put alert('helllo word) outside addEvent listener it works but inside the addEvent listener nothing is working. Please help.
This is my code
header.php
<div class="header__menu">
<span class="header__menu_btn">
<svg class="header__menu_icon" width="3em" height="3em" viewBox="0 0 16 16" class="bi bi-filter-left" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M2 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5zm0-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5zm0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/>
</svg>
</span>
<!-- <svg width="3em" height="3em" viewBox="0 0 16 16" class="bi bi-x" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
</svg> -->
</div>
</nav>
</header>
<div class="header__sidenav">
<div class="header__sidenav_content">
<h1 >Hello From Drawer</h1>
</div>
</div>
header.js
const headerMenuIcon = document.getElementsByClassName("header__menu_btn");
const headerSideBar = document.querySelector("header__sidenav");
headerMenuIcon.addEventListener("click", function () {
headerSideBar.style.width = "100%";
alert("Hello world");
});

How can I change a filter icon status only on the selected item of a list of items in my Angular application?

I am working on an Angular application and I have the following problem. Into a component view I have something like this:
It shown a people list, as you can see next to each person there is a little funnel icon used to filter the output of another component using the selected person (this filter behavior works fine). Once that the funnel icon related to a specific person is clicked it change color to indicate that the filter is active on the specific person.
The problem is that clicking on the funnel icon related a specific person in my list, all the funnel icons of all the persons change color, in this way:
I was handling it in this way into my component view:
<p-orderList [value]="people" [listStyle]="{'height':'400px'}" header="People"
filter="filter" filterBy="name" filterPlaceholder="Filter by name" dragdrop="true">
<ng-template let-person pTemplate="item">
<div class="ui-helper-clearfix fc-event" style="background-color: transparent; color:black !important;border: 0px !important;">
<div class="container">
<div class="row">
<div class="col-sm">
<img src="assets/img/people/person-icon.png" style="display:inline-block;float: left; margin:2px 20px 2px 2px" width="48">
<div style="font-size:14px;margin:15px 5px 0 0">{{person.name}}</div>
</div>
<div class="col-sm">
<div class="people-operations-icons">
<button class="btn" (click)="onClickFilter(person, $event)">
<svg *ngIf="isFilterByPersonActive == false" width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-funnel" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M1.5 1.5A.5.5 0 0 1 2 1h12a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.128.334L10 8.692V13.5a.5.5 0 0 1-.342.474l-3 1A.5.5 0 0 1 6 14.5V8.692L1.628 3.834A.5.5 0 0 1 1.5 3.5v-2zm1 .5v1.308l4.372 4.858A.5.5 0 0 1 7 8.5v5.306l2-.666V8.5a.5.5 0 0 1 .128-.334L13.5 3.308V2h-11z"/>
</svg>
<svg *ngIf="isFilterByPersonActive == true" width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-funnel-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M1.5 1.5A.5.5 0 0 1 2 1h12a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.128.334L10 8.692V13.5a.5.5 0 0 1-.342.474l-3 1A.5.5 0 0 1 6 14.5V8.692L1.628 3.834A.5.5 0 0 1 1.5 3.5v-2z"/>
</svg>
</button>
</div>
</div>
</div>
</div>
</div>
</ng-template>
As you can see to choose the empty or the full funnel icon I am doing:
<button class="btn" (click)="onClickFilter(person, $event)">
<svg *ngIf="isFilterByPersonActive == false" width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-funnel" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M1.5 1.5A.5.5 0 0 1 2 1h12a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.128.334L10 8.692V13.5a.5.5 0 0 1-.342.474l-3 1A.5.5 0 0 1 6 14.5V8.692L1.628 3.834A.5.5 0 0 1 1.5 3.5v-2zm1 .5v1.308l4.372 4.858A.5.5 0 0 1 7 8.5v5.306l2-.666V8.5a.5.5 0 0 1 .128-.334L13.5 3.308V2h-11z"/>
</svg>
<svg *ngIf="isFilterByPersonActive == true" width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-funnel-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M1.5 1.5A.5.5 0 0 1 2 1h12a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.128.334L10 8.692V13.5a.5.5 0 0 1-.342.474l-3 1A.5.5 0 0 1 6 14.5V8.692L1.628 3.834A.5.5 0 0 1 1.5 3.5v-2z"/>
</svg>
</button>
So I am using this isFilterByPersonActive variable defined in my typescript code. This variable is false by default and when the user click the funnel it change status and become true.
The problem is that in this way it works on all the member of my list and not only on the selected one. How can I activate this behavior only on the selected item?
Create a component for single persona item and use it for rendering personas items in list. All of your items will have their personal state which u can mutate with its own value/data

Categories

Resources