color icons upto the hover position - javascript

I have 10 circles (Fontawesome icons) horizontally placed. I want to fill colors to them when the user hover on any icon. For ex: if the user hovers on the 5th circle, all the circles upto the 5th circle should fill in color. (Something like in a rating system) How can i do it?
Following is the code which i render 10 circles.
export const RatePersonalityCard = ({}) => {
for (let score = 1; score < 11; score++) {
let scoreList = [];
scoreList.push(
<div className="trait_vote_single tooltip" style={{fontSize:'40px',color:'gray'}} onClick={() => handleClick(score)}>
{/*<div className="trait_vote_circle"></div>*/}
<i className="fa fa-circle-thin" aria-hidden="true"></i>
<a className="trait_value" style={{marginTop:'-34px',marginLeft:'-1px'}}>{score}</a>
<span className="tooltiptext2 unchange_div" style={{marginLeft: '-40px'}}>{starvalue}</span>
</div>
)
}
return (
<div className="">
<div className="single_trait_rate width_100 text_align_center">{userTraits.trait_name}</div>
<div className="trait_vote_div">
{scoreList}
</div>
</div>
);
};

You could create a hover event for each for every score list item that adds a class to the currently hovered item and everything prior. Then add a blur event to every item to remove the class.
function handleHover(e) {
let index = scoreList.indexOf(e.target);
for (let i = 0; i <= index; i++) {
scoreList[index].classList.add('highlight');
}
}
function handleBlur(e) {
scoreList.forEach(function(item) {
item.classList.remove('highlight');
});
}

No CSS example. I don't see great value in adding any JS to something that can simply done via CSS. If you also need a click event, it's as simple as 1 class on 1 span. I'd also recommend reading:
Decoupling Your HTML, CSS, and JavaScrip which my code does not do.
span .fa-star{
display: none;
}
span:hover > .fa-star{
color: yellow;
display: inline-block;
color: red;
}
span:hover > .fa-star-o{
display: none;
}
span { cursor: pointer }
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<span>
<i class="fa fa-star-o" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
<span>
<i class="fa fa-star-o" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
<span>
<i class="fa fa-star-o" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
<span>
<i class="fa fa-star-o" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
<span>
<i class="fa fa-star-o" aria-hidden="true"></i>
<i class="fa fa-star" aria-hidden="true"></i>
</span>
</span>
</span>
</span>
</span>

Related

swapping font awesome fonts

