"Add to favourites" button to change class and innerHTML - javascript

I need to make an "Add to favs" button that would toggle between "Add" and "Added" states. The trick is that when in "Added" state, I want it to have a hover behaviour like all red and saying "Remove from favs". BUT when you click the button for the 1st time and it changes to "Added", I don't want the 'remove' style turn on immediately.
My solution is to create 2 classes: .isChecked and .isJustPressed. The first is used to determine the button actual state and the second is used to apply the "remove from favs" hover styling only after the mouseleave event.
These classes are handled by jQuery. I am quite new to the language, so I've come up with such working solution (see below). The CSS is simplified. Well the reason I posted this is that I feel there must be a more elegant way to solve this. And besides, I don't like my jQuery code, so I'd appreciate any comments there also
$('.fav_btn').click(function(event) {
$(this).addClass('isJustPressed');
$(this).toggleClass('isChecked');
$(this).html(function() {
return $('.fav_btn').hasClass('isChecked') ? 'Added' : 'Add to favourites';
});
});
$('.fav_btn').on('mouseleave', function(event) {
if ( $(this).hasClass('isChecked')){
$('.fav_btn').removeClass('isJustPressed');
}
});
$('.fav_btn').hover(
function() {
if ($('.fav_btn').hasClass('isChecked') && !$('.fav_btn').hasClass('isJustPressed')){
$('.fav_btn').html('Remove from favourites');
}},
function(){
if ($('.fav_btn').hasClass('isChecked') && !$('.fav_btn').hasClass('isJustPressed')){
$('.fav_btn').html('Added');
}});
.fav_btn {
position: relative;
box-sizing: border-box;
width: 100px;
height: 100px;
border: 1px solid black;
background-color: lightblue;
}
.fav_btn:hover{
background-color: blue;
color: #fff;
}
.fav_btn.fav_btn.isChecked.isJustPressed:hover{
background-color: blue;
color: #fff;
}
.fav_btn.isChecked {
background-color: #fff;
}
.fav_btn.isChecked:hover{
background: pink;
color: black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="fav_btn">Add to fav</div>
</body>

I'm not sure if this is what you are looking for but, I rewrote your solution with more method chaining, and abstraction:
HTML:
<div class="fav_btn">Add To Favs</div>
JS:
//Moved btn text into variable so it can be changed more easily
var btn_text = {
default: "Add To Favs",
added: "Selection Added",
remove: "Remove Selection"
}
$('.fav_btn')
//set initial text and classes
.removeClass('remove added')
.html(btn_text.default)
//The click toggles the 'default' and 'added' states
.on('click', function(e) {
//Toogle the 'added' class
$(this).toggleClass('added');
//Swap the text
if ($(this).is('.added')) {
$(this).html(btn_text.added);
} else {
$(this)
.removeClass('remove added')
.html(btn_text.default)
}
})
.on('mouseover', function(){
//If it has the 'added' class...add the 'remove' text
if ($(this).is('.added')) {
$(this)
.addClass('remove')
.html(btn_text.remove)
.on('mouseout', function() {
//Get rid of the 'remove' class
$(this).removeClass('remove');
//Swap out the 'remove' text
if ($(this).is('.added')) {
$(this).html(btn_text.added);
} else {
$(this).html(btn_text.default);
}
});
}
});
CSS:
.fav_btn {
padding: 5px;
background-color:blue;
color: white;
}
.fav_btn:hover {
background-color: lightblue;
}
.fav_btn.remove:hover {
background-color: pink;
}

Related

How do I run queryCommandState for a certain div (and not the whole page)?

How do I detect if an item is bold, ONLY within my contenteditable div, and not when the user clicks anywhere else on the entire page?
Here's my JSFiddle with the code.
I'm trying to run document.queryCommandState("bold") but only for my contenteditable="true" div.
I've googled for a while and can't find anything. I've tried replacing/adding my div selector $(".text-editor") to the word document in a few different ways, which doesn't work. I feel like I'm missing something obvious. Thanks!
HTML:
<div contenteditable="true" class="text-editor">Content <b>editable</b>. Type here...</div>
<div class="normal-div">Content <b>not</b> editable.</div>
Click on the bold (and not bold) text in the two boxes. Result:
<div class="is-bold">The text your cursor's on is BOLD.</div>
<div class="is-not-bold">The text your cursor's on is NOT BOLD.</div>
<br>^^ I want this green result to only change when you're clicking inside the editable box.
CSS:
.text-editor {
border: 2px solid red;
margin-bottom: 10px;
}
.normal-div {
border: 2px solid blue;
margin-bottom: 10px;
}
.is-bold {
display: none;
color: green;
}
.is-not-bold {
display: none;
color: green;
}
.active {
display: block;
}
jQuery:
setInterval(function () {
var isItBold = document.queryCommandState("bold");
if (isItBold == true) {
$(".is-bold").addClass("active");
$(".is-not-bold").removeClass("active");
}
else {
$(".is-bold").removeClass("active");
$(".is-not-bold").addClass("active");
}
}, 100)
You can check if contenteditable is being focused first, before doing any of that.
var editable = $("[contenteditable]")
setInterval(function () {
if (!editable.is(":focus")) return
var isItBold = document.queryCommandState("bold");
if (isItBold == true) {
$(".is-bold").addClass("active");
$(".is-not-bold").removeClass("active");
}
else {
$(".is-bold").removeClass("active");
$(".is-not-bold").addClass("active");
}
}, 100)
Also setInterval is not necessary here. You can bind on click event for example.

onmouseover not working in option [duplicate]

I am trying to show a description when hovering over an option in a select list, however, I am having trouble getting the code to recognize when hovering.
Relevant code:
Select chunk of form:
<select name="optionList" id="optionList" onclick="rankFeatures(false)" size="5"></select>
<select name="ranks" id="ranks" size="5"></select>
Manipulating selects (arrays defined earlier):
function rankFeatures(create) {
var $optionList = $("#optionList");
var $ranks = $("#ranks");
if(create == true) {
for(i=0; i<5; i++){
$optionList.append(features[i]);
};
}
else {
var index = $optionList.val();
$('#optionList option:selected').remove();
$ranks.append(features[index]);
};
}
This all works. It all falls apart when I try to deal with hovering over options:
$(document).ready(
function (event) {
$('select').hover(function(e) {
var $target = $(e.target);
if($target.is('option')) {
alert('yeah!');
};
})
})
I found that code while searching through Stack Exchange, yet I am having no luck getting it to work. The alert occurs when I click on an option. If I don't move the mouse and close the alert by hitting enter, it goes away. If I close out with the mouse a second alert window pops up. Just moving the mouse around the select occasionally results in an alert box popping up.
I have tried targeting the options directly, but have had little success with that. How do I get the alert to pop up if I hover over an option?
You can use the mouseenter event.
And you do not have to use all this code to check if the element is an option.
Just use the .on() syntax to delegate to the select element.
$(document).ready(function(event) {
$('select').on('mouseenter','option',function(e) {
alert('yeah');
// this refers to the option so you can do this.value if you need..
});
});
Demo at http://jsfiddle.net/AjfE8/
try with mouseover. Its working for me. Hover also working only when the focus comes out from the optionlist(like mouseout).
function (event) {
$('select').mouseover(function(e) {
var $target = $(e.target);
if($target.is('option')) {
alert('yeah!');
};
})
})
You don't need to rap in in a function, I could never get it to work this way. When taking it out works perfect. Also used mouseover because hover is ran when leaving the target.
$('option').mouseover(function(e) {
var $target = $(e.target);
if($target.is('option')) {
console.log('yeah!');
};
})​
Fiddle to see it working. Changed it to console so you don't get spammed with alerts. http://jsfiddle.net/HMDqb/
That you want is to detect hover event on option element, not on select:
$(document).ready(
function (event) {
$('#optionList option').hover(function(e) {
console.log(e.target);
});
})​
I have the same issue, but none of the solutions are working.
$("select").on('mouseenter','option',function(e) {
$("#show-me").show();
});
$("select").on('mouseleave','option',function(e) {
$("#show-me").hide();
});
$("option").mouseover(function(e) {
var $target = $(e.target);
if($target.is('option')) {
alert('yeah!');
};
});
Here my jsfiddle https://jsfiddle.net/ajg99wsm/
I would recommend to go for a customized variant if you like to ease
capture hover events
change hover color
same behavior for "drop down" and "all items" view
plus you can have
resizeable list
individual switching between single selection and multiple selection mode
more individual css-ing
multiple lines for option items
Just have a look to the sample attached.
$(document).ready(function() {
$('.custopt').addClass('liunsel');
$(".custopt, .custcont").on("mouseover", function(e) {
if ($(this).attr("id") == "crnk") {
$("#ranks").css("display", "block")
} else {
$(this).addClass("lihover");
}
})
$(".custopt, .custcont").on("mouseout", function(e) {
if ($(this).attr("id") == "crnk") {
$("#ranks").css("display", "none")
} else {
$(this).removeClass("lihover");
}
})
$(".custopt").on("click", function(e) {
$(".custopt").removeClass("lihover");
if ($("#btsm").val() == "ssm") {
//single select mode
$(".custopt").removeClass("lisel");
$(".custopt").addClass("liunsel");
$(this).removeClass("liunsel");
$(this).addClass("lisel");
} else if ($("#btsm").val() == "msm") {
//multiple select mode
if ($(this).is(".lisel")) {
$(this).addClass("liunsel");
$(this).removeClass("lisel");
} else {
$(this).addClass("lisel");
$(this).removeClass("liunsel");
}
}
updCustHead();
});
$(".custbtn").on("click", function() {
if ($(this).val() == "ssm") {
$(this).val("msm");
$(this).text("switch to single-select mode")
} else {
$(this).val("ssm");
$(this).text("switch to multi-select mode")
$(".custopt").removeClass("lisel");
$(".custopt").addClass("liunsel");
}
updCustHead();
});
function updCustHead() {
if ($("#btsm").val() == "ssm") {
if ($(".lisel").length <= 0) {
$("#hrnk").text("current selected option");
} else {
$("#hrnk").text($(".lisel").text());
}
} else {
var numopt = +$(".lisel").length,
allopt = $(".custopt").length;
$("#hrnk").text(numopt + " of " + allopt + " selected option" + (allopt > 1 || numopt === 0 ? 's' : ''));
}
}
});
body {
text-align: center;
}
.lisel {
background-color: yellow;
}
.liunsel {
background-color: lightgray;
}
.lihover {
background-color: coral;
}
.custopt {
margin: .2em 0 .2em 0;
padding: .1em .3em .1em .3em;
text-align: left;
font-size: .7em;
border-radius: .4em;
}
.custlist,
.custhead {
width: 100%;
text-align: left;
padding: .1em;
border: LightSeaGreen solid .2em;
border-radius: .4em;
height: 4em;
overflow-y: auto;
resize: vertical;
user-select: none;
}
.custlist {
display: none;
cursor: pointer;
}
.custhead {
resize: none;
height: 2.2em;
font-size: .7em;
padding: .1em .4em .1em .4em;
margin-bottom: -.2em;
width: 95%;
}
.custcont {
width: 7em;
padding: .5em 1em .6em .5em;
/* border: blue solid .2em; */
margin: 1em auto 1em auto;
}
.custbtn {
font-size: .7em;
width: 105%;
}
h3 {
margin: 1em 0 .5em .3em;
font-weight: bold;
font-size: 1em;
}
ul {
margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>
customized selectable, hoverable resizeable dropdown with multi-line, single-selection and multiple-selection support
</h3>
<div id="crnk" class="custcont">
<div>
<button id="btsm" class="custbtn" value="ssm">switch to multi-select mode</button>
</div>
<div id="hrnk" class="custhead">
current selected option
</div>
<ul id="ranks" class="custlist">
<li class="custopt">option one</li>
<li class="custopt">option two</li>
<li class="custopt">another third long option</li>
<li class="custopt">another fourth long option</li>
</ul>
</div>

Changing div text and CSS when clicking on a div, and reversing the change when you click again

I have a div named #increase-text-weight which says "INCREASE TEXT WEIGHT".
Whenever you click on it, the contents of another div named #post-content should get font-weight: 500 and the text of #increase-text-weight should be changed to "DECREASE TEXT WEIGHT".
When the div says "DECREASE TEXT WEIGHT" and you click on it,
#post-content
should get
font-weight: 300
and the text of
#increase-text-weight
should be changed to "INCREASE TEXT WEIGHT".
How can I do this?
EDIT:
I had tried doing it by getElementById but it didn't work.
Since you are learning, this is a short way to do this with two clases.
First of all, the id selector $('#test') gets the node element
Then attach a click event listener of to the reference.
After, the selector $(this), makes a reference to selector used in the event attached function, in this case we can say $(this) == $("#test").
After the dot, jQuery .toggleClass() method adds or remove a class from the element, also, if you pass a second true or false parameter, the method will add or remove the given class respectively.
So if you chain this two toggleClass() will add the class if it is not there or will remove it if it exist
$("#test").click(function(){ // also can be .on('click',function(){ ... })
$(this).toggleClass("decreased")
.toggleClass("increased");
});
.decreased {
font-weight: 100;
color: red;
cursor: pointer;
}
.increased {
font-weight: 300;
color: green;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test" class="decreased">Increase my font weight!</div>
A quick way to do this could be to use and if and else statement.
$('#increase-text-weight').on('click', function() {
if ($(this).text() === 'INCREASE TEXT WEIGHT') {
$('#post-content').addClass('highlight');
$(this).text('DECREASE TEXT WEIGHT');
} else {
$(this).text('INCREASE TEXT WEIGHT');
$('#post-content').removeClass('highlight');
}
});
$('#increase-text-weight').on('click', function() {
if ($(this).text() === 'INCREASE TEXT WEIGHT') {
$('#post-content').addClass('highlight');
$(this).text('DECREASE TEXT WEIGHT');
} else {
$(this).text('INCREASE TEXT WEIGHT');
$('#post-content').removeClass('highlight');
}
});
div {
width: 100%;
height: 100px;
text-align: center;
border: 1px solid;
margin: 0 0 25px 0;
cursor: pointer;
}
.highlight {
font-weight: 900;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='increase-text-weight'>INCREASE TEXT WEIGHT</div>
<div id='post-content'>Text text and text</div>
You can simply do this using an onClick event on the div you want to be changed. Each time it is clicked we check which class is associated with that <div>, and then do the required modifications to that <div> based on the class, like updating the text content inside the div with .text(), and then switching out the classes like so:
var myDiv = $("#test");
myDiv.click(function() {
if (myDiv.hasClass("decreased")) {
myDiv.removeClass("decreased")
.addClass("increased")
.text("Decrease my font weight!")
} else {
myDiv.removeClass("increased")
.addClass("decreased")
.text("Increase my font weight!")
}
});
.decreased {
font-weight: 100;
color: red;
cursor: pointer;
}
.increased {
font-weight: 300;
color: green;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test" class="decreased">Increase my font weight!</div>
Although you can easily do this with pure JavaScript like so:
var myDiv = document.getElementById("test");
myDiv.addEventListener("click", function() {
if (myDiv.className === "decreased") {
myDiv.classList.remove("decreased");
myDiv.className = "increased";
myDiv.textContent = "Decrease my font weight!";
} else {
myDiv.classList.remove("increased");
myDiv.className = "decreased";
myDiv.textContent = "Increase my font weight!";
}
});

Changing the background color of a select2 selection within the select field

I am using Select2 to setup multi-select tag type fields in my application. I know which CSS attribute changes the colors of the selection box once it is placed in the select field:
selection box color
.select2-container--default .select2-selection--multiple .select2-selection__choice {
background-color: #e4e4e4;
border: 1px solid #aaa;
border-radius: 4px;
cursor: default;
float: left;
margin-right: 5px;
margin-top: 5px;
padding: 0 5px
}
What I am trying to figure out is how to have this change based on the selection a user makes. The selection list is pre-defined.
Tried something like this:
JavaScript to initialize / change box color
$(document).ready(function () {
$('#test').select2();
$('.select2-container--default .select2-selection--multiple .select2-selection__choice').each(function () {
var title = $(this).attr('title');
console.log(title);
if (title === 'Breakfast') {
$(this).parent().css({ 'background-color': "green" });
}
if (title === 'Brunch') {
$(this).parent().css({ 'background-color': "red" });
}
if (title === 'Lunch') {
$(this).parent().css({ 'background-color': "blue" });
}
});
});
This does not appear to work. Has anyone tried styling the tag boxes for Select2?
Change $(this).parent().css('background-color', 'green');
by $(this).parent().css({ 'background-color': "green" });
And the same with the rest.

Change button's content and color when clicked.

There is a model at http://www.lesha.wemakesites.ru/.
Once focused at plus icon it is replaced by a button "Follow me".
What I wanna do is to change this button to a red one saying "Unfollow" once it is clicked. It is super if someone knows how to build it reversed too so that when an "Unfollow" button is clicked, it becomes "Follow" one.
Pull in jquery in your project. This cannot be achieved with css alone.
$('#btn').on('click', function() {
if (!$(this).hasClass("followed")) {
$(this).addClass("followed btn-red");
$(this).removeClass("btn-blue");
$(this).html("Followed");
} else {
$(this).addClass("btn-blue");
$(this).removeClass("followed btn-red");
$(this).html("Follow");
}
});
#btn {
border: none;
outline: none;
padding: 10px 12px;
color: #fff;
}
.btn-blue {
background-color: blue;
}
.btn-red {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn" class="btn-blue">Follow</button>
Make the JS as simple as possible to understand.
I would suggest having two versions of the button and you can use
display: none;
for the one that is currently not in use.
If users are switching back between following you can store your state in a variable.
let following = true;
let btn = document.getElementById("btn");
if (!!following) {
btn.style.dispaly = "none";
following = false;
} else {
btn.style.display = "block";
following = false;
}

Categories

Resources