Limit selectable divs in a parent div - javascript

I'd like to create a product feature selection page where the user needs to select 3 features out of 6. Now, I got to a point where I can limit the number of selectable elements so if 3 elements are selected, the user wont be able to select a 4th one.
I need to modify this so when the user is attempting to select the 4th element, the 1st element they selected becomes unselected and the 4th element becomes selected. I hope it makes sense.
$('div').click(function(e) {
var $et = $(e.target);
if ($et.hasClass('fill')) {
$et.removeClass('fill');
} else {
if ($('.fill').length < 2) {
$et.addClass('fill');
}
}
});
div {
border: 1px solid blue;
height: 25px;
margin-bottom: 5px;
}
.fill {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<div id="1">one</div>
<div id="2">two</div>
<div id="3">three</div>
<div id="4">four</div>
This fiddle shows where I'm at with my code: http://jsfiddle.net/MarKP/32/
This fiddle is not mine, but this is exactly what I have right now in my project.
I'm trying to get this done using jQuery or plain JavaScript.
Thank you in advance!

To achieve this you can maintain an array which holds the order in which the elements were clicked. Then, when the limit is hit, you can remove the class from the element which was selected first. Try this:
var selections = [];
var $div = $('div').click(function(e) {
selections.push(this.id);
if (selections.length > 3)
selections.shift(); // remove first item
setState();
});
function setState() {
$div.removeClass('fill');
$div.filter(`#${selections.join(',#')}`).addClass('fill');
}
div {
border: 1px solid blue;
height: 25px;
margin-bottom: 5px;
}
.fill {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="1">one</div>
<div id="2">two</div>
<div id="3">three</div>
<div id="4">four</div>
<div id="5">five</div>
<div id="6">six</div>
Finally, note that jQuery 1.4.4 is massively outdated; nearly 10 years in fact. You need to update it.

Related

How to display none if div tag doesn't exist?

If the "slick-initialized" div tag doesn't exist within a parent, then I want the parent ID (product recommender-recipe) to display none. Right now this is what I have set up:
HTML is set up like this:
<div id="product-recommender-recipe">
<div class="slick-initialized">
</div>
</div>
My JS so far. If length is 0, then have the parent ID display none. :
var productTemplate = document.getElementsByClassName("#product-recommender-recipe > .slick-initialized")
if (productTemplate.length === 0){
document.getElementById("product-recommender-recipe").style.display = "none";
}
Do I have this set up properly?
You can hide #product-recommender-recipe and check if .slick-initialized exists than show using just CSS.
it is working perfectly.
#product-recommender-recipe {
padding: 50px;
background-color: red;
display: none;
}
#product-recommender-recipe:has(.slick-initialized) {
display: block;
}
<!-- hidden if slick-initialized not exist -->
<div id="product-recommender-recipe">
<!-- <div class="slick-initialized"></div> -->
</div>
<br/>
<!-- visible if slick-initialized exist -->
<div id="product-recommender-recipe">
<div class="slick-initialized"></div>
</div>
You are pretty close. You have two mistakes in your implementation.
The first one is that you used getElementByClassName when in fact you are using an ID as your selector. Thus you should have used querySelector.
The second one is that you overused your selector. You have selected your parent div and placed it in a var so that you can reference it again.
Here is my implementation:
var productTemplate = document.querySelector("#product-recommender-recipe")
if (!productTemplate.querySelector('.slick-initialized')) {
productTemplate.style.display = none;
}
#product-recommender-recipe {
background: red;
width: 50px;
height: 50px;
}
<div id="product-recommender-recipe">
<div class="slick-initialized"></div>
</div>
getElementsByClassName expects a single class name – not a selector. If you want to use a selector, use querySelector or querySelectorAll. querySelector returns null if the element doesn't exists in the DOM.
const element = document.querySelector(".slick-initialized");
if(element === null) {
document.querySelector("#product-recommender-recipe").style.display = "none";
}

Reset Border style

