Simple switch case not working - javascript

Here is simple code to change the display of a div on the button action using switch case.
Please have a look at it i am not getting where i went wrong.
Link: https://jsfiddle.net/r6nkuwvc/
javascipt code:
$(document).on('click', ".change", function() {
var $input = $(this);
$(".same").each(function() {
if ($(this).css("display") == "block") {
$(this).css("display", "none");
}
});
switch ($input.attr("id")) {
case "b1":
$("#abc").css("display", "block");
break;
case "b2":
$("#xyz").css("display", "block");
break;
}
});

As has been pointed out in the comments, your code works as is. You just forgot to add the jQuery library, and the selectors #hello and #bye didn't exist. Next to that, you are also over-complicating your code. In jQuery you do not have to check if an element is visible before hiding it, you can just hide it. And when using a class selector you do not have to run .each against it for jQuery's own internal functions such as hide(); jQuery will hide all elements with this class.
https://jsfiddle.net/r6nkuwvc/5/
$(document).on('click', ".change", function() {
$(".same").hide();
switch ($(this).attr("id")) {
case "b1":
$("#abc").show();
break;
case "b2":
$("#xyz").show();
break;
}
});

You can make it even much simpler using an object. Store the reference to the
selector in an object this way you can avoid the switch case. Although use show() and hide() methods to show and hide the elements.
// object which holds the reference
var sel = {
b1: "#abc",
b2: "#xyz"
};
$(document).on('click', ".change", function() {
// hide all elements initially there is no need to iterate over them
$(".same").hide();
// get selector from object using id and show the element
$(sel[this.id]).show();
})
$(document).on('click', ".change", function() {
var sel = {
b1: "#abc",
b2: "#xyz"
};
$(".same").hide();
$(sel[this.id]).show();
})
.same {
display: none;
width: 400px;
height: 200px;
border: 1px solid;
}
#abc {
display: block;
}
#xyz {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div id="abc" class="same">
Hello
</div>
<div id="xyz" class="same">
Bye
</div>
<button id="b1" class="change">b1</button>
<br>
<button id="b2" class="change">b2</button>
</body>

You have not put up proper id's. Also I think you forget to set JQuery link in your code, that is why it is giving reference error.
Here is the updated code:
$(document).on('click', ".change", function(){
var $input = $(this);
$(".same").each(function(){
if($(this).css("display")=="block"){
$(this).css("display","none");
}
})
switch($input.attr("id")){
case "b1" : $("#abc").css("display", "block");
break;
case "b2" : $("#xyz").css("display","block");
break;
}
})
.same{
display: none;
width: 400px;
height: 200px;
border: 1px solid;
}
#abc{
display: block;
}
#xyz{
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<body>
<div id="abc" class="same">
Hello
</div>
<div id="xyz" class="same">
Bye
</div>
<button id="b1" class="change">b1</button><br>
<button id="b2" class="change">b2</button>
</body>
Here is the jsfiddle https://jsfiddle.net/r6nkuwvc/6/

In case you want to control what to show/hide from html, than I suggest this approach:
$('body').on('click', '[data-hide]', function(e) {
$($(this).data('hide')).hide();
});
$('body').on('click', '[data-show]', function(e) {
$($(this).data('show')).show();
});
.same {
display: none;
width: 100%;
height: 100px;
border: 1px solid black;
}
#abc {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="abc" class="same">
Hello
</div>
<div id="xyz" class="same">
Bye
</div>
<p>
<button data-hide=".same" data-show="#abc">Show Hallo</button>
</p>
<p>
<button data-hide=".same" data-show="#xyz">Show Bye</button>
</p>

Related

Why does jQuery .text() not return the value inside the div?

