Change tab styling for all tabs except the one being clicked - javascript

So I have a few tabs. There can be multiple tabs, but I currently have 3. What I am trying to do is to change the styling of the tab when it is clicked and the other tabs to have some other styling. My code is as follows:
<div id="ClaimTabs" class="TabbedPanels">
<div class="TabbedPanelsTabGroup">
<div id="list1" class="TabbedPanelsTab TabbedPanelsTabSelected">
<a id="anchor1" class="TabbedPanelAnchor" href="javascript:showTab(1);">Tab 1 </a>
</div>
<div id="list2" class="TabbedPanelsTab">
<a id="anchor2" href="javascript:showTab(2);" >Tab 2</a>
</div>
<div id="list3" class="TabbedPanelsTab">
<a id="anchor3" href="javascript:showTab(3);">Tab 3</a>
</div>
</div>
<div id="ClaimContent" class="TabbedPanelsContentGroup">
<div id="tab1" class="TabbedPanelsContent TabbedPanelsContentVisible" style="display: block;">
Screen 1
</div>
<div id="tab2" class="TabbedPanelsContent" style="display: none;">
Screen 2
</div>
<div id="tab3" class="TabbedPanelsContent" style="display: none;">
Screen 3
</div>
</div>
</div>
My script that manipulates the styling is as follows:
function showTab(tabNumber) {
var children = document.getElementById('TabbedPanelsTabGroup').childNodes;
document.getElementById('tab'.concat(tabNumber)).style.display = 'block';
document.getElementById('list'.concat(tabNumber)).setAttribute("class", "TabbedPanelsTab TabbedPanelsTabSelected");
document.getElementById('anchor'.concat(tabNumber)).setAttribute("class", "TabbedPanelAnchor");
for(i=1; i <= children.length ; i++)
{
if(i != tabNumber){
document.getElementById('tab'.concat(i)).style.display = 'none';
document.getElementById('list'.concat(i)).setAttribute("class", "TabbedPanelsTab");
document.getElementById('anchor'.concat(i)).setAttribute("class", "");
}
}
}
I was wondering if my logic is right. I am concatenating the tab, list and anchor with the number and updating styles. But this does not seem to be working.

