Show content only from the clicked link and hide all siblings - javascript

as stated in the name, i have a menu with links, and i have a list of sections which i want to show/hide on the click of the menu.
What i want here is to be dynamic in a sense that if i add more menus and sections I don't have to change the code that does it, or to add new tags or names.
I tried doing something myself but I'm probably missing something..
Any assistance would be appriciated
I have a simple example on this jfiddle: https://jsfiddle.net/s07ysx6w/6/
HTML:
<div id="header">
<div id="menuBlock">
<ul id="menu">
<li>Novosti</li>
<li>Program Mladi</li>
<li>Program Odrasli</li>
<li>Program Upisi</li>
<li>Galerija</li>
<li>Kontakt</li>
</ul>
</div>
</div>
<body>
<div id="main">
<div id="novosti" name="sekcija1" class="sekcija">
aaaa
</div>
<div id="programMladi" name="sekcija2" class="sekcija">
aaaa
</div>
<div id="programOdrasli" name="sekcija3" class="sekcija">
aaaa
</div>
<div id="programUpisi" name="sekcija4" class="sekcija">
aaa
</div>
<div id="galerija" name="sekcija5" class="sekcija">
aaaa
</div>
<div id="kontakt" name="sekcija6" class="sekcija">
aaa
</div>
</div>
</body>
Javascript:
$(document).ready(function() {
$("#menu").click(function(e) {
var selected = this.attr('href');
$('#main' + selected).show('slow').siblings().hide('slow');
});
});
EDITED:
Copy/pasting made me careless so now there are only unique id's. Also replaced the fiddle with a working one (solution).
UPDATE:
In case anyone uses slicknav as a plugin on his/her's page, to get to the element you have in your menu you need to find how exactly slicknav injected it into your page. For instance, in my case, since i prepend it to my #menuBlock div tag. In order to find the element #novosti i had to dig in deep, since slicknav creates tags on its own in order to work the way it does.
In that case my javascript looked like this.
$(document).ready(function(){
$("#menuBlock div ul li a").click(function (e){
e.preventDefault();
var selected = $(this).attr('href');
$( selected ).fadeIn('slow').siblings().hide();
});
});

There should a space between 2 selectors if they have a parent child relationship, so change this line
$('#main' + selected).show('slow').siblings().hide('slow');
to
$('#main ' + selected).show('slow').siblings().hide('slow');
or simply the selected one (since it is already pointing to a specific element)
$(selected).show('slow').siblings().hide('slow');
check this updated fiddle
$(document).ready(function(){
$("#menu li a").click(function (e){ //bind the event on `a` rather than ul
var selected = $(this).attr('href'); //use $(this) instead of this
$( selected ).show('slow').siblings().hide('slow'); //explained above
});
});

There are more than one errors found in your code,
set a Jquery library
Id should be unique throughout the DOM
Replace this.attr with $(this).attr()
Descendant selector would be #menu #something not #menu#something
Should .stop() an animation before beginning the new one.
Try,
$(document).ready(function() {
$("#menu li a").click(function(e) {
e.preventDefault()
var selected = $(this).attr('href');
$('#main ' + selected).stop().show('slow').siblings().hide('slow');
});
});
DEMO

Try this method
$(document).ready(function() {
$("#menu a").click(function(e) {
debugger;
var selected = $(this).attr('name');
$('#main div').hide();
$('#main div[name="'+selected+'"]').show('slow');
});
});

You are not supposed to have more than one element with the same ID on a page, so change the id on the page to something more specific. Or I'm I mistaken? From your question, you wanted something more extensible, here is an approach
$(document).ready(function(){
$("#menu").click(function (e){
var element = $(e.target).attr('href');
$('#main-divs > ' + element).show('slow').siblings().hide('slow');
});
});

Related

jQuery : Get content of id