I am missing something trivial here, but I don't get it. Why doesn't it alert Test Value?
$('.comment-upvote-wrapper').on('click', function() {
// Get the comments pk
var comment_pk = $(this).closest('#comment-pk').text()
alert(comment_pk)
})
.comment-upvote-wrapper {
width: max-content;
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div hidden id="comment-pk">Test Value</div>
<div class="comment-box">
<div class="comment-options">
<div class="comment-upvote-wrapper comment-options-box">Return "Text Value"
The problem is because #comment-pk is not an ancestor element of .comment-upvote-wrapper, it's a sibling of .comment-box. Therefore you need to use closest() to get the .common-box, then prev():
$('.comment-upvote-wrapper').on('click', function() {
var comment_pk = $(this).closest('.comment-box').prev('#comment-pk').text();
console.log(comment_pk)
})
.comment-upvote-wrapper {
width: max-content;
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div hidden id="comment-pk">Test Value</div>
<div class="comment-box">
<div class="comment-options">
<div class="comment-upvote-wrapper comment-options-box">Return "Text Value"</div>
</div>
</div>
However the fact that the element has an id attribute means there should only ever be one of them in the DOM. As such using DOM traversal to find it is redundant; you can just select it directly by its id:
$('.comment-upvote-wrapper').on('click', function() {
var comment_pk = $('#comment-pk').text();
console.log(comment_pk)
})

Add a div below inline-block wrapped row - Part 2

A solution suggested by #musicnothing in an older thread displays a content div below the row of inline divs, this works good when the div.wrapblock is clicked itself.
http://jsfiddle.net/SYJaj/7/
function placeAfter($block) {
$block.after($('#content'));
}
$('.wrapblock').click(function() {
$('#content').css('display','inline-block');
var top = $(this).offset().top;
var $blocks = $(this).nextAll('.wrapblock');
if ($blocks.length == 0) {
placeAfter($(this));
return false;
}
$blocks.each(function(i, j) {
if($(this).offset().top != top) {
placeAfter($(this).prev('.wrapblock'));
return false;
} else if ((i + 1) == $blocks.length) {
placeAfter($(this));
return false;
}
});
});
The issue I'm having.
I need to trigger the same effect, but by adding the click event to a link within the wrapblock itself.
My code is nearly identical.
What I have changed is the click event handle, from $('.wrapblock').click(function() to $('.more').on('click', function() I also needed to add .closest(".wrapblock") for the content div to position itself outside of the wrapblock.
$('.more').on('click', function() {
...
if ($blocks.length == 0) {
placeAfter($(this).closest(".wrapblock"));
return false;
}
Everything can be seen and tested http://jsfiddle.net/7Lt1hnaL/
Would be great if somebody could shed some light on how I can calculate which block it needs to follow with the offset method, thanks in advance.
As you can see in the latest fiddle example, the content div is not displaying below the row of divs.
I also apologise, I wanted to post on the thread in discussion but I only have a minor posting reputation which doesn't let me, thanks.
var $chosen = null;
var $allBlocks = [];
$(function(){
$allBlocks = $('.wrapblock');
})
$(window).on('resize', function() {
if ($chosen != null) {
$('#content').css('display','none');
$('body').append($('#content'));
$chosen.trigger('click');
}
});
$('.more').on('click', function() {
$chosen = $(this);
var position = $chosen.parent('.wrapblock').position();
$('#content').css('display','inline-block');
$allBlocks.filter(function(idx, ele){
return $(ele).position().top == position.top;
})
.last()
.after($('#content'));
});
.wrapblock
{
background: #963a3a;
display: inline-block;
width: 90px;
height: 90px;
color: white;
font-size: 14px;
text-align: left;
padding: 10px;
margin: 10px;
vertical-align:top;
position:relative;
}
#content
{
display:none;
vertical-align:top;
width:100%;
background: #5582c1;
font-size: 12px;
color: white;
padding: 10px;
}
.more {
position:absolute;
bottom:15px;
right:15px;
cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<div class="wrapblock">1
<span class="more" data-ref="1">more</span>
</div>
<div class="wrapblock">2
<span class="more" data-ref="2">more</span>
</div>
<div class="wrapblock">3
<span class="more" data-ref="3">more</span>
</div>
<div class="wrapblock">4
<span class="more" data-ref="4">more</span>
</div>
<div class="wrapblock">5
<span class="more" data-ref="5">more</span>
</div>
<div class="wrapblock">6
<span class="more" data-ref="6">more</span>
</div>
<div class="wrapblock">7
<span class="more" data-ref="7">more</span>
</div>
<div class="wrapblock">8
<span class="more" data-ref="8">more</span>
</div>
<div class="wrapblock">9
<span class="more" data-ref="9">more</span>
</div>
<div id="content">Some Content</div>
Seems to do what you want. Basically, it just filters down the set of all blocks to the row of the block you clicked on using the assumption that they'll all have the same vertical offset (top), then takes the last one, because jQuery will keep them in document order, so that'll be the last one in the layout row.
Oh, and I updated the fiddle http://jsfiddle.net/7Lt1hnaL/1/

Remove a class which is not recognized by DOM

I am working on a interactive map, which triggers an overlay image (which highlights the selected area)
But now I add classes to an div and I want to delete them if I highlight an other area. First I tried the starts with indicator to remove classes which starts with hl- this is my js file:
$('.btn-pointer').click(function() {
$('.highlight-layer').removeClass('[class^="hl-"]');
});
$('.btn-sp').click(function() {
$('.highlight-layer').addClass('hl-sp');
$('.popover').not(this).popover('hide');
});
$('.btn-vp').click(function() {
$('.highlight-layer').addClass('hl-vp');
$('.popover').not(this).popover('hide');
});
$('.btn-sl').click(function() {
$('.highlight-layer').addClass('hl-sl');
$('.popover').not(this).popover('hide');
});
$('.btn-ec').click(function() {
$('.highlight-layer').addClass('hl-ec');
$('.popover').not(this).popover('hide');
});
And here is the html:
<div>
<img src="../img/map/map-full.jpg" alt="">
<button class="btn btn-sp btn-pointer" data-container="body" data-toggle="popover" data-placement="top" data-content="<h2>Safaripark</h2>">Safaripark</button>
<button class="btn btn-vp btn-pointer" data-container="body" data-toggle="popover" data-placement="top" data-content="<h2>Vakantiepark</h2>">Vakantiepark</button>
<button class="btn btn-sl btn-pointer" data-container="body" data-toggle="popover" data-placement="top" data-content="<h2>Speelland</h2>">Speelland</button>
<button class="btn btn-ec btn-pointer" data-container="body" data-toggle="popover" data-placement="top" data-content="<h2>Event Center</h2>">Event Center</button>
<div class="highlight-layer hl-ec"></div>
</div>
I tried to create a Fiddle but never added external Resources so the error it gives me is the following: Uncaught Error: Bootstrap's JavaScript requires jQuery
You could use the callback for removeClass to filter out the classes you want to remove based on a starting string etc
$('.highlight-layer').removeClass(function(i, klass) {
var remove = 'hl-';
return klass.split(/\s/).filter(function(k) {
return k.indexOf(remove) === 0;
}).join(' ');
});
removeClass doesn't accept a selector, it accepts a space-delimited series of classes to remove. So just list the ones you want to remove:
$('.highlight-layer').removeClass('hl-sp hl-vp hl-sl hl-ec');
It's fine if one (or indeed all) of them aren't on any given element; the one(s) that is/are will be removed.
Example:
$("input[type=button]").on("click", function() {
$(".highlight-layer").removeClass("hl-sp hl-vp hl-sl hl-ec");
});
.hl-sp {
color: red;
}
.hl-vp {
color: green;
}
.hl-sl {
color: blue;
}
.hl-ec {
color: grey;
}
<div>
<input type="button" value="Remove">
<div class="highlight-layer hl-sp">Starts out with hl-sp</div>
<div class="highlight-layer hl-vp">Starts out with hl-vp</div>
<div class="highlight-layer hl-sl">Starts out with hl-sl</div>
<div class="highlight-layer hl-ec">Starts out with hl-ec</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Working Fiddle.
You have just to change one line in your code and it will works check the code below that remove all the classes and keep just the essential one highlight-layer :
$('.btn-pointer').click(function() {
$('.highlight-layer').removeClass().addClass('highlight-layer');
});
Like this the element classes are always two highlight-layer and clicker button class.
Hope this helps.
You can add extension to jQuery which would loop through elements returned from selector and remove list.
Following is a basic example:
JSFiddle.
$.fn.removeClasses = function(regex) {
Array.prototype.forEach.call(this, function(el) {
var class_list = el.classList;
var filtered_list = Array.prototype.filter.call(class_list, function(c) {
return regex.test(c);
});
console.log(filtered_list);
$(el).removeClass(filtered_list.join(" "))
});
}
$(".foo").on("click", function() {
var reg = /^test/;
$(this).removeClasses(reg);
});
.test {
background: #333;
}
.test1 {
color: #fff;
}
.test2 {
border: 1px solid gray;
}
.test3 {
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="test test1 test2 test3 foo">
Test
</div>

How to create a function to get next id of element in jquery and call this function?

I've created a custom function goToNext() it's just supposed to alert the id of the next element that i've clicked on.
I want to call this custom function inside another click function.
For now when I click on first element it alerts id_2 (next from the first, so it's ok) but if you click the second element it doesn't return id_3 (like it's supposed to be) but it return id_2 same if you click on the last element (supposed to alert the first)
this is my jsfiddle example here
function goToNext() {
var get_next_id = $('.btn').next().attr("id");
alert(get_next_id);
}
$('.btn').click(function() {
goToNext();
});
.btn {
width: 50px;
height: 50px;
margin: 10px auto;
background-color: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="btn" id="id-1">
1
</div>
<div class="btn" id="id-2">
2
</div>
<div class="btn" id="id-3">
3
</div>
Try this
function goToNext($btn){
var get_next_id = $btn.next().attr("id");
alert(get_next_id);
}
$('.btn').click(function(){
goToNext($(this));
});
You have to use this
function goToNext(thisObj){
var get_next_id = $(thisObj).next().attr("id");
if(get_next_id!=undefined)
alert(get_next_id);
else
alert($(thisObj).parents().find("div:first").attr("id"));
}
$('.btn').click(function(){
goToNext(this);
});
.btn{
width:50px;
height:50px;
margin:10px auto;
background-color:yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class ="btn" id="id-1">
1
</div>
<div class ="btn" id="id-2">
2
</div>
<div class ="btn" id="id-3">
3
</div>
You need to use reference this
function goToNext(e){
var get_next_id = $(e).next().attr("id");
alert(get_next_id);
}
$('.btn').click(function(){
goToNext(this);
});
Updated Fiddle

JS JQUERY bug when expanding ul event of click on li doesnt work

I've created a simple web page to learn about JQuery, But whenever I click on Button: another one its making the event of click on li disappear, glitched, it does nothing when the li is clicked.. . Here is the code:
JS:
$(document).ready(function(){
console.log("Ready");
var toggle = 0;
$("li").on("click",function(){
console.log("Clicked on li");
try{
$(this).hide(800);
$(this).removeClass("con");
$(this).addClass("con");
}
catch(err){
console.log("Exception "+err.message);
}
});
$("input").on("focus",function(){
console.log("Focused on input");
$("li").hide(800);
$("#D").html("Open div");
toggle = 1;
});
$("input").on("focusout",function(){
console.log("FocusedOut on input");
$("li").html($("input").val());
$("li").show(500,function(){
$("#D").html("Close div");
toggle = 0;
});
});
$("button").on("click",function(){
console.log("Clicked button :"+$(this).html());
if($(this).attr("id")=="s"){
$("li").show(300);
}
else if($(this).attr("id")=="n"){
$("li").removeClass("con");
}
else if($(this).attr("id")=="C"){
$("li").addClass("con");
}
else if($(this).attr("id")=="an"){
console.log("Added to html : "+$(".uDefined").html()+"<br/><li>"+$("li").last().html().substring(0,7)+($("li").last().html().substring(7,8)-(1)+1+1)+"</li>");
$(".uDefined").html($(".uDefined").html()+"<br/><li>"+$("li").last().html().substring(0,7)+($("li").last().html().substring(7,8)-(1)+1+1)+"</li>");
}
else{
$(".list").slideToggle(1000,function(){
if(toggle==0){
$("#D").html("Open div");
toggle=1;
}
else{
$("#D").html("Close div");
toggle = 0;
}
});
}
});
});
HTML:
<html>
<style type="text/css">
.list{
font-size: 100;
background-color: white;
}
li{
margin-left: 100;
border-radius: 20;
border-width: 3;
background-color: Black;
color:White;
}
.con{
color:red;
}
.uDefined{
}
</style>
<body onload="" style="background-color:gray;margin:40" >
<title>JQuery TryOut</title>
<h3 style="margin-left:800;">Welcome</h3>
<button id="D">Close Div</button>
<button id="s">Show All</button>
<button id="n">Remove Classes</button>
<button id="C">Add Classes</button>
<div class="list">
<ul class="uDefined">
<li class="con">content1</li>
<li>content2</li>
<li>content3</li>
<li>content4</li>
<li>content5</li>
<li>content6</li>
</ul>
</div>
<div>
<p>Please focus on this text box:</p><input id="ttt" placeholder="Enter text here" value="" type="text" />
</div>
<button id="an" >another one</button>
</body>
<script type="text/javascript" src="jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="JavaScript.js"></script>
THANKS FOR HELPERS!
Direct events are only attached to elements (that exist) at the time the .on() method is called. So when you are adding buttons dynamically, you need to use delegated event handlers.
You should change your code like this:
$("ul").on("click", "li", function () {
...
});
More about delegated events:
http://learn.jquery.com/events/event-delegation/

Categories