Javascript button colour change not working with hex code? - javascript

I'm working on a project where subscribers to a site can choose between a monthly and yearly subscription. The user has to choose their subscription type by clicking on a monthly or yearly button (Button code below)
<!-- Select Subscription Instructions -->
<p class="mb-0">
<strong>Select your subscription type then click subscribe:</strong>
</p>
<!-- Yearly Subscription Button -->
<button id="yearly_subscription_selected" class="btn mr-2" type="submit" onclick="">
Yearly Membership: £41.50 plus VAT
</button>
<!-- Monthly Subscription Button -->
<button id="monthly_subscription_selected" class="btn my-2" type="submit" onclick="">
Monthly Membership: £8.25 plus VAT
</button>
When the user clicks on one of these buttons the href="" behind the subscribe button will change (This is working correctly)
I also want the membership button the user clicks on to change the background colour while the unselected membership button remains white. I have used the following JS code for this:
// Membership select Year JS
document.getElementById("yearly_subscription_selected").onclick = function () {
let link = document.getElementById("abc");
link.setAttribute("href", "https://www.checkouty.htm");
document.getElementById("yearly_subscription_selected").setAttribute("style", "background-color: green; color: #fff");
if (document.getElementById("yearly_subscription_selected").style.backgroundColor == "green") {
document.getElementById("monthly_subscription_selected").setAttribute("style", "background-color: white; color: #000");
}
return false;
}
// Membership select Month JS
document.getElementById("monthly_subscription_selected").onclick = function () {
let link = document.getElementById("abc");
link.setAttribute("href", "https://www.checkoutm.htm");
document.getElementById("monthly_subscription_selected").setAttribute("style", "background-color: green; color: #fff");
if (document.getElementById("monthly_subscription_selected").style.backgroundColor == "green") {
document.getElementById("yearly_subscription_selected").setAttribute("style", "background-color: white; color: #000");
}
return false;
}
This code above is working and when the user selects a membership option the selected option button will turn green and the none selected button will turn white. However, if I change the background-color: "green"; and replace it with the hex colour code background-color: #bf1363 then the JS stops working and when you click on both buttons to switch between the memberships both buttons turn the same colour #bf1363.
// Membership select Year JS
document.getElementById("yearly_subscription_selected").onclick = function () {
let link = document.getElementById("abc");
link.setAttribute("href", "https://www.checkouty.htm");
document.getElementById("yearly_subscription_selected").setAttribute("style", "background-color: #bf1363; color: #fff");
if (document.getElementById("yearly_subscription_selected").style.backgroundColor == "#bf1363") {
document.getElementById("monthly_subscription_selected").setAttribute("style", "background-color: white; color: #000");
}
return false;
}
// Membership select Month JS
document.getElementById("monthly_subscription_selected").onclick = function () {
let link = document.getElementById("abc");
link.setAttribute("href", "https://www.checkoutm.htm");
document.getElementById("monthly_subscription_selected").setAttribute("style", "background-color: #bf1363; color: #fff");
if (document.getElementById("monthly_subscription_selected").style.backgroundColor == "#bf1363") {
document.getElementById("yearly_subscription_selected").setAttribute("style", "background-color: white; color: #000");
}
return false;
}
Does anyone know why this might be happening?? I'm using bootstrap 4 and vanilla JS

