jquery toggle between ID's based on element attribute - javascript

i have this
$(".picker").click(function(e) {
var imgID = $(this).attr("data-imgID");
$('body').addClass('picker-' + imgID);
});
<span class="taPicker" data-imgID="0"></span>
<span class="taPicker" data-imgID="1"></span>
<span class="taPicker" data-imgID="2"></span>
i want to toggle between generic classes on body element, for example if you click on .picker i want to add a unique class to body element based on the data-imgID attribute
But, how can i prevent the duplication's? for example if you click on another .picker i want to remove the previous class and add a new one

In your case you could do something like this:
var selectedClass = null;
$(".taPicker").click(function(e) {
var imgID = $(this).attr("data-imgID");
$('body').addClass('picker-' + imgID);
if (selectedClass != null) {
$('body').removeClass(selectedClass);
}
selectedClass = 'picker-' + imgID;
});
body.picker-0 {
background-color: pink;
}
body.picker-1 {
background-color: red;
}
body.picker-2 {
background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="taPicker" data-imgID="0">click 0</span>
<span class="taPicker" data-imgID="1">click 1</span>
<span class="taPicker" data-imgID="2">click 2</span>
Here is a fiddle

Another approach would be to determined the classes which need to be removed on each subsequent update. To this end, you can use a function which parses the current classes and removes any class which contains picker-, before setting the new class.
Here's what the JS code would look like:
function getPickerClasses(index, className) {
return className.split(' ').filter((classItem) => classItem.includes('picker-'));
}
$(".taPicker").click(function(e) {
var imgID = $(this).attr("data-imgID");
$('body').removeClass(getPickerClasses).addClass('picker-' + imgID);
});
This way, before setting the new class, the old one is removed.
Have a look at this fiddle to see the code in action: https://jsfiddle.net/0u24a1g3/

It can be done without adding extra global variable
$(".taPicker").click(function(e) {
var imgID = $(this).attr("data-imgID");
$('body').removeClass(function() {
return (this.className.match(/picker-./g) || []).join(' ');
});
$('body').addClass('picker-' + imgID);
});
body.picker-0 {
background-color: pink;
}
body.picker-1 {
background-color: red;
}
body.picker-2 {
background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="taPicker" data-imgID="0">click 0</span>
<span class="taPicker" data-imgID="1">click 1</span>
<span class="taPicker" data-imgID="2">click 2</span>

You can capture the original class(es) of body in a variable at DOM ready then use .removeClass() before re-adding back the original class plus the one based on the clicked element.
$(".taPicker").click(function(e) {
var imgID = $(this).attr("data-imgID");
var picker = $('body').attr("class").match(/picker-\d+/g) || [];
$('body').removeClass(picker).addClass('picker-' + imgID);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body class="original">
<span class="taPicker" data-imgID="0">0</span>
<span class="taPicker" data-imgID="1">1</span>
<span class="taPicker" data-imgID="2">2</span>
</body>

Related

Giving a div a style on click

applying a class to an element only when clicked
You could make 2 different click functions. One for trap and one for the rest.
For that you need to know which ones are the other ( safe ones ). See otherDivsIds in the below code. You find the other id's using the filter function in the idArray and then loop through them ( with forEach or something else ) and add event listeners to each of them.
I would also suggest to ' swap ' the naming of the variables trapBox and trapId. Vice versa would be better
See code below
var idArray = ['one','two','three','four'];
var trapBox = idArray[Math.floor(Math.random() * idArray.length)];
var trapId= document.getElementById(trapBox);
trapId.addEventListener('click', boomClickFunction, false);
var otherDivsIds = idArray.filter(id => id !== trapBox);
otherDivsIds.forEach(id => {
safeBox = document.getElementById(id);
safeBox.addEventListener('click', safeClickFunction, false)
})
var timeoutId = window.setTimeout(ticker, 5000);
function ticker() {
document.getElementById('timesUp').innerHTML = "Time's up!";
document.body.style.backgroundColor = "black";
}
function boomClickFunction() {
this.classList.add('boom')
}
function safeClickFunction() {
this.classList.add('safe')
}
div {
width: 20px;
height: 20px;
background-color: green;
margin: 20px;
float: left;
}
.boom {
background-color: red;
}
.safe {
background-color: lightblue;
}
#timesUp {
color: white;
}
<div id='one'>
</div>
<div id='two'>
</div>
<div id='three'>
</div>
<div id='four'>
</div>
<span id="timesUp">
</span>
You can add a class to an element by using classList.add('classToBeAdded').
In your case, you could put it in your clickFunction:
trapId.classList.add('boom');

Javascript get id number from a class name with parseint

Using Javascript, i am trying to extract a number from an element that looks like this
document.getElementById("mybutton").addEventListener("click", function() {
console.log("Button clicked")
parent = this.parentNode;
console.log(parent);
value = parseInt(parent);
console.log(value);
});
#mybutton {
padding: 20px;
background: gold;
}
<div class="myelement myid-364444-number">
<div id="mybutton">
Button
</div>
</div>
I am getting NaN everytime, where am I goind wrong?
The simplest way, for this specific example is to use a regular expression on the className of the parent node.
document.getElementById("mybutton").addEventListener("click", function() {
console.log("Button clicked")
const parent = this.parentNode;
console.log(parent);
const value = parseInt(parent.className.match(/\d+/));
console.log(value);
});
#mybutton {
padding: 20px;
background: gold;
}
<div class="myelement myid-364444-number">
<div id="mybutton">
Button
</div>
</div>

remove class to sibling of elemnt jquery

I have this Jquery function, with a filter that adds a class named selected to the filter by click and shows all that data filter tags of the selected filter.
I want to define that if the sibling of the chosen element has a class named selected, that class needs to be removed from the rest and has to be added to only the selected element.
Function Script
(function ($) {
"use strict";
$.fn.filter = function (options) {
var defaults = {
nav: '[data-filter]' //
}
var $this = this,
settings = $.extend(defaults, options),
$target = $(settings.target),
selected = [];
return this.each( function() {
var $element = $(this);
$(settings.nav).each( function() {
$(this).click( function(event) {
// add selected class
$(this).toggleClass('selected');
// manipulate selected terms array
if ($.inArray($(this).data('filter'), selected) < 0 ) {
selected.push($(this).data('filter'));
} else {
var index = $.inArray($(this).data('filter'), selected);
selected.splice(index, 1);
}
// show/hide elements
$element.find('[data-filter-tags]').each( function() {
var terms = $(this).data('filter-tags').split(','),
show = null;
for (var i=0;i<selected.length;i++) {
show = ($.inArray(selected[i], terms) >= 0 && show !== false);
}
if (show || selected.length == 0) {
$(this).fadeIn();
} else {
$(this).fadeOut();
}
});
event.preventDefault();
});
});
});
};
}(jQuery));
HTML
<div id="tags">
<div id="cities" data-activeclass="selected">
תל אביב
רמת גן
הכל
<div>
</br>
משרה מלאה
משרה חלקית
הכל
</br>
מזכירות
הפעלה
הכל
</br>
</nav>
<div id="filter">
<div class="block" style="background: green" data-filter-
tags="time,kind,city,telaviv,full,sec">תל אביב משרה מלאה מזכירות</div>
<div class="block" style="background: blue" data-filter-
tags="time,kind,city,ramatgan,full,sec">רמת גן מלאה מזכירות</div>
<div class="block" style="background: blue" data-filter-
tags="time,kind,city,ramatgan,part,op">רמת גן חלקית הפעלה</div>
<div class="block" style="background: blue" data-filter-
tags="time,kind,city,telaviv,full,op">תל אביב מלאה הפעלה</div>
<div class="block" style="background: blue" data-filter-
tags="time,kind,city,ramatgan,part,sec">רמת גן חלקית מזכירות</div>
</div>
I want to define that if the sibling of the choosen elemnts has class named
"selected" remove the class from them and add it only to the selected element.
If clicking the element selects it and deselects all of its siblings, then in your click handler:
$(this).addClass("selected").siblings().removeClass("selected");
Simplified live example:
$("[data-filter]").on("click", function() {
$(this).addClass("selected").siblings().removeClass("selected");
});
[data-filter] {
border: 1px solid blue;
}
.selected {
background-color: yellow;
}
<div>
<span data-filter="1">one</span>
<span data-filter="2">two</span>
<span data-filter="3">three</span>
<span data-filter="4">four</span>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
If clicking the element toggles it, we want toggleClass (which you have) but the rest is the same:
$(this).toggleClass("selected").siblings().removeClass("selected");
...since the .siblings().removeClass("selected"); part just won't do anything if the current element was the one that was selected.
Simplified live example:
$("[data-filter]").on("click", function() {
$(this).toggleClass("selected").siblings().removeClass("selected");
});
[data-filter] {
border: 1px solid blue;
}
.selected {
background-color: yellow;
}
<div>
<span data-filter="1">one</span>
<span data-filter="2">two</span>
<span data-filter="3">three</span>
<span data-filter="4">four</span>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

HTML append a class based on the name of current class JS

Is there a way to append a class to the current class name?
<li class="myWrap"></li>
Then onClick toggle class:
$('.myWrap').toggleClass('selected');
Is there anyway I can read the current class i've select and appended it to my one i'm adding. So my new class instead of:
<section class="myWrap selected"></section>
It will be:
<section class="myWrap myWrap_selected"></section>
.toggleClass() can already do this for you but you will need a way to determine the base class, because at any given point your elements can have more than one class (the base class, the selected class and any others). If you ensure that your base class will remain the first specified, then you can use the following.
$('li').on('click', function() {
// find the base class
var baseClass = $(this).attr('class').split(' ')[0];
// toggle the selected class
$(this).toggleClass(baseClass + '_selected');
});
$(function() {
$('li').on('click', function() {
var baseClass = $(this).attr('class').split(' ')[0];
$(this).toggleClass(baseClass + '_selected');
});
});
li.myClass {
border: 1px dashed red;
background-color: #ffcccc;
}
li.myClass_selected {
border-style:solid;
}
li.myWrap {
border: 1px dashed green;
background-color: #ccffcc;
}
li.myWrap_selected {
border-style:solid;
}
li.otherClass {
font-style:italic;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="myClass otherClass">Hello class</li>
<li class="myWrap otherClass">Hello wrap</li>
</ul>
Please try this function:
<script type="text/javascript" language="javascript">
$(document).ready(function() {
$('.myWrap').on('click', function() {
var newclass = $(this).attr('class') + "_selected";
$(this).toggleClass(newclass);
});
});
</script>

Custom html tab implementation problems

my use case : create tab like experience. clicking on add button creates a (horz tab button) and a corresponding div, which is linked via onclick listener, dynamically.
problems :
on clicking add button, values from previous tabs are reset (which is obvious wrt to the way $tabs_prev & $menu_prev is populated) and
their respective js goes away (which I can't understand, why?)
a remove tab implementation (because the way I've coded these tabs, removing a tab and corresponding div isn't really simple, so, any clues in this direction, maybe?)
code : fiddle : http://jsfiddle.net/g58fzs75/1/
HTML:
<body>
<input id="hidden" type="hidden" value="1"></input>
<div id="template_tabBtn" style="display:none">
<input type="button" value="add" onclick="addTab()"></input>
</div>
<ul id="menu">
</ul>
<div id="tabs">
</div>
<div id="template_tabBar" style="display:none">
<li>
<input type="button" id="tab_btn" class="template_tabBar" value="Tab" onclick="tabClick(this)"></input>
</li>
</div>
<div id="template_tabs" style="display:none">
<div id="tabs" class="template_tabs tab_div" value="1">
<input type="text" id="txt" class="template_tabs" value="alert"></input>
<input type="button" id="btn" class="template_tabs" value="alert"></input>
</div>
</div>
</body>
CSS:
<style>
ul#menu {
padding: 0;
}
ul#menu li {
display: inline;
}
ul#menu li input {
background-color: black;
color: white;
padding: 10px 20px;
text-decoration: none;
border-radius: 4px 4px 0 0;
}
ul#menu li input:hover {
background-color: orange;
}
</style>
jQuery :
<script src="http://code.jquery.com/jquery-1.9.1.js" type="text/javascript"></script>
<script>
$tabs_prev = "";
$menu_prev = "";
$add_btn = "";
$current_tabID = "";
function tabClick(id) {
showCurrent($(id).attr('id'));
}
function addTab() {
var tabCount = parseInt($('#hidden').val()) + 1;
$('#hidden').val(tabCount);
run(tabCount);
showCurrent($('#tabs-' + tabCount).attr('id'));
}
$(document).ready(function() {
$add_btn = "<li>" + $('#template_tabBtn').html() + "</li>";
run(1);
});
function run(tabCount) {
//$tabs_prev += main($('#template_tabs'),tabCount);//alert("tabs\n"+$tabs_prev);
$menu_prev += main($('#template_tabBar'), tabCount); //alert("menu\n"+$menu_prev);
$('#tabs').html($('#tabs').html() + main($('#template_tabs'), tabCount));
$('#menu').html($menu_prev + $add_btn);
logic(tabCount);
}
function main(target, tabCount) {
$htmlBackup = $(target).html();
$('.' + $(target).attr('id')).each(function() {
$(this).attr('id', $(this).attr('id') + "-" + tabCount).removeClass($(target).attr('id'));
$(this).attr('value', $(this).attr('value') + "-" + tabCount);
});
$html = $(target).html();
$(target).html($htmlBackup);
return $html;
}
function logic(tabCount) {
$('#btn-' + tabCount).click(function() {
alert($('#txt-' + tabCount).val());
});
}
function showCurrent(current_id) {
$('.tab_div').each(function() {
var id = $(this).attr('id');
var id_num = id.substr(id.lastIndexOf('-') + 1, id.length);
var current_id_num = current_id.substr(current_id.lastIndexOf('-') + 1, current_id.length);
if (id_num == current_id_num) {
$("#tabs-" + id_num).show();
$('#tab_btn-' + id_num).css({
"background-color": "orange"
});
} else {
$("#tabs-" + id_num).hide();
$('#tab_btn-' + id_num).css({
"background-color": "black"
});
}
});
}
</script>
The reason why your javascript is disappearing is because resetting the innerHTML deletes the onclick handlers on the elements. Why: the original elements are destroyed, including references to events and new elements are created.
The code responsible for this:
$('#tabs').html($('#tabs').html() + main($('#template_tabs'), tabCount));
Please use jQuery's appending of an element by cloning the template tab:
$('#tabs').append($('#template_tabs').clone(true));
Append appends htmlstrings or elements to an parent element. It's a buffed up version of the documents native 'appendChild'.
clone clone the template element (makes a copy). You can do this in your function main and return it to the append function.
function main(tabCount)
{
var node = $('#template_tabs').clone(true));
//do things with the node, like setting an onclick handler, or id.
//example
node.setAttribute("id", "tab" + tabCount);
}
Removing can be done also:
function removeNode(node)
{
//provide a node via jQuery
//example: removeNode($("#tab2")) <-- now tab2 will be removed from the DOM.
node.remove();
}

Categories