Im trying to figure out a simple way to enable me to select 2 DIV elements using JQuery - here is my attempt : http://jsfiddle.net/MarKP/5/
I need to limit the selections to just 2 and will use the class I add to get the selected objects.
Can anyone point me in a better direction
<div id="1">one</div>
<div id="2">two</div>
<div id="3">three</div>
<div id="4">four</div>
var selected = 0;
var prevSelect;
$('div').click(function() {
if (selected == 2) {
selected = 1;
console.log(prevSelect);
$('#' + prevSelect).removeClass('fill');
}
$(this).addClass('fill');
prevSelect = $(this).attr('id');
selected = selected +1;
});
div {
border: 1px solid blue;
height: 25px;
margin-bottom: 5px;
}
.fill {
background-color: red;
}
I updated your functionality to disallow any selection change if 2 divs are already selected unless you click a selected div to unselect it:
http://jsfiddle.net/MarKP/32/
$('div').click(function(e){
var $et = $(e.target);
if ($et.hasClass('fill')) {
$et.removeClass('fill');
} else {
if ($('.fill').length < 2) {
$et.addClass('fill');
}
}
});
Old solution: http://jsfiddle.net/MarKP/11/
What you want is something like this:
$('.divclass').click(function(){
var cnt=$('.divclass .selected').length;
if(cnt>2) return;
$(this).addClass('selected');
});
This will add the class selected to at most 2 divclass objects. To get the selected objects, you just call $('.divclass .selected').
If you always want to remove the oldest one clicked (unless it is already selected), I'd maintain my own array like this:
Example: http://jsfiddle.net/MarKP/17/
var selected = [];
$('div').click(function() {
if( $.inArray( this, selected ) > -1 ) return;
if( selected.length === 2 ) {
$(selected.shift()).removeClass('fill');
}
selected.push($(this).addClass('fill')[0]);
});
Only add a selected class if there are fewer than two divs returned from a selector for div.selected. Otherwise, remove the selected class. For instance:
$('div').click(function() {
if (!$(this).hasClass("selected") && $("div.selected").length < 2) {
$(this).addClass("selected");
} else {
$(this).removeClass("selected");
}
});
Related
I am trying to create somewhat of a tabSelect function in a card game where the player will be able to select 1 of the 5 cards in their hand. I made a highlight class and am adding it to a div containing the card image so the outline changes from blue to light blue. So in the loop the class should be added to the first div, then the second div while removing it from the first div, then the third div while removing it from the second div....etc.
this is what i have tried so far but its not working as intended :
selectCard() {
const $playerOneHand = $('.pOne')
for (i = 0; i < $playerOneHand.length; i++) {
if ($($playerOneHand[i - 1]).hasClass('highlight') == true) {
$($playerOneHand[i - 1]).removeClass('highlight')
}
if ($($playerOneHand[i]).hasClass('highlight') == false) {
$($playerOneHand[i]).addClass('highlight')
return
}
}
}
Get the index of the card that's currently highlighted. Increment that index to get the one to highlight in its place.
function selectCard() {
var index = $(".pOne.highlight").index(".pOne");
index = (index + 1) % $(".pOne").length; // increment and wrap around
$(".pOne").removeClass("highlight");
$(".pOne").eq(index).addClass("highlight");
}
$("#next").click(selectCard);
.pOne {
height: 30px;
width: 30px;
background-color: yellow;
}
.pOne.highlight {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="pOne highlight">1</div>
<div class="pOne">2</div>
<div class="pOne">3</div>
<div class="pOne">4</div>
<div class="pOne">5</div>
<button id="next">Next Card</button>
Salutations,
I am learning to code through some online resources and my brother who works in the field in an effort to get into a development career. Right now I am working on a silly web app where you are matching photos. Below each photo is a button with a unique ID. Currently, when you select a button, it will turn blue.
I am trying to create a function that will look for 2 specific buttons being clicked.
If I were to speak what I want it to do in a conversation with you, I would say "if button1 is select when button4 is selected, do this thing"
What function am I looking for?
Can anyone help this n00b out?
Below I have the function as is for when a button is clicked. The class changes in order to adjust the color.
I can post whatever code is necessary, otherwise this is all I could think to post. {BC1b is a button that should be paired with F1b}
function sbtnb1() {
document.getElementById("BC1b").className = "selected";
}
Here is an example.
https://jsfiddle.net/273rhzyw/
With Jquery
https://jsfiddle.net/agoLcuv8/8/
// All buttons with class of button
const buttons = document.querySelectorAll(".button");
// declare array to keep the match checks
let matchCheckerArray = [];
// Loop through each button and attach an onClick
buttons.forEach(function(button) {
button.onclick = function() {
clickHandler(button);
}
});
const clickHandler = function(button) {
matchCheckerArray.push(button.dataset.matchId)
console.log(matchCheckerArray);
if (matchCheckerArray.length == 2) {
if (isMatch()) {
alert('Match');
}
matchCheckerArray = [];
return;
}
}
const isMatch = function() {
if (matchCheckerArray[0] === matchCheckerArray[1]) {
return true;
}
return false;
}
I would keep two global variables (or an array/set of variables) that store what's been clicked. You can manipulate these however you'd like (e.g. clear out the selection if the user selected two photos that aren't a match; don't let the user select a second card if it doesn't match; etc...).
This can work in conjunction with what you already have. The class name will allow you to add specific selected styling, while the global variables allow you to keep track of what has been selected. The global variables will also allow you to check for match or no match.
There are many ways to do this but this is how I would go about it.
$(".checkButton").on("click", function(){
// toggle button state
if($(this).attr("data-state") == "on") {
$(this).attr("data-state", "off"); // toggle button off
$(this).removeClass("highlight"); // remove highlight
$(".myImage").removeClass("highlight"); // remove highlight
} else {
$(this).attr("data-state", "on"); // make button active
$(this).addClass("highlight"); // add highlight
}
//----------------------------------------------------------
// Here you would have to build your checks and how you want
// the comparison of buttons and images to be linked.
//----------------------------------------------------------
// For example:
// check if more than 2 buttons are active and if buttons match the if statement.
var buttonCount = 0;
$("#buttonContainer button").each(function(){
if($(this).attr("data-state") == "on"){
buttonCount += 1;
}
});
// if 2 buttons are clicked then check then allow to do something
if(buttonCount == 2){
// highlight image 1 if buttons 1 and 2 are on.
if($(".checkButton[data-id=b1]").attr("data-state") == "on" &&
$(".checkButton[data-id=b2]").attr("data-state") == "on"){
$("#image1").addClass("highlight");
}
// highlight image 2 if buttons 3 and 4 are on.
if($(".checkButton[data-id=b3]").attr("data-state") == "on" &&
$(".checkButton[data-id=b4]").attr("data-state") == "on"){
$("#image2").addClass("highlight");
}
}
//----------------------------------------------------------
});
.myImage {
width: 100px;
height: 100px;
margin: 5px;
background: black;
float: left;
}
.highlight {
outline: 2px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="width: 100%; height: 110px;">
<div class="myImage" id="image1"></div>
<div class="myImage" id="image2"></div>
</div>
<div id="buttonContainer" style="width: 100%;">
<button class='checkButton' data-id="b1" data-state='off'>button 1</button>
<button class='checkButton' data-id="b2" data-state='off'>button 2</button>
<button class='checkButton' data-id="b3" data-state='off'>button 3</button>
<button class='checkButton' data-id="b4" data-state='off'>button 4</button>
</div>
I am not quite sure if that's the correct way to phrase it, but here is my problem
As you can see, pretty simple code:
<div class="first"></div>
<div></div>
What I want to achieve is:
You click on the div with the first class, it will swap that class with the sibling element
You click the sibling element, and it swaps it back, so you just swap classes around 2 elements
The problem here is it works correctly only the first time, and the second time when the new element receives the class via addClass, jQuery doesn't recognize that it contains the class by the first page load? How can I resolve this?
P.S: I made a console.log(111); just to make sure, and sure enough it triggers ONLY when I click on the black div after the first swap (the one that SHOULD NOT have the first class anymore)
To achieve this behavior, you can use delegated events http://api.jquery.com/delegate/ on elements wrapper;
$(document).delegate('.first', 'click', function(e){
e.preventDefault();
console.log(123);
$(this).removeClass('first');
$(this).siblings().addClass('first');
})
A quick and simple way to do it is this:
$(document).ready(function() {
var first = $('.first');
var second = first.next();
first.click(function(e) {
e.preventDefault();
first.removeClass('first');
second.addClass('first');
});
second.click(function(e) {
e.preventDefault();
second.removeClass('first');
first.addClass('first');
});
});
div {
background-color: black;
height: 100px;
width: 100px;
margin-bottom: 10px;
}
.first {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="first"></div>
<div></div>
This way does not scale well.
Your problem was you only change when you click the $(first) which does not change when clicked it's still point to the first div.
A better way with vanilla javascript:
document.addEventListener('click', function(e) {
if (e.target.classList.contains('first')) {
e.target.classList.remove('first')
var sibling = getNextSibling(e.target) || getPreviousSibling(e.target)
if (sibling) {
sibling.classList.add('first')
}
}
})
function getNextSibling(elem) {
var sibling = elem.nextSibling
while(sibling && sibling.nodeType != 1) {
sibling = sibling.nextSibling
}
return sibling
}
function getPreviousSibling(elem) {
var sibling = elem.previousSibling
while(sibling && sibling.nodeType != 1) {
sibling = sibling.previousSibling
}
return sibling
}
All you need to do is push both items into an array, then flip between indexes on click.
var elems = [];
$(document).on("click", ".first", function(event) {
elems = elems.length == 0 ? [event.originalEvent.target, $(event.originalEvent.target).next()] : elems;
$(elems[event.originalEvent.target === elems[0] ? 1 : 0]).addClass("first");
$(elems[event.originalEvent.target === elems[0] ? 0 : 1]).removeClass("first");
});
.first {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="first">x</div>
<div>y</div>
I have below HTML
<div class="parent">
<span class="child">1</span>
<span class="child">2</span>
<span class="child">3</span>
<span class="child">4</span>
<span class="child">5</span>
</div>
and below CSS
.parent .child {
border : 1px solid black;
display :inline-block;
width:40px;
height:25px;
text-align:center;
cursor:pointer;
}
.mark {
background-color: green;
}
and simple click event for to see selected element a below.
$(".parent > .child").click(function(e){
if(e.shiftKey) {
$(".parent .child").each(function(){
$(this).addClass("mark");
});
}
else {
$(this).addClass("mark");
}
});
Edited : When I click one element and another element with shiftKey , between these two elements should be add class mark. But my code iterate all elements as $(".parent > .child").... I would like to avoid it (I mean if 2 elements between them , I would like to iterate 4 times (inclusive start and element) with my iteration).
My question is can I iterate between two selected elements (inclusive) instead of iterating from thier parent element (in my case I don't want to iterate from parent) ? I know the start and end elements. If so, why I need to iterate all elements and check their status as I want ? JSFiddle link.
For clear question ...
I have 10 HTML element ,assume 3 is start and 6 is end.I would like to iterate as
(for var i=3 ; i <=6 ; i++) {...}
instead of iterating all elements and check their status as
(for var i=1 ; i <=10 ; i++) {
// checking is it between start and end elements
}
Demo
Try this demo. Not sure if it accomplishes what you need. Comment if changes needed.
$(".parent .child").click(function () {
if($(".parent .child.mark:first").length == 1 && !$(this).hasClass('mark')){
firstIndex = $(".parent .child.mark:first").index();
thisIndex = $(this).index();
start = Math.min(thisIndex, firstIndex);
end = Math.max(firstIndex, thisIndex) + 1;
$('.parent .child').slice(start, end).each(function(){
$(this).addClass('mark');
})
} else {
$(this).addClass('mark');
}
});
Not clear from your question but are you saying something like this
Jquery for next element is :
$(".parent .child").click(function(){
$(this).addClass("mark");
$(this).next().addClass('mark');
if($(this).is(':last-child')){
$('.parent .child:first-child').addClass('mark');
}
});
If element is last child then have added class mark to first ,this one was my assumption so far.
Why don't you use this:
$( ".mark" ).nextUntil( ".mark" ).css( "color", "red" );
$( ".mark" )--> this is your first click item
.nextUntil( ".mark" )--> this one is your second click
Hope it will works
I have the following javascript/jquery code, the purpose of which is to -
Deselect a previously selected item from the list, if the selected item value exists in an array
Hide/display each list item dependent on whether they exist in the array
var list = $(row).find("select > option")
var selectedValue = $(row).find("select > option:selected")
if (selectedValue) {
if ($.inArray(selectedValue[0].value, dependencyListItemValues) == -1) {
alert('deselect');
$(selectedValue).attr("selected", false);
}
}
$(list).each(function () {
var value = this.value;
if (value != "") {
if ($.inArray(value, dependencyListItemValues) > -1) {
alert('show');
$(this).show();
}
else {
alert('hide');
$(this).hide();
}
}
});
This is working fine in chrome and firefox, but not in IE9. When running in IE, the alert lines are hit, but the following lines seemingly do nothing:
$(selectedValue).attr("selected", false);
$(this).show();
$(this).hide();
Do I need to use alternative code so this will work in IE?
First: You can use
list.each
instead of $(list).each.
Second, you cannot hide an OPTION element in crossbrowser way.
So, you must remove it (for hide) and re-create it (for show).
You can store all options (and them parent) in array, like so:
var cache_options= [];
list.each(function(index) {
cache_options.push({el:$(this), parent:$(this).parent()});
});
and after
for(var i = 0; i<cache_options.length; i++) {
var value = cache_options[i].el[0].value;
if (value != "") {
if ($.inArray(value, dependencyListItemValues) > -1) {
cache_options[i].parent.append(cache_options[i].el);
}
else {
cache_options[i].el.remove();
}
}
}
Tested!
OK my solution was as follows ... this is based on the answer by meder (thanks!) on this question - Hide select option in IE using jQuery
Firstly, in place of this line:
$(selectedValue).attr("selected", false);
I did this:
$(row).find("select")[0].selectedIndex = -1;
And to show/hide the relevant list items, I had to first wrap those that I needed to hide in a span and then apply the .hide() command, and for those I needed to display, replace the span with the original option element:
//first we need to hide the visible list values that are not in the list of dependent list values.
//get the list values which are currently displayed, these will be the 'option' elements of the 'select' element (list).
//the hidden values are within a span so will not be picked up by this selector
var displayedListValues = $(row).find("select > option")
//loop through the displayed list values
$(displayedListValues).each(function () {
//get the value from this 'option' element
var displayedValue = this.value;
//ignore empty values (first blank line in list)
if (displayedValue != "") {
//if the value is not in the list of dependent list values, wrap in span and apply .hide() command
if ($.inArray(displayedValue, dependencyListItemValues) == -1) {
$(this).wrap('<span>').hide();
}
}
});
//now we need to display the hidden list values that are in the list of dependent list values.
//get the list values which are currently hidden, these will be the 'span' elements of the 'select' element (list).
//the visible values are within an 'option' so will not be picked up by this selector
var hiddenListValues = $(row).find("select > span")
//loop through the hidden list values
$(hiddenListValues).each(function () {
//find the 'option' element from this 'span' element and get its value
var opt = $(this).find('option');
var hiddenValue = opt[0].value;
//ignore empty values (first blank line in list)
if (hiddenValue != "") {
//if the value is in the list of dependent list values, apply .show() command on the 'option' element
//(not sure why the .show() command works in this case?)
//and then replace the 'span' element with the 'option' element, which is effectively removing the span wrapper
if ($.inArray(hiddenValue, dependencyListItemValues) > -1) {
$(opt).show();
$(this).replaceWith(opt);
}
}
});
Which works fine ... although rather annoying I had to do this rather messy re-coding just because IE doesn't support .show() and .hide() of list values!!!!!
Here is a good solution:
http://ajax911.com/hide-option-elements-jquery/