Because when you do:
document.getElementById("yearly_subscription_selected").style.backgroundColor = "#bf1363";
console.log(document.getElementById("yearly_subscription_selected").style.backgroundColor);
It will return:
rgb(191, 19, 99)
So you can't compare that value with your string #bf1363 that's just one of the many ways to encode a color value.
Refactor
Anyway since your code had so many repetitions and was directly changing the element style instead of using css classes, I took the chance to better refactor your code to show that the same result could be achieved differently.
Here you have two css classes btn-subscription and active. The first is styling the button when it still isn't active (white bg) and the second one will style the button as active (purple bg).
Plus each of those buttons store the url where the link is supposed to point at as a data-url attribute.
That way you can have a single event handler that will deal with the click event occurring on both the buttons:
let link = document.getElementById("abc");
//selects all the `.btn-subscription` elements
document.querySelectorAll('.btn-subscription')
//for each one of them as btn
.forEach( btn => {
//adds the click event handler
btn.addEventListener('click', (event)=>{
//the currently clicked button
const clickedButton = event.target;
//changes the href attribute of link as the data-url of the currently clicked btn
link.setAttribute("href", clickedButton.dataset.url);
//removes the active class from the first element .btn-subscription having it (if any)
document.querySelector('.btn-subscription.active')?.classList.remove('active');
//adds the class active only to the currently clicked button
clickedButton.classList.add('active');
});
});
#abc{
display: block;
margin-top: 2rem;
border: solid;
padding: 1em;
}
/*just to show on screen the href attribute value*/
#abc::before{
border: dashed 3px lightgray;
content: "href: " attr(href);
display: block;
padding: 4px .5em;
margin-bottom: 1em;
}
.btn-subscription{
cursor: pointer;
background-color: white;
color: #000;
}
.active{
background-color: #bf1363;
color: #fff;
}
<!-- Select Subscription Instructions -->
<p class="mb-0">
<strong>Select your subscription type then click subscribe:</strong>
</p>
<!-- Yearly Subscription Button -->
<button
id="yearly_subscription_selected"
class="btn mr-2 btn-subscription"
type="button"
data-url="https://www.checkouty.htm">
Yearly Membership: £41.50 plus VAT
</button>
<!-- Monthly Subscription Button -->
<button
id="monthly_subscription_selected"
class="btn my-2 btn-subscription"
type="button"
data-url="https://www.checkoutm.htm">
Monthly Membership: £8.25 plus VAT
</button>
<a id="abc" href="">Link target element</a>

Related

How to focus one button by default?

I'm having trouble with 2 buttons that each toggles different "div" elements. I want to focus "button 1" by default. How do I do that? Autofocus is not working. Here's the HTML code
<div class="filter">
<button class="filter-btn active" data-target="#block-1" autofocus>1</button>
<button class="filter-btn" data-target="#block-2">2</button>
</div>
Here's the JS code
let $blocks = $(".block-card");
$(".filter-btn").on("click", (e) => {
let $btn = $(e.target).addClass("active");
$btn.siblings().removeClass("active");
let selector = $btn.data("target");
$blocks.removeClass("active").filter(selector).addClass("active");
});
If autofocus is not working due to browser behavior or styling of other elements, you can still use Javascript to set focus.
Example:
document.querySelector(".filter-btn.active").focus({focusVisible: true});
{focusVisible: true} is optional here and it forces browser to make the focus visible.
There is a jQuery equivalent, but it seems that it does not take the optional config.
Example:
$(".filter-btn.active").focus();
Some CSS can be added to making testing easier.
Example:
button:focus {
color: crimson;
}
button:focus-visible {
outline: 2px solid crimson;
border-radius: 3px;
}
When running the following example, note that the first button should be focused.
Full example: (run it in live with button below)
document.querySelector(".filter-btn.active").focus({focusVisible: true});
button:focus{ color: crimson }
button:focus-visible {
outline: 2px solid crimson;
border-radius: 3px;
}
<div class="filter">
<button class="filter-btn active" data-target="#block-1">1</button>
<button class="filter-btn" data-target="#block-2">2</button>
</div>
Hope this will help!

HTML/CSS/JS: 'Show' answer on button press