Need some help with jQuery DOM.
I need to extract the content of the id. I have a list that user can select and it will filter the hotspot of the map. After user select, I want filtertitle to display the new selected filter. I can apply the "id" to the filter title but not sure about the content because the content has Shopping / Dining. Someone please.
HTML
<div class="map-filter">
<div class="filtertitle">All Categories</div>
<ul class="filter-list">
<li class="active" id="All Categories">All Categories</li>
<li id="Shopping">Shopping/Dining</li>
<li id="Hotel">Hotels & Resorts</li>
<li id="Art">Art Galleries</li>
</ul>
</div>
jQuery
$('.filter-list li').click(function(){
var id = $(this).attr('id');
$(this).siblings().removeClass('active');
$(this).addClass('active');
$('.filtertitle').html(id); //This part is where I set the id
});
Use .text(), it gives you the text content of the desired element.
$('.filtertitle').html($(this).text());
In case of html content use .html().
$('.filtertitle').html($(this).html());
If I'm understanding what you're asking correctly then you can try something like this.
$('.filter-list li').click(function(e){
$(this).siblings().removeClass('active');
$(this).addClass('active');
$('.filtertitle').html($(e.currentTarget).text());
});
JSFiddle - https://jsfiddle.net/583zgs57/
Instead of simple setting id, you can use $(this).text(); to fetch the text content of current element.
$('.filter-list li').click(function(){
var id = $(this).attr('id');
$(this).siblings().removeClass('active');
$(this).addClass('active');
$('.filtertitle').html($(this).text());
});

If This is Clicked Show This Else Hide This

I have seen other if else examples on here but nothing specifically addressing jquery "if clicked show this else hide this". Here's a simple code example. I would like to know the cleanest way to show the .redStuff when #red is clicked else hide it and show the other classes when the relative id is clicked.
Here is the HTML:
.redStuff, .blueStuff, .greenStuff {
display: none;
}
<ul id="color">
<li id="red">Red</li>
<li id="blue">Blue</li>
<li id="green">Green</li>
</ul>
<div class="redStuff">Red Stuff</div>
<div class="blueStuff">Blue Stuff</div>
<div class="greenStuff">Green Stuff</div>
Using data attributes is easy once you get the idea.
css
.redStuff, .blueStuff, .greenStuff {
display: none;
}
html
<ul id="color">
<li id="red" data-color="red">Red</li>
<li id="blue" data-color="blue">Blue</li>
<li id="green" data-color="green">Green</li>
</ul>
<div class="redStuff" data-content="red">Red Stuff</div>
<div class="blueStuff" data-content="blue">Blue Stuff</div>
<div class="greenStuff" data-content="green">Green Stuff</div>
jquery
// no need for the ids or classes
// we set data attributes for the html
$("li[data-color]").click(function(){
// next line is for second click, to hide the prev div element
$("div[data-content]").hide();
// we are getting the data-color attr value here
// and for readibility we assigned it to a variable called color
var color = $(this).data("color");
// find the div with the same content and show
$("div[data-content='"+color+"']").show();
});
jsfiddle link to play with codes
This should work.
It's not an "If Then Else" statement exactly, but it accomplishes the logical objective.
var $stuff = $(".redStuff, .blueStuff, .greenStuff");
var $colors = $("#color li a");
$colors.on("click", function(){
// get color from parent (li) id
var color = $(this).parent()[0].id;
// turn all stuff off (because we don't know what came last)
$stuff.attr({style: null});
// turn on clicked stuff class
$("." + color + "Stuff").attr({style: "display:block;"});
});
Demo is here.
Numerous ways to approach this depending on complexity of the layout.
If the order is the same relationship between the <li>'s and the <div> you can use index(). Adding a common class would be helpful
<div class="redStuff stuff">Red Stuff</div>
JS
$('#color li').click(function(){
// "this" is the element event occurred on
var index = $(this).index();
// hide all the "stuff" class and show the matching indexed one
$('.stuff').hide().eq(index).show();
});
Or add data- attributes to target specific element so that index order becomes irrelevant
HTML
<li id="red">Red</li>
JS
$('#color a').click(function(){
$('.stuff').hide().filter( $(this).data('target') ).show();
});
Or by using ID to create a selector
$('#color li').click(function(){
$('.stuff').hide().filter('.' + this.id +'Stuff').show();
});

how to economize jquery selectors

