I need to show/hide multiple elements with the same name when another element is clicked, like
<span name="showhide" value="one" id="button">Click to Hide One</span>
<span name="showhide" value="two" id="button">Click to Hide Two</span>
<span name="showhide" value="shoe" id="button">Click to Hide shoe</span>
would hide the elements with the corresponding value when clicked
<span name="showhide" value="one">One</span>
<span name="showhide" value="two">Two</span>
<span name="showhide" value="shoe">shoe</span>
Also, onclick='' can't be used in the HTML, it has to go in the script. Can't apply any attributes to a tags other than href too (this is for a MediaWiki)
I've tried a bunch of different methods but I can't seem to get it to work, does anybody have any suggestions?
The markup's not valid: there's no such attribute as <span name> or <span value>, and you can't have multiple elements with the same id. All this is likely to confuse any attempts you make to fetch the elements by name or id. Use a class instead, and since what you've got is links to other parts of the page it would seem sensible to mark them up as internal links. You can always style them not to look like links using CSS.
<a class="showhide" href="#one">Click to hide one</a>
<a class="showhide" href="#two">Click to hide two</a>
<div id="one">One</div>
<div id="two">Two</div>
<script type="text/javascript">
for (var i= document.links.length; i-->0;) {
var link= document.links[i];
if (link.className=='showhide') {
var div= document.getElementById(link.hash.substring(1));
Toggler(link, div, true);
}
}
function Toggler(toggler, togglee, state) {
toggler.onclick= function() {
state= !state;
togglee.style.display= state? 'block' : 'none';
return false;
}
}
</script>
On page load, first add an event to all the elements with that name to toggle hide/show. When an element is clicked, loop through all the elements and change their style to display:none or display:block depending on the current state. To identify the current state you can either find the display attribute value or add/delete a class.
Related
I frequently create web apps that use traditional tabs at the top of the page. When doing this, I have a common problem I have been unable to find an elegant solution to.
The problem is the user can load the same content in two separate tabs on the same page. Any HTML ID's on these two different tabs then conflict, causing any JavaScript referencing one of those ID's to fail on the second tab. In addition, any JavaScript referencing a class on one of these pages will affect elements on all tabs, when I really only want it to affect the current tab.
For example, what if I included this block of code twice in the same page?
<style>
#container { margin; 20px; }
#message { background: red; }
</style>
<div id='container'>
<span id='message'>This was from an include file</span>
<button id='changeColorBtn'>Change color</button>
</div>
<script>
$('#changeColorBtn').click(() => $('#message').css('background', 'blue'))
</script>
JSFIDDLE to illustrate the problem: https://jsfiddle.net/dillydadally/2njcq9py/
I have tried or considered three approaches to solve this in the past:
I tried appending a page id to every element in the included content using PHP. This become messy quick and annoying to write out.
I tried making each tab an iframe. At first, this seemed to work well, but quickly became a management nightmare having that many iframes open on the same page that sometimes needed to communicate with each other and share data. I ran into multiple issues and decided not to attempt this approach again.
I considered wrapping each instance of included content in a single element with a unique ID, but I decided I would run into similar issues as option 1 above. Every CSS selector would have to have that element with the ID first, yet again creating messy code and possibly slowing the page down with numerous multi-depth JQuery selectors. In addition, there would still be multiple elements with the same ID on the same page (although I'm not sure that would matter since every selector should have a parent element included).
Is there an element or approach created to address this problem already in HTML/CSS that I'm missing?
You must use a class instead of an ID on an element with the same styling used more than once that you wish to affect with the same css style rule in your document.
For example:
<div id="main"><!-- / The main ID is only used once in the document / -->
<p class="par">
Here is the first paragraph with the same style as the second
</p>
<p class="par">
Here is the second paragraph with the same style as the first
</p>
</div>
Now to your issue of affecting the same type of element used multiple times in your document...
Because you have both the span (message) and button together as a pair under the same parent element, you can access the index of a loop within an event listener to identify the one being pressed using the nodelist being selected.
I use vanilla JS querySelectorAll() on the node list. You must use classes for multiple elements of the same tag name.
I targeted the elements parent class let message = document.querySelectorAll('.content span') and let btn= document.querySelectorAll('.content button'). Then you run the nodes through a forEach loop and add an eventlistener to the button element using the index in the forEach loop. Though this index is the index for the btn element, because these are paired up it will target the correct message element using the index from the btn.
let btn = document.querySelectorAll('.container button');
let message = document.querySelectorAll('.container span');
btn.forEach((button, i) => {
// in short....
// each time the loop iterates the nodelist of btn, it assigns the keyword
// `button` to that iteration of the elements nodelist, so when we click a specific
// `button` it refers to the button being pressed at that time and not all of them
button.addEventListener('click', (e) => {
message[i].style.backgroundColor = 'blue';
})
})
.container span {
background: red;
}
<div id='tab1'>
<div class='container'>
<span>This was from an include file</span>
<button>Change color</button>
</div>
</div>
<div id='tab2'>
<div class='container'>
<span>This was from an include file</span>
<button>Change color</button>
</div>
</div>
Using Jquery: Use $.each to run the list through a loop and use $(this) on a click event and target the elements previous sibling which is the grouped pair within the parents span tag (message).
let btn = $('.container button');
let message = $('.container span');
$.each((btn), function(){
$(this).click(function(){
$(this).prev().css("background-color", "blue")
})
})
.container span {
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='tab1'>
<div class='container'>
<span>This was from an include file</span>
<button>Change color</button>
</div>
</div>
<div id='tab2'>
<div class='container'>
<span>This was from an include file</span>
<button>Change color</button>
</div>
</div>
I'm trying to pull a toggleClass() on a class from an id element, e.g:
$('#create a').click(function(){
$('#create div').toggleClass('active');
});
and it doesn't wanna toggle the class active on the divider.
Here is the button:
<a href="#create" id="create" data-toggle="tab">
<i class="fa fa-plus" aria-hidden="true"></i>
</a>
and here is the class I'm trying to toggle active on:
<div class="" id="create">
<!-- Content Here -->
</div>
You have two issues here. Firstly #create a won't match any elements as the a element has that id, not a child element of it. You could instead use a#create or just #create.
Secondly you've duplicated the create id on both the a and the div, when id attributes must be unique within a page. You need to use another id value to identify the div element.
With those issues in mind, try this:
$('#create').click(function(){
$('#content').toggleClass('active');
});
.active { color: red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#create" id="create" data-toggle="tab">
<i class="fa fa-plus" aria-hidden="true">+</i>
</a>
<div class="" id="content">
Content here...
</div>
First, you should not have the same ID for more than one element.
Second, selectors don't work like you think: $('#create a') means "all A elements inside the element with the id = create". Just use $('#create'). You could use $('a#create'), which means "the A element with id = create", but that's unneccessary since id should always be unique.
Make sure you give a unique ids in your DOM.
And then your selectors are wrong.
They should be
$('#create').click(function(){
$('#creatediv').toggleClass('active'); // given new id to div
});
There is no need to mention the div as you have id in hand.
I am dynamically assigning the div id based on the api call back data. For example I have a bunch of data returned which is appended to a div and I can assign the div id with a unique ip address. I have full control over what I can assign i.e. DIV id or class or whatever..
I have attached an example of what the output looks like and hopefully it will clarify what i am looking for.
What I want to be able to achieve is when an endpoint link is clicked, it will show the respective div and hide all other DIV data boxes.. The endpoint links can made clickable and i can add onclick scripts to them or whatever needs to be done
Whether we use the div id or class name i am not fussed.
This should work just fine.
Assign your div with a class, in the demo i'm using EndPoint. The onclick function will use the class to find the div element and hide it. Then it will use this the element used to trigger the function, target the div within that element and show it.
$('.EndPoint').on('click', function () {
$('.EndPoint').find('div').hide();
$(this).find('div').show();
});
.EndPoint div{display:none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="EndPoint">
End Point [0]
<div><b>IP Address:</b> 216.12.145.20</div>
</div>
<div class="EndPoint">
End Point [1]
<div><b>IP Address:</b> 172.230.105.123</div>
</div>
<div class="EndPoint">
End Point [2]
<div><b>IP Address:</b> 206.204.52.31</div>
</div>
If you don't understand anything please leave a comment below and I will get back to you as soon as possible.
Edit - jQuery Append with onclick
var IPs=["216.12.145.20","172.230.105.123","206.204.52.31"];
//Foreach value in array
$.each(IPs, function(i,v) {
//Append to id:container
$('#container').append('<div class="EndPoint">End Point ['+i+']<div><b>IP Address:</b> '+v+'</div></div>');
});
$('.EndPoint').on('click', function () {
$('.EndPoint').find('div').hide();
$(this).find('div').show();
});
.EndPoint div{display:none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container"></div>
I hope this helps. Happy coding!
Since elements are dynamically generated it's better to do with classes IMO.
HTML
<div id="endpoint1">
<a href='#' class='clicker'>End Point 1</a>
<p class='hideThis'>1.1.1.1</p>
</div>
<div id="endpoint2">
<a href='#' class='clicker'>End Point 2</a>
<p class='hideThis'>1.1.1.1</p>
</div>
<div id="endpoint3">
<a href='#' class='clicker'>End Point 3</a>
<p class='hideThis'>1.1.1.1</p>
</div>
JavaScript (using JQuery)
$('.clicker').on('click', function () {
$('.hideThis').hide();
$(this).next().show();
});
http://jsfiddle.net/ksvexr40/1
If you want to hide the content initially, just add the following CSS class which hides the content initially.
.hideThis{
display: none;
}
I'm having an issue with using Jquery toggle on a feed. I have a hyperlink called Tags. When i click on this it toggles a div underneath it.
It works - But only for the top post in the feed - If I have any other posts in the feed it doesn't work.
Below Is Jquery:-
<script type="text/javascript">
$(function () {
$("#hypfeedTagBtn").click(function() {
$("#divPostBodyTags").toggle();
return false;
});
});
</script>
Below is HTML:-
<div id="divPostFoot_64" class="dPostMain dPostFoot">
<span id="Content_ucFeeds_repFeedThread_lblFeedViewCouont_0" class="spFootReplyCount"></span>
<span id="Content_ucFeeds_repFeedThread_lblFeedShareLink_0" class="spFootLinks"></span>
<span id="Content_ucFeeds_repFeedThread_lblFeedDeleteLink_0" class="spFootLinks"></span>
<a id="hypfeedTagBtn" class="spFootLinksShowTags">Tags</a>
<a id="Content_ucFeeds_repFeedThread_hypFeedMessageMe_0" class="spFootLinks" href="/Mail/NewMessage.aspx?FeedID=64">Message Me</a>
</div>
<div id="divPostBodyTags" class="dPostMain dPostTAGSDIV" style="display: block;">
<ul id="PostBodyTags">
<li class="TAGLiItem">
<a class="TAGaItem">Plumbers</a>
</li>
<li class="TAGLiItem">
<a class="TAGaItem">Plumbers</a>
</li>
</ul>
</div>
Thanks
Steve
MDN element.id
The ID must be unique in a document, and is often used to retrieve the
element using document.getElementById.
In some documents (in particular, HTML, XUL, and SVG), the id of an
element can be specified as an attribute on the element like so: .
However you can't use this attribute in a custom XML document without
correctly specifying the type of the id attribute in the DOCTYPE.
Other common usages of id include using the element's ID as a selector
when styling the document with CSS.
Note that IDs are case-sensitive, but you should not create IDs that
differ only in the capitalization (see Case Sensitivity in class and
id Names).
Use a class instead of an id if you want to toggle more than one section.
I'm using jQuery Mobile which creates a lot of the DOM for you. I need to remove() radio buttons, but based on how the HTML is constructed in jQuery Mobile, I do not have an id for the parent div. I can easily grab both the input and labels, but need to also get rid of the our div to completely removed the entry styling from the list of radio buttons.
<div class="ui-radio">
<input type="radio" value="ahBkMj" id="ahBkMj" name="spam" data-theme="c">
<label for="ahBkMj" class="ui-btn ui-btn-icon-left ui-btn-up-c">
<span class="ui-btn-inner">
<span class="ui-btn-text">Foo</span>
<span class="ui-icon ui-icon-ui-icon-radio-off ui-icon-radio-off"></span>
</span>
</label>
</div>
Will jQuery's .parent() do ?
Since the <div> element is the immediate parent of your <input> element, you can use the aptly-named parent() method:
$("#ahBkMj").parent().remove();
In the general case, if you want the first ancestor matching a selector, you can use closest():
$("#ahBkMj").closest("div").remove();
Note, however, that closest() includes the element itself in its search.
this works for me.....
var child = '# or . and name of your child div... ';
var width = Math.round($(child).parent().width());