I am creating a quiz for my webpage. Currently, I have a function working on the first question. Where a button will say "Show Solution". Once clicked, it will show the element. Currently the button doesn't change the button text to "Hide Solution" once it has been displayed.
The main problem is that i have multiple questions. And when i click show solution it will show the first question.
I know that the function is linked to that function, but I do not want to copy the function multiple times and change the IDs to answer1, answer2 etc...
I have looked at posts on google/stack and YouTube videos and I just don't understand it really.
Here is my code
function show_hide()
{
var myAnswer = document.getElementById('answer');
var displaySetting = myAnswer.style.display;
var quizButton = document.getElementsByClassName('quiz-button');
if(displaySetting=="inline-block"){
myAnswer.style.display = 'none';
quizButton.innerHTML = 'Show Answer';
}
else
{
myAnswer.style.display = 'inline-block';
quizButton.innerHTML = 'Hide Answer';
}
}
.quiz-question{
margin-bottom: 10px;
text-align: left;
font-size: 15px;
color: #f44336;
font-weight: 400;
}
.quiz-button{
display: inline-block;
text-decoration: none;
color: #111;
border: 1px solid #f44336;
padding: 5px 5px;
font-size: 13px;
background: transparent;
position: relative;
cursor: pointer;
}
.quiz-button:hover{
color: #fff;
background: #f44336;
transition: 0.5s;
}
#answer{
display: none;
}
<div class="part-content quiz">
<h2>Chapter 1.1 End of Topic Quiz</h2>
<p>
The following quiz is meant to reinforce your understanding of the material presented above.
</p>
<!-- Question 1 Start -->
<h4 class="quiz-question">1. What is a statement? </h4>
<button onclick="show_hide()" class="quiz-button">Show Solution</button>
<p id="answer">
A <b>statement</b> is an instruction in a computer program that tells the computer to perform an action.
</p>
<br><br><hr>
<!-- Question 1 End -->
<!-- Question 2 Start -->
<h4 class="quiz-question">2. What is a function? </h4>
<button onclick="show_hide()" class="quiz-button">Show Solution</button>
<p id="answer">
A <b>function</b> is several statements that are executed sequentially.
</p>
<br><br><hr>
</div>
Here is one of the easiest solutions:
Change all onclick="show_hide()" to onclick="show_hide(this)"
Change your JS to:
<script>
function show_hide(element)
{
var myAnswer = element.nextElementSibling;
var displaySetting = myAnswer.style.display;
var quizButton = element;
if(displaySetting=="inline-block"){
myAnswer.style.display = 'none';
quizButton.innerHTML = 'Show Answer';
}
else
{
myAnswer.style.display = 'inline-block';
quizButton.innerHTML = 'Hide Answer';
}
}
</script>
With this, you won't need to refer to the answer's ID anymore.
The "this" in the onclick attribute is referring to the button itself, and the "nextElementSibling" refers to the next element (which is the containing the answer in your case) of the element (button). So actually var myAnswer means to get the next element of the button.
However, with this function, you need to make sure the button's next element is the answer element, else won't be working.
Also, the reason why directly var quizButton = document.getElementsByClassName('quiz-button'); won't work is because as you see, it gets multiple elements instead of one element. Different elements can have the same class. This will return an array of the elements having the class instead of the first element having the class.

How can I make Icon bigger without changing the button size?