I have a image that is currently being styled with Jquery once it's clicked. I eventually hide it in Javascript. I want to reshow it, but I want it to have the border removed.
Here is HTML:
<div id="playOptionsWager" style="display: none">
<h4>Choose your move to beat the computer!</h4>
<img id="clickedRockWager" src="img/rock.jpg" onclick="playWagerRock()" />
<img id="clickedPaperWager" src="img/paper.jpg" onclick="playWagerPaper()"/>
<img id="clickedScissorsWager" src="img/scissors.jpg" onclick="playWagerScissors()" />
</div>
Jquery:
$(function () {
$("img").on("click",function() {
$(this).siblings().css('border','0px')
$(this).css('border', "solid 2px red");
});
});
Here is what I was trying in Javascript:
function autobet() {
coinBalance -= currentBet*2;
alert(getBalance());
document.getElementsByTagName("IMG").style.border="";
}
However when it reshows the div it has the border on it still.
Thanks for the help!
Your issue is that document.getElementsByTagName("IMG") returns a collection of elements, so simply applying .style.border on this collection won't work. Instead, you need to loop over this collection, and set every image within it to have no border using .style.border = 0;:
See working example (with div) below:
function removeBorder() {
[...document.getElementsByTagName("div")].forEach(elem => {
elem.style.border = 0;
});
}
.box {
height: 100px;
width: 100px;
background: black;
display: inline-block;
}
.active {
border: 3px solid red;
}
<div class="box"></div>
<div class="box active"></div>
<div class="box"></div>
<br />
<button onclick="removeBorder()">Remove border</button>
Also note that [...document.getElementsByTagName("IMG")] is a way of converting the collection of elements into an array of elements, which thus allows us to use the .forEach method to loop over it.
You started with jQuery, let's continue with jQuery.
function autobet() {
coinBalance -= currentBet*2;
alert(getBalance());
$("img").css("border","");
}
The problem is that getElementsByTagName() returns a collection not one element.
First you need to iterate over the collection of html elements you have - when using getElementsByTagName you get back an array of elements.
Second you need to give the elements a style of zero.
const divElements = document.getElementsByTagName("IMG");
for (let i=0; i < divElements.length; i++) {
divElements[i].style.border = 0;
}
You can see the code on stackbliz -
https://stackblitz.com/edit/border-issue?file=index.js

Adding and removing classes on mouse enter and leave on canvas shape