i am trying to create a star rating list using jQuery, html and css. at the moment the icons appear through a class im assuming this just calls the class from the font awesome link i used
(<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />)
i have tried but i cant find any way to swap the star for a basic asterisk ive tried to used content : " * "; and other types of content tags that refer to asterisks but to no avail
due to the link being a web link and the font isnt actually called inside the code im having trouble changing them
essentially i need to remove the fa fa-star part and have a normal asterisk there, and i cant have it outside the class or my Jquery will display any stars when triggered
.stars {
position: absolute;
width: 100px;
top: 42px;
left: 180px;
}
.checked {
color: #F0191C;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
<div class="stars">
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
<span class="fa fa-star checked"></span>
</div>

How to target all elements with Jquery on click

Only first element getting clicked not all, how to get alert on all elements.
Jsfiddle
var btn = document.querySelector(".box i");
btn.onclick = function () {
alert('hello');
}
<div class="box">
<i class="fa fa-address-book-o" aria-hidden="true"></i>
<i class="fa fa-address-book-o" aria-hidden="true"></i>
<i class="fa fa-address-book-o" aria-hidden="true"></i>
<i class="fa fa-address-book-o" aria-hidden="true"></i>
</div>
Try querySelectorAll for select all then attract onclick to all element
var btnlist = document.querySelectorAll(".box i");
btnlist.forEach(element =>{element.onclick = function () {
alert('hello');
}});
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<div class="box">
<i class="fa fa-address-book-o" aria-hidden="true"></i>
<i class="fa fa-address-book-o" aria-hidden="true"></i>
<i class="fa fa-address-book-o" aria-hidden="true"></i>
<i class="fa fa-address-book-o" aria-hidden="true"></i>
</div>
Despite the title of the question, you don't currently use jQuery in your code. So, I provide 2 solutions:
jQuery:
jQuery('.box i').click(function() {
alert('hello');
});
Pure JS
window.addEventListener('click', function(e) {
// or e.target.classList.contains('fa-address-book-o')
if (e.target.className === 'fa fa-address-book-o') { // Better to add some additional class to identify element, like "fireAlert" for instance.
alert('hello');
}
});
Alternatively, you could select icons with query selector and add individual event listeners to all of them in a loop, but it's bad for performance & generally not considered a good thing to do.
The reason why it only work on the first element is that using .querySelector() method will select only the first element the meet your selector criteria, to be able to select all the elements you have to use .querySelectorAll() which will return a NodeList which can iterate through like this:
var btns = document.querySelectorAll(".box i");
btns.forEach((el, i) => {
el.onclick = function () {
console.log(`Hello! ${i}`);
}
});
<div class="box">
<i class="fa fa-address-book-o" aria-hidden="true">1</i>
<i class="fa fa-address-book-o" aria-hidden="true">2</i>
<i class="fa fa-address-book-o" aria-hidden="true">4</i>
<i class="fa fa-address-book-o" aria-hidden="true">5</i>
</div>

how to toggle between icons when a button is clicked?

I want to switch between a moon and a sun when the dark mode is enabled or disabled.
Now I have it that I can change once, but after that it stays as a moon.
How do I fix this this?
function darkmode() {
document.body.classList.toggle('dark-mode');
document.getElementById('toggleknop').innerHTML = '<i class="fas fa-moon fa-2x" id="maan" style="color:#737eac;"></i>';
}
<button onclick="darkmode()" id="Knop">
<span id="toggleknop"><i class="fas fa-sun fa-2x" id="zon" style="color:#d8c658;"></i></span>
</button>
You can change/toggle easily Drak <=> Light only using CSS.
just use 'document.body.classList.toggle('dark-mode');' code only for toggle. show icon depend on the parent class. please see the snippet here:
function darkmode() {
document.body.classList.toggle('dark-mode');
}
.dark-mode button {
background: black;
color: white;
}
.dark-mode .sun-icon,
.moon-icon {
display: none;
}
.dark-mode .moon-icon {
display: inline;
}
<button onclick="darkmode()" id="Knop">
click
<span class="sun-icon">
sun <i class="fas fa-sun fa-2x" id="zon" style="color:#d8c658;"></i>
</span>
<span class="moon-icon">
moon <i class="fas fa-moon fa-2x" id="maan" style="color:#737eac;"></i>
</span>
</button>
Maybe it helps to solve your problem.
Thank you
var currentTheme = 'dark';
function changeTheme() {
document.body.classList.toggle('dark-mode');
if (currentTheme === 'dark') {
document.getElementById('toggleknop').innerHTML = '<i class="fas fa-sun fa-2x" id="zon" style="color:#d8c658;"></i>';
currentTheme = 'sun';
}else {
document.getElementById('toggleknop').innerHTML = '<i class="fas fa-moon fa-2x" id="maan" style="color:#737eac;"></i>';
currentTheme = 'dark';
}
}
You need to remember whether you are in dark mode with a variable stored outside the function:
var inDarkMode = false;
function toggleDarkMode() {
if (inDarkMode) {
document.body.classList.remove('dark-mode');
document.getElementById('toggleknop').innerHTML =
'<i class="fas fa-moon fa-2x" id="maan" style="color:#737eac;"></i>';
inDarkMode = false;
} else {
document.body.classList.add('dark-mode');
document.getElementById('toggleknop').innerHTML =
'<i class="fas fa-sun fa-2x" id="zon" style="color:#d8c658;"></i>';
inDarkMode = true;
}
}
Use hasClass to check if it contains class.
function darkmode() {
document.body.classList.toggle('dark-mode');
var toggleknop= document.getElementById('toggleknop');
if(toggleknop.hasClass('fa-sun')
{
toggleknop.classList.remove('fa-sun');
toggleknop.classList.add('fa-moon');
//Your styling
}
else if(toggleknop.hasClass('fa-moon') {
toggleknop.classList.remove('fa-moon');
toggleknop.classList.add('fa-sun');//Your styling
}
function darkmode() {
document.body.classList.toggle('dark-mode');
document.getElementById('toggleknop').innerHTML = document.body.classList.contains('dark-mode') ? '<i class="fas fa-moon fa-2x" id="maan" style="color:#737eac;"></i>' : '<i class="fas fa-sun fa-2x" id="zon" style="color:#d8c658;"></i>';
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" rel="stylesheet"/>
<button onclick="darkmode()" id="Knop">
<span id="toggleknop"><i class="fas fa-sun fa-2x" id="zon" style="color:#d8c658;"></i></span>
</button>
function darkmode() {
document.body.classList.toggle('dark-mode');
document.getElementById('toggleknop').innerHTML = document.body.classList.contains('dark-mode') ? '<i class="fas fa-moon fa-2x" id="maan" style="color:#737eac;"></i>' : '<i class="fas fa-sun fa-2x" id="zon" style="color:#d8c658;"></i>';
}

Dynamically determine which button of a particular class has been clicked with jquery

A demo of my dilemma here
Let's say I have the following html:
<html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<body>
<div class="main" id="thingSection">
<h1>
Test Header
</h1>
<button class="btn-icon"><i class="fa fa-fw fa-lg fa-windows"></i> <i class="fa fa-fw fa-lg fa-toggle-off"></i> <i class="fa fa-fw fa-lg fa-apple"></i></button>
<div class="content" id="content1">
Some content
</div>
</div>
<hr />
<div class="main" id="thingSection1">
<h1>
Another Test
</h1>
<button class="btn-icon"><i class="fa fa-fw fa-lg fa-windows"></i> <i class="fa fa-fw fa-lg fa-toggle-off"></i> <i class="fa fa-fw fa-lg fa-apple"></i></button>
<div class="content" id="content2">
Some content
</div>
</div>
<hr>
<div class="main" id="thingSection2">
<h1>
Another test, you say?
</h1>
<button class="btn-icon"><i class="fa fa-fw fa-lg fa-windows"></i> <i class="fa fa-fw fa-lg fa-toggle-off"></i> <i class="fa fa-fw fa-lg fa-apple"></i></button>
<div class="content" id="content3">
Some content
</div>
</div>
</body>
</html>
I am using the following jquery to change the toggle icon from FontAwesome from off to on:
$(function() {
$('.btn-icon').click(function() {
if ($(this).find($(".fa")).hasClass('fa-toggle-off')) {
$("i.fa-toggle-off").toggleClass('fa-toggle-on');
} else {
$("i.fa-toggle-on").toggleClass('fa-toggle-off');
}
});
});
When I click the button to toggle the icon, it works as expected, i.e. it changes all of the buttons on the page. However, I would like to dynamically determine which button has been pressed, and then change the content of a child div based on the position of the switch.
I want to avoid hardcoding id's for each button to avoid a ton of if/else statements in the script that must be updated each time I, say, add a new button or a new section. That is to say, I want to dynamically detect which button has been pressed, and affect only that button and its children.
I've noticed that console.log(this) yields only the HTML for the particular button that has been pressed, not all of the buttons.
I'm a novice with jquery. I haven't been able to find a solution to this problem yet, and I feel like there has to be a way to do this dynamically without hardcoding IDs.
EDIT: I've accomplished (partially) what I want to do with the following code:
$(function() {
$('.btn-icon').click(function() {
var t = $(this).find('.is-toggle');
if (t.hasClass('fa-toggle-off')) {
t.addClass('fa-toggle-on');
t.removeClass('fa-toggle-off');
}
else {
t.addClass('fa-toggle-off');
t.removeClass('fa-toggle-on');
}
});
});
Looks like I just didn't understand what exactly $(this) was (:
All you need is $(this) that selects the element that triggered the event. From there you can select down to the div you want.
EDIT: Here is how that might look in code, I pulled this from your fiddle and edited it
$(function() {
$('.btn-icon').click(function() {
$(this).children('.fa-toggle-off, .fa-toggle-on').toggleClass('fa-toggle-on fa-toggle-off');
});
});

How to extract text from element with attribute style="display:none;

HTML of that part is:
<div class="review-small-text">
<span class="stars-rate">
<span property="starsRating">
<i class="fa fa-star-yellow fa-star"></i>
<i class="fa fa-star-yellow fa-star"></i>
<i class="fa fa-star-yellow fa-star"></i>
<i class="fa fa-star-yellow fa-star"></i>
<i class="fa fa-star-yellow fa-star"></i>
</span>
</span>
<span property="reviewRating" typeof="Rating" style="display:none;">
<span property="ratingValue">5</span>
<span property="bestRating">5</span>
<span property="worstRating">0</span>
</span>
<span property="itemReviewed" typeof="Service" class="">Liposuction</span> </div>
I'm trying to extract the second span's ratingValue of a particular review using selenium and i tried to extract that value by using this css selector:
'div.review-small-text>span:nth-of-type(2)>span:nth-of-type(1)'
but it is giving me an empty string.
have also tried this one
'div.review-small-text>span:nth-child(2)>span:nth-child(1)'
so I think the problem is not in the css-selector. Display none is creating an issue here.
Is there any possible way to extract that value?
Python source code that i have tried so far is:
from selenium import webdriver
import time
url = "myurlhere"
driver = webdriver.Chrome()
driver.get(url)
time.sleep(3)
all_reviews_listings = driver.find_elements_by_xpath("//div[#id='tab_reviews']/div[#class='provider_all_Reviews']/div[#id='pnlReviews']/div")
for review in all_reviews_listings:
review_rating = review.find_element_by_css_selector('div.review-small-text>span:nth-of-type(2)>span:nth-of-type(1)').text
print("Review Rating: ", review_rating)
Here is the css to get the ratingValue.
Using JavaScript:
review_rating = driver.execute_script("""return document.querySelector(".review-small-text > span[property='reviewRating'] > span[property='ratingValue']").textContent""")
Without JavaScript: Alternatively you can also do this.
driver.find_element_by_css_selector(".review-small-text > span:nth-child(2) > span[property='ratingValue']").get_attribute("textContent")
The ancestor tag is having the attribute style="display:none;, so to extract all the reviewRatings you can use the following solution:
driver.execute_script("arguments[0].removeAttribute('style')", driver.find_element_by_css_selector("div.review-small-text span[property='reviewRating'][typeof='Rating']"))
print([element.text for element in driver.find_elements_css_selector("div.review-small-text span[property='reviewRating'][typeof='Rating'] span")])

Categories

Resources