Probably a stupid question, but I couldn't find a direct answer, so how can I change ":not('#home div, .nav')" in to something like ":not('this div, .nav')"? That would allow me reuse the same function for different objects.
$( "#home" ).click(function() {
$("#content .plates").children(":not('#home div, .nav')" ).fadeOut(700);
});
and here is the HTML if needed:
<div id="wrapper">
<div id="content">
<div id="home" class="plates">
<div class="nav"></div>
<div id="one"></div>
<div id="two"></div>
</div>
<div id="about" class="plates">
<div class="nav"></div>
<div id="three"></div>
<div id="four"></div>
</div>
</div>
</div>
Thanks for your help!
In the handler, this will be the clicked element, so you could just use this:
$( "#home" ).click(function() {
$("#wrapper #content .plates").children(":not('#"+this.id+" div, .nav')" ).fadeOut(700);
});
The OP is asking for something generic that can be reused on both the "home" and the "about" divs (and maybe on others to be added later?). But, for each one, excluding the "nav" item from the fadeout. So try this:
function myFunc( clickableItem) {
$(".plates:not(" + clickableItem + ")").children( ":not('.nav')" ).fadeOut(700); }
$( "#home" ).click( function(){
myFunc( "#home");
});
$( "#about" ).click( function(){
myFunc("#about");
});
You are using CSS selector :not(), but you can also use jQuery chained function .not(), which subtracts matched elements from another set of matched elements.
The usage is like this:
$(selector1).not(selector2).fadeOut(700);
Where elements in selector2 will get substracted from set matched by selector1.
Let's start from the top. Provided you follow the spec and IDs are unique on your page (as they should be), your click event selector should be just
$("#home").click(function() {...});
Also, the inner selector should be
$("#content .plates").children(...);
There's no need to stack ID selectors in front of other ID selectors since IDs should be unique and selectors are parsed from right to left.
You can use jQuery not to exclude the clicked element.
Code:
$("#wrapper #content #home").click(function () {
$("#wrapper #content .plates").children(':not(.nav)').not($(this)).fadeOut(700);
});
Demo: http://jsfiddle.net/IrvinDominin/dms6u1ww/
$("#wrapper #content #home" ).click(function() {
$("#wrapper #content .plates").children().not($('div', this)).not('.nav').fadeOut(700);
});

JQuery : Remove class, not child content

I use jQuery to append the content into each contentx class like.
<div id="sidebar">
<div class="contentx"></div>
<div class="contentx"></div>
</div>
<script>
$("#sidebar .contentx").each(function()
{
//Append here
}
</script>
After Append I have, for example :
<div id="sidebar">
<div class="contentx">
something 1 is inserted here.
</div>
<div class="contentx">
something 2 is inserted here.
</div>
</div>
but I want to remove class="contentx" whenever the content is appended. This mean I have only :
<div id="sidebar">
something 1 is inserted here.
something 2 is inserted here.
</div>
How
Option 1
If you just want to remove the class "contentX" from the div after the content has been added, you can try the following:
$('#sidebar .contextX').each(function () {
// Append here.
}).removeClass('contextX');
EDIT: Seems I misread the question a little (based on your indicated desired output).
Option 2
If you want to remove the entire element and replace it with the content of your choice? For that, you can try:
$('#sidebar .contextX').each(function () {
$(this).replaceWith('<new content here.>');
});
jQuery replaceWith
Besides the append, call removeClass
$("#sidebar .contentx").each(function()
{
//Append here
$(this).removeClass('contentx');
}
Try this
var tmp = $(".contentx").html();
$('.contentx').append(tmp);
var tmp2 = $(".contentx").html();
$('.contentx').remove();
$('#sidebar').append(tmp2);

jQuery Fancy Toggle Not Working

I have a set of links that I'm trying to conceal inside a toggle , but my code below is not doing it . Please what have I done wrong.
Thank you.
<script>
$("#navigation li a[id]").click(function()) {
$("#" + this.id.substr(1)).slideToggle(600).siblings('.toggleDiv').slideUp(600);
});
</script>
<div id="search" class="toggleDiv" style="display:none">List</div>
<div id="sidebar">
<ul>
<li>President</li>
<li>Vice</li>
<li>Secretary</li>
</ul>
</div>
Brackets in jQuery are for attributes.
a[id] will not work because those a tags don't have an id attribute. You also don't have a #navigation div.
Try $("#sidebar ul li a")
You have missed a ).
$("#" + this.id.substr(1))
// ----^
However your selector doesn't select the anchor elements as they don't have ID attributes and this.id is undefined. It seems you want to get the id parameter of href attribute.
$("#sidebar li a").click(function()) {
$("#"+this.href.slice(-1)).slideToggle(600).siblings('.toggleDiv').slideUp(600);
});

Categories

Resources