I'm trying to change a div's attribute class. I have three defined classes and want to cycle through the classes when a user initiates a click event. The first click event works as expected, but the second doesn't show any results.
I've went through a few iterations of trying to get this to work, but have not had any success. I think what's going on is that the DOM tree isn't being updated with the click event, so when the second click event is fired it sees the card-green class, adds the card-yellow class and then exits the branching logic.
$(document).ready(function() {
$('body').on('click', function(event) {
var cardColors = ['card-green', 'card-yellow', 'card-red'];
if ($(event.target.nodeName).attr('class') == 'card-green') {
$(event.target.nodeName).removeClass(event.target.nodeName.className).addClass(cardColors[1]);
} else if ($(this).attr('class') == 'card-yellow') {
$(event.target.nodeName).removeClass(event.target.nodeName.className).addClass(cardColors[2]);
} else {
$(event.target.nodeName).removeClass(event.target.nodeName.className).addClass(cardColors[0]);
}
})
});
Use a switch and toggleClass(). Details are commented in Snippet. No need for an array if you are using a limited number of options. When using $(this) you don't need to keep track of what you clicked (much like event.target except $(this) isn't concerned about events as it is concerned with owner of function.)
SNIPPET
$(document).ready(function() {
$(document).on('click', 'div', function(event) {
/* Determine $(this) class
|| Pass class through the switch
*/
var color = $(this).attr('class');
/* Each part of the switch is a if/else
|| conditional. If the condition isn't
|| met, then it will kick you
|| down to the next conditional and
|| so on, until you reach default or
|| meet a condition in which case the
|| break will kick you out of switch.
|| Each condition has a toggleClass()
|| method to switch colors according
|| to the present class of div
*/
switch (color) {
case 'green':
$(this).toggleClass('green yellow');
break;
case 'yellow':
$(this).toggleClass('yellow red');
break;
case 'red':
$(this).toggleClass('red green');
break;
default:
break;
}
});
});
div {
height: 30px;
width: 50px;
border: 1px solid black;
cursor: pointer;
}
.green {
background: green
}
.red {
background: red;
}
.yellow {
background: yellow
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
<div class='green'></div>
This changes the color in order of the cards array when elements within the document body are clicked:
(Very similar to #gyre's answer, only includes the event.target within the code logic, rather than just the body).
var cards = ['card-green', 'card-yellow', 'card-red'];
$('body').on('click', function() {
var elem = event.target,
curClass = $(elem).attr('class'),
i = cards.indexOf($(elem).attr('class'));
$(elem)
.removeClass(curClass)
.addClass(cards[i = (i + 1) % cards.length]);
});
div {
height: 100px;
width: 100px;
display: inline-block;
}
.card-green {
background-color: green;
}
.card-yellow {
background-color: yellow;
}
.card-red {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo" class="card-green"></div>
<div id="bar" class="card-yellow"></div>
<div id="baz" class="card-red"></div>
Use an additional index variable to keep track of the position in the array:
Demo Snippet:
$(document).ready(function() {
var cardColors = ['card-green', 'card-yellow', 'card-red']
var i = 0
$('body').on('click', function() {
$(this)
.removeClass(cardColors[i])
.addClass(cardColors[i = (i + 1) % cardColors.length])
})
})
body {
width: 100vw;
height: 100vh;
margin: 0;
padding: 0;
}
.card-green { background-color: green; }
.card-yellow { background-color: yellow; }
.card-red { background-color: red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
The same code is workable just remove nodeName from removeClass(event.target.nodeName.className) instead of this use removeClass(event.target.className).
Try this, Its working for me.
$(document).ready(function() {
$('body').on('click', function(event) {
var cardColors = ['card-green', 'card-yellow', 'card-red'];
alert(event.target.className)
if ($(event.target.nodeName).attr('class') == 'card-green') {
$(event.target.nodeName).removeClass(event.target.className).addClass(cardColors[1]);
} else if ($(this).attr('class') == 'card-yellow') {
$(event.target.nodeName).removeClass(event.target.className).addClass(cardColors[2]);
} else {
$(event.target.nodeName).removeClass(event.target.className).addClass(cardColors[0]);
}
})
});
Here is jsfiddle of raw code and the result should be like this
<div class="wrapper">
<div class="row">
<div class="col red">R</div>
<div class="col blue">B</div>
<div class="col green">G</div>
<div class="col orange">O</div>
</div>
</div>
The mission is: Last color of previous row should be the first in next row and first color from previuos row should be the second in next row.
I think that I have to use loop and recursion but I don't have enough knowledge to do this.
Thanks in advance :)
You can run through the for loop and do something like this
check this snippet
//last color of previous row should be first in next row
//first color from previous row should be second in next row
var colors = ['red', 'blue', 'green', 'orange'];
$(document).ready(function() {
var rows = $('.row');
rows.each(function(row) {
var index = $(this).index();
var prevRow;
if (index > 0)
prevRow = $(this).prev();
colorColumns($(this).find('.col'), prevRow);
});
});
function colorColumns(cols, prevRow) {
var index = 0;
// alert("hi");
cols.each(function(col) {
var colIndex = $(this).index();
if (prevRow) {
var cols = prevRow.find('.col').length;
var totalCols = cols - 1;
var currentIndex = ((colIndex + totalCols) % cols);
var prevRowColor = $(prevRow).find('.col').eq(currentIndex);
var classes = prevRowColor.attr('class');
var classArr = classes.split(" ");
$(this).addClass(classArr[1]);
} else {
$(this).addClass(colors[colIndex]);
}
});
}
.row {
display: flex;
}
.row .col {
width: 20px;
height: 20px;
border-radius: 100%;
text-align: center;
}
.red {
background: red;
}
.orange {
background: orange;
}
.blue {
background: blue;
}
.green {
background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="row">
<div class="col">R</div>
<div class="col">B</div>
<div class="col">G</div>
<div class="col">O</div>
</div>
<div class="row">
<div class="col">R</div>
<div class="col">B</div>
<div class="col">G</div>
<div class="col">О</div>
</div>
<div class="row">
<div class="col">R</div>
<div class="col">B</div>
<div class="col">G</div>
<div class="col">O</div>
</div>
Hope it helps
I am trying to swap a div's position from top on and when I click another div then top div can be swap.
HTML
<div class="wrap top">
<input type="text" value="div1" class="textbox " />
</div>
<div class="wrap">
<input type="text" value="div2" class="textbox " />
</div>
<div class="wrap">
<input type="text" value="div3" class="textbox " />
</div>
jQuery
(function ($) {
$(".wrap").on("click", function () {
if ($(this).index() == 0) {
} else {
$(this).insertBefore($(this).prev());
}
});
}(jQuery));
The fact is I don't want to remove the div which I click instead want to swap the positions around.
How Can I do this using jQuery itself?
I would suggest using css to position the top div and just swap the class as follows:
(function ($) {
$(".wrap").on("click", function () {
if ($(this).index() == 0) {
} else {
$(".wrap").removeClass("top");
$(this).addClass("top");
}
});
}(jQuery));
this will swap whatever you click with the first element.
$(".wrap").on("click", function () {
var $this = $(this);
if ($this.index() == 0) {
} else {
var first = $this.siblings('.wrap').first();
first.insertBefore($this);
$this.prependTo($this.parent());
}
});
if you just want to move the clicked element to the top, you can simply do
$this.prependTo($this.parent());
To swap the two DOM elements using jQuery, you could use something like this: -
(function($) {
$(".wrap").on("click", function(event) {
var index = $(event.target).index();
var first = $(".wrap").first();
if (index > 0) {
$(first).swapWith(this);
}
});
}(jQuery));
jQuery.fn.swapWith = function(to) {
return this.each(function() {
var copy_to = $(to).clone(true);
var copy_from = $(this).clone(true);
$(to).replaceWith(copy_from);
$(this).replaceWith(copy_to);
});
};
.wrap {
height: 100px;
width: 200px;
margin: 10px 10px 10px 10px;
background-color: #2d8cd0;
}
h2 {
color: white;
text-align: center;
padding-top: 20px;
pointer-events: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="wrap">
<h2>1</h2>
</div>
<div class="wrap">
<h2>2</h2>
</div>
<div class="wrap">
<h2>3</h2>
</div>
<div class="wrap">
<h2>4</h2>
</div>
DEMO
Hi,
on click of images I'am passing the Image Name (attribute) to an Array, which is working fine, but whenever user click again to UnSelect, I'am trying to REMOVE Current Name($(this)), which is not happening, Instead Its being Removed Completely (Empty Array).
and also every time comma is appending for 1st element :-(
JS :
questionCount = 0;
$('.q2 .product-multiple').on('click',function(e){
if($(this).hasClass('selectTag')){
questionCount--;
$(this).removeClass('selectTag');
removeItem = "Removing Clicked element Name - " + $(this).find('img').attr('name')
alert(removeItem);
console.log("Should be Removed here.. " +" "+ getTagsNameArray)
}
else {
questionCount++;
$(this).addClass('selectTag');
getTagsNameArray = new Array();
getTagsName = getTagsName + "," + $(this).find('img').attr('name');
getTagsNameArray.push(getTagsName)
console.log("Passing Value in Array - " +" "+ getTagsNameArray)
}
});
$('.q2-get-answer').on('click', function(){
getTagsName = getTagsName +" / "+ $('.q2-answer').find('.product-multiple.selectTag img').attr('name');
alert(getTagsName)
console.log(getTagsName);
})
html :
<div class="q2">
<label for="q2">What type of symptoms that your child has?</label>
<div class="q2-answer" id="q2">
<div class="product-multiple">
<img alt="doctor select" src="http://i.istockimg.com/file_thumbview_approve/45921804/5/stock-photo-45921804-lake-view.jpg" name="gassy">
<div>Gassy</div>
</div>
<div class="product-multiple">
<img alt="doctor select" src="http://i.istockimg.com/file_thumbview_approve/45921804/5/stock-photo-45921804-lake-view.jpg" name="fussy">
<div>Fussy</div>
</div>
<div class="product-multiple">
<img alt="doctor select" src="http://i.istockimg.com/file_thumbview_approve/45921804/5/stock-photo-45921804-lake-view.jpg" name="diahrea">
<div>Diahrea</div>
</div>
<div class="product-multiple">
<img alt="doctor select" src="http://i.istockimg.com/file_thumbview_approve/45921804/5/stock-photo-45921804-lake-view.jpg" name="spitup">
<div>Spit Up</div>
</div>
<div class="product-multiple">
<img alt="doctor select" src="http://i.istockimg.com/file_thumbview_approve/45921804/5/stock-photo-45921804-lake-view.jpg" name="constipation">
<div>Constipation</div>
</div>
</div>
<div class="q2-get-answer">
Q3 click me
</div>
</div>
Thanks for Answer!!
can i create a common function for this, as there are many questions with same functionality ?
Any Thoughts ?
Thanks Again
Try this.
var getQ1Answer, getQ2Answer, getQ3Answer, getQ4Answer, getQ5Answer, getQ6Answer, sliderValue, selectMonth, q1answer, getTags;
var getTagsName = "";
var getTagsNameArray = new Array();
questionCount = 0;
$('.q2 .product-multiple').on('click', function(e) {
if ($(this).hasClass('selectTag')) {
questionCount--;
$(this).removeClass('selectTag');
var index = getTagsNameArray.indexOf($(this).find('img').attr('name'));
if (index !== -1) {
getTagsNameArray.splice(index, 1);
}
} else {
questionCount++;
$(this).addClass('selectTag');
getTagsNameArray.push($(this).find('img').attr('name'));
}
});
You need to declare array outside the function. You pushed items in array with , which is not needed. Your JS code will look like:
var getQ1Answer, getQ2Answer, getQ3Answer, getQ4Answer, getQ5Answer, getQ6Answer, sliderValue, selectMonth, q1answer, getTags;
var getTagsName = "";
var getTagsNameArray = new Array(); // here you should create an array
questionCount = 0;
$('.q2 .product-multiple').on('click',function(e){
if($(this).hasClass('selectTag')){
questionCount--;
$(this).removeClass('selectTag');
removeItem = "Removing Clicked element Name - " + $(this).find('img').attr('name')
alert(removeItem);
var doubleSelect = $(this).find('img').attr('name');
var index = getTagsNameArray.indexOf(doubleSelect);
console.log(index)
if (index > -1) {
getTagsNameArray.splice(index, 1);
}
console.log("Should be Removed here.. " +" "+ getTagsNameArray)
}
else {
questionCount++;
$(this).addClass('selectTag');
getTagsNameArray.push($(this).find('img').attr('name')); //change is here
console.log("Passing Value in Array - " +" "+ getTagsNameArray)
}
});
$('.q2-get-answer').on('click', function(){
getTagsName = getTagsName +" / "+ $('.q2-answer').find('.product-multiple.selectTag img').attr('name');
alert(getTagsName)
console.log(getTagsName);
})
Fiddle
You are appending a string to an array, which transforms the array into a string: getTagsName + ","
Instead of appending a string to the array, you need to add a new element to the Array by using getTagName.push($(this).find('img').attr('name')). You can remove items by using indexOf() and splice().
If you want to print the array, simply use getTagsName.join(). This will turn your array in a comma-seperated string.
It's because you create a new getTagsNameArray array everytime you unselect a $('.q2 .product-multiple'). See the else statement in the click handler.
If I understand your question correctly, you want an array with the name attributes of the selected images? In that case:
declare and create the getTagsNameArray outside the click handler
on click of an image, add the name to the array
on click again (so unselecting), find the name in the array and
remove it.
https://jsfiddle.net/gcke1msx/7/
var getTagsNameArray = [];
$('.q2 .product-multiple').on('click', function(e) {
// get the name of the image
var name = $(this).find('img').attr('name');
if($(this).hasClass('selectTag')) {
// it was selected, now unselected
// so remove its name from the array
// see: http://stackoverflow.com/questions/5767325/remove-a-particular-element-from-an-array-in-javascript
$(this).removeClass('selectTag');
var index = getTagsNameArray.indexOf(name);
getTagsNameArray.splice(index, 1);
} else {
// selected it
// and add name to array
$(this).addClass('selectTag');
getTagsNameArray.push(name);
}
});
$('.q2-get-answer').on('click', function(){
alert('selected: ' + getTagsNameArray.join(', '));
})
First of all, you should not have so many variables. Just a variable to push/splice item from/to array.
Array.prototype.splice() => The splice() method changes the content of an array by removing existing elements and/or adding new elements.
Syntax: array.splice(start, deleteCount[, item1[, item2[, ...]]])
var getTagsNameArray = [];
$('.q2 .product-multiple').on('click', function(e) {
var item = $(this).find('img').attr('name');
if ($(this).hasClass('selectTag')) {
$(this).removeClass('selectTag');
getTagsNameArray.splice(getTagsNameArray.indexOf(item), 1);
} else {
$(this).addClass('selectTag');
getTagsNameArray.push(item);
}
console.log(getTagsNameArray.join(', '));
});
$('.q2-get-answer').on('click', function() {
console.log(getTagsNameArray.join(', '));
})
.product-multiple {
float: left;
margin: 10px;
}
.product-multiple img {
width: 200px;
height: 150px;
}
.product-multiple img:hover {
cursor: pointer;
}
.ui-state-default,
.ui-widget-content .ui-state-default,
.ui-widget-header .ui-state-default {
cursor: pointer;
}
.digestive-tool {
padding: 10px;
margin: 10px;
border: 1px solid #ccc;
}
.digestive-tool .q1-answer li,
.digestive-tool .q2-answer li,
.digestive-tool .q3-answer li,
.digestive-tool .q4-answer li,
.digestive-tool .q5-answer li,
.digestive-tool .q6-answer li {
list-style-type: none;
display: inline-block;
}
.digestive-tool .q1-get-answer,
.digestive-tool .q2-get-answer,
.digestive-tool .q3-get-answer,
.digestive-tool .q4-get-answer,
.digestive-tool .q5-get-answer,
.digestive-tool .q6-get-answer {
border: 1px solid #f00;
padding: 10px;
display: inline-block;
cursor: pointer;
}
.digestive-tool .product,
.digestive-tool .product-multiple {
display: inline-block;
}
.digestive-tool .product img,
.digestive-tool .product-multiple img {
width: 150px;
height: 180px;
cursor: pointer;
}
.selectTag {
border: 2px solid #00257a;
}
.q2-get-answer {
margin-top: 20px;
clear: left;
border: 1px solid #900;
background: #f00;
cursor: pointer;
width: 200px;
padding: 20px;
color: #fff;
}
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="q2">
<label for="q2">What type of symptoms that your child has?</label>
<div class="q2-answer" id="q2">
<div class="product-multiple">
<img alt="doctor select" src="http://i.istockimg.com/file_thumbview_approve/45921804/5/stock-photo-45921804-lake-view.jpg" name="gassy">
<div>Gassy</div>
</div>
<div class="product-multiple">
<img alt="doctor select" src="http://i.istockimg.com/file_thumbview_approve/45921804/5/stock-photo-45921804-lake-view.jpg" name="fussy">
<div>Fussy</div>
</div>
<div class="product-multiple">
<img alt="doctor select" src="http://i.istockimg.com/file_thumbview_approve/45921804/5/stock-photo-45921804-lake-view.jpg" name="diahrea">
<div>Diahrea</div>
</div>
<div class="product-multiple">
<img alt="doctor select" src="http://i.istockimg.com/file_thumbview_approve/45921804/5/stock-photo-45921804-lake-view.jpg" name="spitup">
<div>Spit Up</div>
</div>
<div class="product-multiple">
<img alt="doctor select" src="http://i.istockimg.com/file_thumbview_approve/45921804/5/stock-photo-45921804-lake-view.jpg" name="constipation">
<div>Constipation</div>
</div>
</div>
<div class="q2-get-answer">
Q3 click me
</div>
</div>
Fiddle here
Here is a live demo
https://jsfiddle.net/soonsuweb/4ea54xxu/3/
You can use array.push, splice, join.
var selected = [];
$('.q2 .product-multiple').on('click',function (e) {
if($(this).hasClass('selectTag')){
$(this).removeClass('selectTag');
var name = $(this).find('img').attr('name');
// remove the name from selected
for (var i=0; i<selected.length; i++) {
if (name === selected[i]) {
selected.splice(i, 1);
}
}
console.log("Should be Removed here.. ", name);
console.log("Passing Value in Array - ", selected.join(', '))
}
else {
$(this).addClass('selectTag');
var name = $(this).find('img').attr('name');
selected.push(name);
console.log("Passing Value in Array - ", selected.join(', '))
}
});
$('.q2-get-answer').on('click', function () {
alert(selected.join(', '));
console.log(selected.join(', '));
});
How can i select each div inside parent div & apply class (om_0 & go on) with increasing index number. Here I am unable to target each div.
Or how can I add attribute id="om_0", id="om_1", id="om_2" etc. to each div
The problem is it's applying all classes in one div & repeat it
var cirLength = $("div#circleBox > div").length;
for(var i=0; i<cirLength; i++){
$("div#circleBox").find('div').addClass('om_'+i);
}
<div id="circleBox"><div class="om_0 om_1 om_2"><span>AcessGreen</span></div><div class="om_0 om_1 om_2"><span>AccessBlue</span></div><div class="om_0 om_1 om_2"><span>AccessOrange</span></div></div>
You can use each() to iterate jQuery objects
$("div#circleBox").find('div').each(function(i) {
$(this).addClass('om_' + i);
// If you need to add it as id then use `this.id= 'om_' + i ` instead of `$(this).addClass('om_' + i)`
});
.om_0 {
color: red;
}
.om_1 {
color: green;
}
.om_2 {
color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="circleBox">
<div><span>AcessGreen</span>
</div>
<div><span>AccessBlue</span>
</div>
<div><span>AccessOrange</span>
</div>
</div>
With your own code you need to select individual item using eq()
var cirLength = $("div#circleBox > div").length;
for (var i = 0; i < cirLength; i++) {
$("div#circleBox").find('div').eq(i).addClass('om_' + i);
}
.om_0 {
color: red;
}
.om_1 {
color: green;
}
.om_2 {
color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="circleBox">
<div><span>AcessGreen</span>
</div>
<div><span>AccessBlue</span>
</div>
<div><span>AccessOrange</span>
</div>
</div>