I'm trying to add a class to a element when mouse hovers over it and then remove it when mouse leaves. It works currently only with giving it direct style in js.
As shown below I tried various ways to do this, all had some problems. Only the direct style change worked. On mouse leave I do the same but remove the class. The mouse over and leave checks canvas element.
poly.on('mouseover', function () {
this.opacity(1);
layer.draw();
$('.' + this.name()).css({ backgroundColor: "#ffcc00" });
//$('.' + this.name()).classList.add("textboxhighlight");
//$('.' + this.name()).className += " textboxhighlight";
//$('.' + this.name()).addClass("textboxhighlight");
//$('.' + this.name()).setAttribute("class", "textboxhighlight");
});
I'm not sure what the problem is as I tired various methods in adding class all of them with different problems. Using just this.addClass wont work as it needs to start with $('.' + this.name()) or nothing works in the code not even forcing the style part. $('.' + this.name()) refers to a class name in element with the same name as poly.
In css:
.textboxhighlight {
background-color: #ffcc00;
}
Thanks for any help.
May be you have to use in your css class background-color: #red !important. See working example here
It would be easier if you provided more code to work with. The example below will illustrate on how to add a class on hover and remove a class on leaving the element.
$('#element').hover(function(e) {
$(this).addClass('selected');
}, function(a) {
$(this).removeClass('selected');
});
.selected {
background-color: green;
}
<div id='element'>
element
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
Hard to say what is wrong with your code when you don't show the mouseenter/leave parts of your code. But here is an example with classes:
https://codepen.io/andeersg/pen/MOGqPQ
$('.el').mouseenter(function() {
$(this).addClass('el-hover');
});
$('.el').mouseleave(function() {
$(this).removeClass('el-hover');
});
You can use toggleClass on hover event
$(".hoverclass").hover(function () {
$(this).toggleClass("hoverclass_toggle");
});
.hoverclass {
height: 72px;
width: 100%;
border: 1px solid #000;
}
.hoverclass_toggle {
background-color: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="hoverclass">
<div class="item">
<div id="item1"> <i class="icon"></i>Test</div>
</div>
<div>
Otherwise you can do that type :
$(".hoverclass").hover(
function () {
$(this).addClass("result_hover");
},
function () {
$(this).removeClass("result_hover");
}
);
.hoverclass {
height: 72px;
width: 100%;
border: 1px solid #000;
}
.result_hover {
background-color: #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="hoverclass">
<div class="item">
<div id="item1">
<i class="icon"></i>Test
</div>
</div>
<div>

Swapping text equal in different divs and classes

I have several boxes of cards on one page, these boxes can come dynamically in different, not upper right corner has a text for the click to open the accordion type content, for each class I have to do an action as below, I think of something Regardless of the number of classes.
*new
I do not know how to explain it, I'll try a summary:
Change the text of only one div when clicking, because when I click on the item in the box it changes all the other texts of the
Other boxes.
$('.change-1').click(function () {
var $mudartxt = $('.mudartexto');
if ($mudartxt.text() == 'expandir')
$mudartxt.text('ocultar');
else {
$mudartxt.text('expandir');
}
});
You need to find the current clicked item.
For that you can use the event object
$('.change-1').click(function (e) {
// Get current target as jquery object
var $target = $(e.currentTarget);
// Find mudartexto in current target.
var $mudartxt = $target.find('.mudartexto');
if ($mudartxt.text() == 'expandir')
$mudartxt.text('ocultar');
else {
$mudartxt.text('expandir');
}
});
.change-1 {
display:inline-block;
width:200px;
height:50px;
text-align: center;
background-color:#dfdfdf;
clear: both;
float: left;
margin-top:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="change-1">
<div class="mudartexto">expandir</div>
</div>
<div class="change-1">
<div class="mudartexto">expandir</div>
</div>
<div class="change-1">
<div class="mudartexto">expandir</div>
</div>
<div class="change-1">
<div class="mudartexto">expandir</div>
</div>
If you are asking how to change text of an element, inside a clicked box, this should do it.
$('.change-1').click(function () {
var $mudartxt = $(this).find('.mudartexto');
if ($mudartxt.text() == 'expandir')
$mudartxt.text('ocultar');
else {
$mudartxt.text('expandir');
}
});

jQuery :has selector filter trouble

I have some containers with ids="container1", "container2", "container3"...
They can have one of two types of tags inside: tables or canvas.
I want to hide one of them depending on the device orientation.
I have tried with this
$('[id^=container]:has(canvas)').hide();
or
$('[id^=container]:has(table)').hide();
but both hide all the containers, don't filtering their inside tags.
You can do
var x = $('[id^=container]').find("table").length;
// Will be 0 if no table inside it
if(x==0) { .. }
else { .. }
You can use classes on your containers instead of ids. Here's a JSFiddle demo.
For better performance in modern browsers, use $( "your-pure-css-selector" ).has( selector/DOMElement ) instead.
Source: https://api.jquery.com/has-selector/
Basically I made a 3 containers. One with a table, one with a canvas and one with nothing.
<div class="container green">
<table></table>
</div>
<div class="container blue">
<canvas></canvas>
</div>
<div class="container red"></div>
And a quick CSS to have the divs visible.
div.container{
display: inline-block;
height: 50px;
margin: 10px;
width: 50px;
}
div.green{
background-color: green;
}
div.blue{
background-color: blue;
}
div.red{
background-color: red;
}
And to complete it, a jQuery that executes when the document is ready.
$(document).ready(function(){
$('div.container').has('canvas').hide();
});
If you know the element by which you want to grab the container is not nested within additional tags, you can use the parentNode property of an HTML element to climb up the DOM tree and hide the parent.
document.querySelector("[id^=container] > table").parentNode.style.display= "none";
Example that demos the concept:
document.getElementById("input").addEventListener("change", function() {
document.getElementById("container1").style.display = "block";
document.getElementById("container2").style.display = "block";
document.querySelector("[id^=container] > " + this.value).parentNode.style.display = "none";
});
#container1 {
border: 1px solid red;
}
#container2 {
border: 1px solid blue;
}
<select id="input">
<options>
<option value="table">Hide the table</option>
<option value="canvas">Hide the canvas</option>
</options>
</select>
<div id="container1">Table
<table></table>
</div>
<div id="container2">Canvas
<canvas></canvas>
</div>
I didn't realized I had a global container with id= "container*".
What a silly mistake. Sorry for stealing your time, and thank you everyone!

Categories