You appear to have at least two problems here.
First, you're trying to use document.getElementById for TabbedPanelsTabGroup, but that's a class.
Second, you're using .childNodes when you are probably looking for .children. .childNodes includes all child nodes, including the text inside the tags (which is a node). So when you use that number to loop over it, your loop isn't counting to 3 (your # of divs), it's counting to 7, and that's giving errors.
But, .children isn't supported before IE9, so like others have suggested, you may want to consider jQuery to get at that with better support.

With plain JavaScript I would recommend EventListener:
<div id="elem"> "some content here" </div>
var elem = document.getElementById('elem');
elem.addEventListener ('click', show, false);
function show() {
//add css Class
var element = document.getElementById("elem");
element.classList.add("activeTab");
}
But as mentioned in the comment, jQuery is perfect for that kind of things.
best
M

Related

How to show element only if other element contains something using jQuery?

My guess is what I want to achieve should be easy, but due to my lack of knowledge of front-end development, I cannot manage to solve issue. Have a page that works with AJAX-filters that users can select. Filters that are currently applied show up within <div> with id=current-filters.
HTML looks like this:
<div id="current-filters-box">
<div style="margin-bottom: 15px">
<strong>Current filters:</strong>
<div id="current-filters">
<!-- here every single applied filter is displayed -->
</div>
</div>
</div>
Need to hide the the entire DIV current-filters-box in case no filter is applied.
The page uses a Javascript file, bundle.js which is massive, but contains the following line:
s=document.getElementById("current-filters")
Therefore tried the following if-statement to hide the DIV:
if(s.length<1)$('#current-filters-box').hide()
and
if(s=0)$('#current-filters-box').hide()
But this does not seem to have any effect. Can someone tell, what I did wrong?
Demo of page can be found here
EDIT: this is what the HTML looks like when filters are applied:
<div id="current-filters-box">
<div style="margin-bottom: 15px">
<strong>Current filters:</strong>
<div id="current-filters">
<div class="badge-search-public">
<strong>Humanities & Languages</strong> <span class="x" data-property="disciplines" data-value="4" onclick="filter.removeFilter(this)">×</span>
</div>
<div class="badge-search-public">
<strong>January</strong> <span class="x" data-property="months" data-value="1" onclick="filter.removeFilter(this)">×</span>
</div>
</div>
</div>
Both of your conditions are incorrect or I would say they are not doing what you think they do.
s.length will always prints undefined so instead of s.length<1 you could use s.children.length
and the second one is not a condition rather it is an assignment
s==0 // condition
s=0 //assignment
the correct condition for your requirement would be
if(s.children.length<1){
I have assigned snippets for illustration.
Without filters
s = document.getElementById("current-filters")
console.log(s.children.length);
if (s.children.length < 1) {
$('#current-filters-box').hide(1000)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="current-filters-box">
filter box
<div style="margin-bottom: 15px">
<strong>Current filters:</strong>
<div id="current-filters">
<!-- here every single applied filter is displayed -->
</div>
</div>
</div>
Without filters
s = document.getElementById("current-filters")
console.log(s.children.length);
if (s.children.length < 1) {
$('#current-filters-box').hide(1000)
}
<div id="current-filters-box">
<div style="margin-bottom: 15px">
<strong>Current filters:</strong>
<div id="current-filters">
<div class="badge-search-public">
<strong>Humanities & Languages</strong> <span class="x" data-property="disciplines" data-value="4" onclick="filter.removeFilter(this)">×</span>
</div>
<div class="badge-search-public">
<strong>January</strong> <span class="x" data-property="months" data-value="1" onclick="filter.removeFilter(this)">×</span>
</div>
</div>
</div>
Try this .
if( $('#current-filters').is(':empty') ) {
$('#current-filters-box').hide()// or $('#current-filters-box').css("display","none")
}
You are performing an assignment, try..
if (s.children.length)
Using vanilla JavaScript, you can check if the current-filters div is empty or not and toggle the parent div current-filters-box like this:
s= document.getElementById("current-filters");
t= document.getElementById("current-filters-box");
if(s.children.length<1) {
t.style.display = 'none';
// t.style.visibility= 'hidden'; <<-- use this if you want the div to be hidden but maintain space
}
else {
t.style.display = 'block';
// t.style.visibility= 'visible'; <<-- use this if you used visibility in the if statement above
}
You can achieve this by adding your own variable which counts or maintains your applied filters, e.g.
var applied_filter_count = 0;
at every time filter is applied
applied_filter_count++;
if(applied_filter_count) {
$('#current-filters-box').show()
}
and at every time filter is removed
applied_filter_count--;
if(!applied_filter_count) {
$('#current-filters-box').hide()
}
and by default current-filters-box should be display:none

Change list-group-item from hidden to visible with JS

I have a list which contains of several items that are hidden.
In my JS i want a function that changes the items of this list so it becomes visible. I want each item to become visible if a certain event has happened. The event is working fine and can be considered as shakeCount= 6, to test it properly.
Here is my list:
<div class="container">
<div class="list-group">
<div id="s1">Shake1</div>
<div id="s2">Shake2</div>
<div id="s3">Shake3</div>
</div>
</div>
What i tried so far and didn't work:
function nR(){
if (shakeCount>5)
document.getElementbyId("s1").style.visibility ="visible";
}
Thanks in advance!
Have you tried using Toggle? I would recommend it but you may need to remove the "hidden" class from your elements and add in the style="display: none;" attribute to each in order to default them to hidden.
<div class="container">
<div class="list-group">
<div id="s1">Shake1</div>
<div id="s2">Shake2</div>
<div id="s3">Shake3</div>
</div>
</div>
function nR(){
if (shakeCount>5)
document.getElementbyId("s1").toggle();
}
First, you're using getElementbyId -- it should be getElementById (missing capital 'B').
Second, you've made the #shake links visibility:hidden, but you are targeting the wrapping div when you run your js.
var shakeCount = 6;
if (shakeCount>5)
document.getElementById("s1").style.visibility ="visible";
.hidden {visibility: hidden;}
<div class="container">
<div class="list-group">
<div id="s1" class="list-group-item hidden"><a href="#shake1" >Shake1</a></div>
<div id="s2" class="list-group-item hidden"><a href="#shake2" >Shake2</a></div>
<div id="s3" class="list-group-item hidden"><a href="#shake3" >Shake3</a></div>
</div>
</div>
The above code hides the wrapping div elements instead of the links so that they are shown when the js runs.

toggle pictures by hovering ul li

I need it to be a javascript solution only please. Please refer to this demo.
The goal is to hover the dots on the right bottom corner and swap the images accordingly. But what it does now is showing a blank page when hovering, and the whole ul becomes vertical and goes to top left corner. What did I do wrong here???
HTML:
<div id="wrapper">
<section id="contentWrapper">
<div id="resistorContent" class="content">
<section id="resistorDetail1"><img src="http://d3d71ba2asa5oz.cloudfront.net/40000483/images/pic1.jpg"></section>
<section id="resistorDetail2"><img src="http://d3d71ba2asa5oz.cloudfront.net/40000483/images/pic2.jpg"></section>
<section id="resistorDetail3"><img src="http://d3d71ba2asa5oz.cloudfront.net/40000483/images/pic3.jpg"></section>
<section id="resistorDetail4"><img src="http://d3d71ba2asa5oz.cloudfront.net/40000483/images/pic4.jpg"></section>
<ul>
<li onMouseOver="showDetail(resistorDetail1)"></li>
<li onMouseOver="showDetail(resistorDetail2)"></li>
<li onMouseOver="showDetail(resistorDetail3)"></li>
<li onMouseOver="showDetail(resistorDetail4)"></li>
</ul>
</div>
</section>
</div>
JAVASCRIPT:
<script type="text/javascript">
var children = document.querySelectorAll('.content > section[id]')
function showDetail(target){
for (var i = 0, child; child = children[i]; i++) {
child.style.display = 'none';
}
document.getElementById(target).style.display = 'block';
}
</script>
POSSIBLE COLLIDING CSS ?:
.content section:not(:first-child) {
display: none;
}
Thank you in advance!!
TL;DR
Here is the working fiddle: https://jsfiddle.net/2qz2srqs/3/
Reason
Your code was very close, but it had a few minor issues.
The first was a copy-paste error, you had two elements with the id of resistorDetail3.
Second, your syntax for the onmouseover event was incorrect. Prefix any javascript with javascript: and ensure it has proper syntax.
Third, your showDetail method expected a string id of the element to show. In your onmouseover declaration you had showDetail(resistorDetail1) instead of showDetail('resistorDetail1').
Finally, when you javascript is referenced in the HTML, you need to make sure you load the javascript first. Just by taking a look at the developer's console you could see that it through an error "showDetail is not defined.. I switched it to No wrap - in <body> and it worked fine.
BUT I highly recommend against directly referencing javascript from your HTML. Instead, load the HTML first and then use the DOM ready event of javascript to bind your events. That will increase your load time and make it easier to switch to something like jQuery/Zepto if needed.
Full Code
HTML
<section id="contentWrapper">
<div id="resistorContent" class="content">
<section id="resistorDetail1">
<img src="http://d3d71ba2asa5oz.cloudfront.net/40000483/images/pic1.jpg" />
</section>
<section id="resistorDetail2">
<img src="http://d3d71ba2asa5oz.cloudfront.net/40000483/images/pic2.jpg" />
</section>
<section id="resistorDetail3">
<img src="http://d3d71ba2asa5oz.cloudfront.net/40000483/images/pic3.jpg" />
</section>
<section id="resistorDetail4">
<img src="http://d3d71ba2asa5oz.cloudfront.net/40000483/images/pic4.jpg" />
</section>
<ul>
<li onmouseover="javascript: showDetail('resistorDetail1')"></li>
<li onmouseover="javascript: showDetail('resistorDetail2')"></li>
<li onmouseover="javascript: showDetail('resistorDetail3')"></li>
<li onmouseover="javascript: showDetail('resistorDetail4')"></li>
</ul>
</div>
</section>
JS
var children = document.querySelectorAll('.content > section[id]');
function showDetail(target) {
for (var i = 0, child; child = children[i]; i++) {
child.style.display = 'none';
}
document.getElementById(target).style.display = 'block';
}
CSS
(unchanged)
Here's another working fiddle.
https://jsfiddle.net/2qz2srqs/4/
The issue was a couple things.
You were passing undefined vars into your onmouseover attributes. You wanted strings (I quoted them)
In JSFiddle, you don't automatically get the window scope, so you have to assign a function as a property of a window if you want to be able to hit it with an event attribute.

mouseenter/leave & mouseover/out problems

Script:
$( ".title").mouseenter(function() {
var which = $(this).index();
$('.globalnav li').find('.dropdown').hide().eq(which).show();
}).mouseleave(function() {
var which = $(this).index();
$('.globalnav li').find('.dropdown').hide().eq(which).hide();
});
Navigation:
<ul class="globalnav">
<li>
<div class="title">Home</div>
<div class="dropdown">
<div class="navlinks">
<div class="linkstitle">Title</div>
<div class="navlink">Link1</div>
<div class="navlink">Link1</div>
</div>
</div>
</li>
...
The above code is what I am using right now which does not work in Chrome as intended *I need to hold my click down to view the div. I use mouseover, it does not work properly in IE and FF.
I am also having trouble showing the associated div of the title (on title hover, show specific div) due to the nature of the coding format itself (client given code). Right now, on hovering over a title, it shows the first li's content for "navlinks".
Here's a fiddle to show you
Thanks
Why are you using the index of the .title element, if the other LI's look like that, the which variable will always be 0, and it's not the way to target the right .dropdown ?
Try something more like this
$( ".title").on('mouseenter mouseleave', function(e) {
var dropdown = $(this).closest('li').find('.dropdown').toggle(e.type=='mouseenter');
$('.dropdown').not(dropdown).hide();
});
And if you want the dropdown to be visible while hovering it, place it inside the element that triggers the mouseleave
<li>
<div class="title">
Home
<div class="dropdown">
<div class="navlinks">
<div class="linkstitle">Title</div>
<div class="navlink">Link1</div>
<div class="navlink">Link1</div>
</div>
</div>
</div>
</li>
FIDDLE

How to access the dom by knowing the value of a node && Getting the index of accordion by just knowing value

I have 2 questions:
1) Since I have similar structure for the html contents and the only difference is that class title contents are different. I tried using $(div .title:contains("cat")) also
$(div .title).text()="cat")
2)How can I get the index of the accordion by just checking the $(div a) contents are required ones. I tried using $(div a).text()=="cat"
Check the codes here:
HTML1 contents
<div class="mod moduleselected" id="mod969">
<div class="content module moduleselect">
<div class="hd" ><div class="inner">
<div class="title">cat</div>
<ul class="terminallist"></ul>
<ul class="buttons">
<li class="help"></li>
<li class="show" ></li>
</ul>
</div>
</div>
</div>
<div class="mod moduleselected" id="mod969">
<div class="content module moduleselect">
<div class="hd" ><div class="inner">
<div class="title">rat</div>
<ul class="terminallist"></ul>
<ul class="buttons">
<li class="help"></li>
<li class="show" ></li>
</ul>
</div>
</div>
</div>
<div class="mod moduleselected" id="mod969">
<div class="content module moduleselect">
<div class="hd" ><div class="inner">
<div class="title">dog</div>
<ul class="terminallist"></ul>
<ul class="buttons">
<li class="help"></li>
<li class="show" ></li>
</ul>
</div>
</div>
</div>
Accordian
<div id="dia">
<div id="dialog" title="Detailed FeedBack ">
<div id="accordion">
<h3>dog</h3>
<h3>cat</h3>
<h3>rat</h3>
</div>
</div>
</div>
Javascript
$('div .title').mouseover(function() {
if($("div a").text().indexOf("cat")!=-1)
{
$("#accordion").accordion("activate", 1);
}
$('div .title').mouseleave(function(){$("#accordion").accordion("activate", -1); });
});
Here is what I am trying to do with this javascript code. When I mouse over the cat contents I want the accordion with cat contents to open. And when I leave it to close the accordion selection.
When I hover my mouse over the html contents cat ,rat. It should side by side open the accordion button of those contents. Example: I hovered over rat (of html contents) I should see accordion rat open (or active i.e. contents visible).
Updated (see demo)
It sounds like you want something like this: when a content section is hovered over, find the title of that section, match its text against the text of the <a> elements in the accordion, and activate that section:
$(function() {
$("#accordion").accordion();
var links = $('#accordion a').map(function() {
return $(this).text().trim().toLowerCase();
}).toArray();
$('div.content').mouseover(function() {
var title = $(this).find('div.title').text().toLowerCase();
var index = links.indexOf(title);
if (index != -1) {
$("#accordion").accordion("activate", index);
}
});
});​
P.S. jQuery does have a .hover() method for this as well.
It should be as succinct as the following (with potential minor tweaks):
$('.content .title').hover(function(e){
var index = this.textContent.split(/\W/)[1] - 1;
$("#accordion").accordion('activate', index);
});
​
Be careful with the HTML as this regular expression is overly simple in that it just grabs the last "word" which in the case of your example is a number. We subtract one to get a zero-based index. That will break if you add further text to the element.
See: http://jsfiddle.net/35yGV/

Categories

Resources