I recently had this code to have a button that copies the URL to the clipboard. It had a text displayed on the button ("copy") and after clicking on the button the text turned to "kopiert" ("copied"). 2 seconds later it turned back.
Now I changed the originalText to an Icon. The problem is, that the icon turns into the old "kopiert" text and after 2 Seconds it turns to the originalText. But the Icon is not a text anymore, so it turns to nothing. How can I change that, so it turns back to the Icon again? Also I would like to replace the "kopiert" text to the same icon, but the icon is a little more bigger. What method or function can I use to achieve this?
The turning back to Icon is fixed. I only don't know how to make the Icon bigger in Javascript. I guess I need to change the Font-Size, but how can I do that in Javascript?
I changed the Fontsize with https://stackoverflow.com/a/56825511/14969267. Now the Problem is, that the Button size changes, because of the font-size.
EDIT: I fixed the whole Issue. Thanks for the help!
var $temp = $("<input>");
var $url = $(location).attr('href');
$('.clipboard').on('click', function() {
const originalText = $('.clipboard').html();
// CSS function:
const addCSS = s => document.head.appendChild(document.createElement("style")).innerHTML=s;
$("body").append($temp);
$temp.val($url).select();
document.execCommand("copy");
$temp.remove();
$('.clipboard').html(originalText);
// CSS Usage:
addCSS(".clipboard{ font-size: 20px; padding: 4.8px 21.3px 4.8px 21.3px; }")
// Run something in 1 seconds to revert back to the button's text
setTimeout(function() {
addCSS(".clipboard{ font-size: 15px; padding: 9px 21.3px 9px 21.3px}")
$('.clipboard').html(originalText);
}, 1000); // 1 seconds
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="background">
<center>
<button class="clipboard"><i class="fas fa-copy"></i></button>
</center>
</div>
A common strategy here is to simply put each possible button content in a span element (or other inline element) and toggle them as needed. That saves you from having to track and create text content. You can style each inner element as needed with CSS and call it good.
var $temp = $("<input>");
var $url = $(location).attr('href');
$('.clipboard').on('click', function(e) {
const btn = $(this);
// copy to clipboard
$("body").append($temp);
$temp.val($url).select();
document.execCommand("copy");
$temp.remove();
// show copied message
btn.find('i').hide();
btn.find('.copied-text').show();
// Wait 1 second to revert the button content
setTimeout(function() {
btn.find('.copied-text').hide();
btn.find('i').show();
}, 1000); // 1 seconds
})
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css" integrity="sha512-iBBXm8fW90+nuLcSKlbmrPcLa0OT92xO1BIsZ+ywDWZCvqsWgccV3gFoRBv0z+8dLJgyAHIhR35VZc2oM/gI1w==" crossorigin="anonymous" referrerpolicy="no-referrer"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style>
.background {
text-align: center;
}
button {
font-size: 20px;
padding: 4.8px 21.3px 4.8px 21.3px;
min-width: 140px;
}
.copied-text {
display: none;
font-size: 15px;
padding: 9px 21.3px 9px 21.3px;
}
</style>
<div class="background">
<button class="clipboard">
<i class="fas fa-copy"></i>
<span class="copied-text">Kopiert</span>
</button>
<button class="clipboard">
<i class="fas fa-copy"></i>
<span class="copied-text">Kopiert</span>
</button>
</div>

Can the input value of the button be an image which changes when toggled?

I have a button which shows and hides an element when clicked. It also changes the value to 'Show' or 'Hide'. I would like to have an image (along with the text) in the value attribute of the button to change along with the text when I toggle.
EDIT: I updated my codepen with solutions advised. There are however, other issues to solve there.
Here is a codepen showing what I mean visually
Here is a snippet.
function toggle(ele) {
var cont = document.getElementById('proj-details');
if (cont.style.display == 'flex') {
cont.style.display = 'none';
document.getElementById(ele.id).value = 'Show details';
} else {
cont.style.display = 'flex';
document.getElementById(ele.id).value = 'Hide details';
}
}
.spec-proj-briefshowhide {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding-left: 3em;
padding-right: 3em;
}
.spec-proj-briefshowhide input {
padding: 0.4em;
color: blue;
font-size: 0.8em;
font-weight: 400;
text-transform: uppercase;
cursor: pointer;
background-color: white;
border: 0.05em solid blue;
border-radius: 0.5em;
}
.spec-proj-briefshowhide img {
max-width: 10em;
padding: 2em;
display: flex;
flex-direction: column;
}
button {
display: flex;
flex-direction: row;
align-items: center;
}
<div class="spec-proj-briefshowhide">
<p>
<input type="button" value="Hide details" id="bt" onclick="toggle(this)">
</p>
<div style="display:flex;" id="proj-details">
<div>
<p>Brief:</p>
<ul>
<li>So I have this show/hide toggle button working to my liking.</li>
<li>What I would also like is to have an image along with text in the button.</li>
<li>You see..? I have the value attribute of the button changing as I click on it to toggle.</li>
<li>What I would want is an image with open-eyes to represent the displayed element and another image close-eyes to represent when I toggle the button to hide the details. Check what I mean by close and open eyes before thinking I am crazy.</li>
<li>I noticed people use image background, especially when they want a button to look like a play button, pause button or a record button. These are static buttons and do not change.</li>
<li>I want a change of image instead, because I have two images which need to be toggled back and forth</li>
</ul>
</div>
</div>
<p>Here are the two images for the curious kind.<img src="https://i.ibb.co/NjRDMFS/OPENEYE.png" alt="OPENEYE" border="0">
<img src="https://i.ibb.co/yPhD6HF/CLOSEEYE.png" alt="CLOSEEYE" border="0">
</p>
<button>Show<img src="https://i.ibb.co/NjRDMFS/OPENEYE.png" alt="OPENEYE" border="0">details</button>
<button>Hide<img src="https://i.ibb.co/yPhD6HF/CLOSEEYE.png" alt="CLOSEEYE" border="0">details</button>
</div>
The purpose of the name and value fields in input is for submittal of a form to the server.
So as far as setting an image in a value field - you could include an image href in the value field, but it wouldn't automatically render the image. You can't include an image and a text value.
What I suggest you do if you want to have both and to submit both to the server is to use an input type=hidden field with the image url, plus a separate img tag for the visual image, like
<p>
<table><tr>
<td id="imgTD"><input type="hidden" name="imgField" id="imgField" /> </td>
</tr>
<tr><td>
<input type="button" value="Hide details" id="bt" onclick="toggle(this)">
</td></tr>
</table>
</p>
Putting together my code example, I notice that you haven't given your button a name. If the button is not for form purposes, you might want to use the button tag instead of an input
there is another simple way to just the image src :
const imgBtn = document.getElementById("eye")
function toggleImg(){
let cont = document.getElementById('proj-details');
if (cont.style.display == 'flex') {
cont.style.display = 'none';
imgBtn.src = "https://i.ibb.co/yPhD6HF/CLOSEEYE.png"
} else {
cont.style.display = 'flex';
imgBtn.src = "https://i.ibb.co/NjRDMFS/OPENEYE.png"
}
}
imgBtn.addEventListener("click",toggleImg)
<div class="spec-proj-briefshowhide">
<img id="eye" src="https://i.ibb.co/NjRDMFS/OPENEYE.png" alt="OPENEYE" border="0">
<p>
<input type="button" value="Hide details" id="bt" onclick="toggle(this)">
</p>
<div style="display:flex;" id="proj-details">
<p>Brief:</p>
<ul>
<li>So I have this show/hide toggle button working to my liking.</li>
<li>What I would also like is to have an image along with text in the button.</li>
<li>You see..? I have the value attribute of the button changing as I click on it to toggle.</li>
<li>What I would want is an image with open-eyes to represent the displayed element and another image close-eyes to represent when I toggle the button to hide the details. Check what I mean by close and open eyes before thinking I am crazy.</li>
<li>I noticed people use image background, especially when they want a button to look like a play button, pause button or a record button. These are static buttons and do not change.</li>
<li>I want a change of image instead, because I have two images which need to be toggled back and forth.</li>
</ul>
</div>
<p>Here are the two images for the curious kind.</p>
</div>

Keep button in active state until clicked off

This is the page I'm working on: https://www.maisondefemmes.com/product/choose-your-own-adventure-earrings/
I want the buttons to stay in an active state until unclicked so that the user can clearly see what they have selected.
I have read and followed these instructions, to no avail: Keep button in active state until clicked upon again
NB: The 'button' used to be a toggle switch that I have turned off. Not sure if this is causing an issue.
I've added this JQuery to my theme:
$('.bundled_product_optional_checkbox').click(function(){
if($(this).hasClass('active')){
$(this).removeClass('active')
} else {
$(this).addClass('active')
}
});
As well as this CSS:
.bundled_product_optional_checkbox.active {
background-color: #cfb87c !important;
border: 1px solid #cfb87c !important;
}
<label class="bundled_product_optional_checkbox">
<input class="bundled_product_checkbox" type="checkbox" name="component_1592104877_bundle_selected_optional_4" value>
" Add for "
<span class="price">
<span class="woocommerce-Price-amount amount">
<span class="woocommerce-Price-currencySymbol">$</span>
</span>
</span>
::after
</label>
Appreciate any answers. Please be kind.
Just create your own class called active
<button class="Toggle Button">Toggle Button</button>
then create your own class active and style it in css
.active{
border: none;
background: teal;
color: white;
}
Now in jQuery toggle the active class on click
$('.toggle-button').click( function() {
$('.toggle-button').toggleClass('active');
});
Now you should have a working toggle switch
Here is the link to my code pen:
https://codepen.io/prabodhpanda/pen/pogNqpQ
answer updated..
if you are not using bootstrap then you can ignore those classes and CDN links : )
$('.bundled_product_optional_checkbox').click(function(){
if($(this).hasClass('active')){
$(this).removeClass('active')
} else {
$(this).addClass('active')
}
});
.bundled_product_optional_checkbox.active {
background-color: #cfb87c !important;
border: 1px solid #cfb87c !important;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="btn btn-lg btn-default border bundled_product_optional_checkbox">Click me</button>

Categories

Resources