I am trying to toggle an image when a class is clicked. So far I have this (below) and it works to change my 'plus.png' to my 'minus.png' but I need it to change back to my 'plus.png' if the class is clicked again.
I have the following jQuery:
<script type="text/javascript">
$(document).ready(function () {
$('label.tree-toggler, .yellow').click(function () {
$(this).parent().children('.yellow').attr('src', 'img/minus.png');
});
});
</script>
HTML
<li><label class="tree-toggler nav-header">Saftey and Emissions</label><img class="yellow" src="img/plus.png"><hr></hr>
<ul class="nav nav-list tree">
<li>link<img class="yellow" src="img/chevron-right.png"><hr></hr></li>
<li>link<img class="yellow" src="img/chevron-right.png"><hr></hr></li>
</ul>
</li>
Is someone could help me out by adding to what I have, it would greatly be appreciated!
You can add/remove a class to keep track of which image src you are using. Something like this:
$('label.tree-toggler, .yellow').click(function () {
if ( $(this).parent().children('.yellow').hasClass('minus') ) {
$(this).parent().children('.yellow').attr('src', 'img/plus.png').removeClass('minus');
} else {
$(this).parent().children('.yellow').attr('src', 'img/minus.png').addClass('minus');
}
});
You could also use a data attribute and do something similar:
$('label.tree-toggler, .yellow').click(function () {
if ( $(this).parent().children('.yellow').data('current_src') == 'minus') {
$(this).parent().children('.yellow').attr('src', 'img/plus.png').data('current_src', 'plus');
} else {
$(this).parent().children('.yellow').attr('src', 'img/minus.png').data('current_src', 'minus');
}
});
Using the data attribute would require initially setting data-current_src='minus' on the element.
the way i will do it is...
$(document).ready(
function() {
$(".className").click(
var imgPath = $("img").attr('src');
if(imgPath === "+.png") { // check against current path
// change the path to -
} else {
// change the path to +
}
); } );
i didn't test it, but that's the idea
I would recommend adding another class like .active or .shown through JQuery when you switch the image around. That way you could check the current state of the object you're querying.
The Jquery would probably look something like
$('label.tree-toggler, .yellow').click(function () {
// If the active class is NOT applied
if( !( $(this).parent().children('.yellow').hasClass('active') ) ) {
// Apply it and change the image
$(this).parent().children('.yellow').addClass('active').attr('src','img/minus.png');
}
else
$(this).parent().children('.yellow').removeClass('active').attr('src', 'img/plus.png');
});
What's happening here is the active class is being used to determine the state of the image displayed. When you click it, you'll change the image and apply the flag.
After every click the flag is checked and behaves accordingly. Hope that helps! I'm still new to S.O. =.="
If you want to do it in JS, I suggest you to put :
your initial image in src
your alternative image in data-alternative
Like this :
<li>
<label class="tree-toggler nav-header">Saftey and Emissions</label>
<img class="yellow" src="img/plus.png" data-alternative="img/minus.png"><hr></hr>
<ul class="nav nav-list tree">
<li>link<img class="yellow" src="img/chevron-right.png"><hr></hr></li>
<li>link<img class="yellow" src="img/chevron-right.png"><hr></hr></li>
</ul>
</li>
And the JS :
<script type="text/javascript">
$(document).ready(function () {
$('label.tree-toggler, .yellow').click(function () {
var yellow = $(this).parent().children('.yellow').first();
var alternative = yellow.data('alternative');
yellow.data('alternative', yellow.attr('src'))
.attr('src', alternative );
});
});
</script>
Did you see the toggle function of Jquery?
http://api.jquery.com/toggle/
Related
I have a fairly simple .addClass(open) function in jQuery, but am having trouble passing the right variables.
I have these two buttons in a sidebar:
<ul>
<li class="dashButton active" id="#1"><?php the_field('sidebar_text_0'); ?></li>
<li class="dashButton" id="#2"><?php the_field('sidebar_text_1'); ?></li>
</ul>
And then two divs that should open in eachother's place when it's button is clicked. mainDashWrap relates to id=#1 and editProfile relates to id=#2.
<div class="mainDashWrap dashView open">
...... content .....
</div>
<div class="editProfile dashView">
...... content .....
</div>
And my jQuery adds and removes the open class, which has display:none if there is no open class and display:block if it does have the open class.
My problem is with the //Get the attr2 part below. I don't think it's properly setting the class so that it's formatted to go into the $(newSect).slideDown() function.
$('.dashButton').click(function() {
//Switch active Tab Buttons and close the Menu.
$('.dashButton.active').removeClass('active');
$(this).addClass('active');
$('.dashView.open').removeClass('open');
//Get the attr2
if ( this.id == '#1') {
var attr2 = '.mainDashWrap';
}
else { var attr2 = '.editProfile' }
switchDashViews(attr2);
});
function switchDashViews(newSect) {
//close active section
$('.dashView.open').slideUp('2000', function() {
$('.dashView.open').removeClass('open');
$(newSect).slideDown('2000', function() {
$(newSect).addClass('open');
});
});
};
This will add and remove the open class and hide the dashview that doesn't have the open class, but it will not add the open class to newSect or slide down newSect. How can I get attr2/newsect to set properly?
I suppose you first removed all .open in click event
$('.dashView.open').removeClass('open');
and only after that trying to slide up this elements in switchDashViews function
$('.dashView.open').slideUp('2000'...
But .open are already deleted
Upd. try not to use var keywords in this block
if ( this.id == '#1') {
var attr2 = '.mainDashWrap';
}
else { var attr2 = '.editProfile' }
because attr2 can be out of scope. Just
if ( this.id == '#1') {
attr2 = '.mainDashWrap';
}
else { attr2 = '.editProfile' }
Remove # from your id in your HTML, it is not a allowed character in id, (Imagine what selector will look like $(##1), pretty bad, huh?).
Add a data-attribute so that you can get rid of if() .. else() ...
HTML
<ul>
<li class="dashButton active" data-class=".mainDashWrap" id="1"><?php the_field('sidebar_text_0'); ?></li>
<li class="dashButton" data-class=".editProfile" id="2"><?php the_field('sidebar_text_1'); ?></li>
</ul>
jQuery
$('.dashButton').click(function() {
//Switch active Tab Buttons and close the Menu.
$('.dashButton.active').removeClass('active');
$(this).addClass('active');
$('.dashView.open').removeClass('open');
// Do this
var attr2 = $(this).data("class");
/* Or you can do this
if ( this.id == '1') {
var attr2 = '.mainDashWrap';
}
else { var attr2 = '.editProfile' }
*/
switchDashViews(attr2);
});
function switchDashViews(newSect) {
//close active section
$('.dashView.open').slideUp('2000', function() {
$('.dashView.open').removeClass('open');
$(newSect).slideDown('2000', function() {
$(newSect).addClass('open');
});
});
};
Make sense?
Don't include # in the ID. While it's legal in modern browsers, it's confusing and will make it difficult to access the element using jQuery or CSS selectors. Instead use
<li class="dashButton active" id="1">
Then change the if to match this:
if (this.id = "1")
I also suggest you use more meaningful IDs than just numbers.
this can be different depending on the function scope, try to use event.target instead so this.id would be event.target.id.
See your example of your code with changes:
$('.dashButton').click(function(event) {
//Switch active Tab Buttons and close the Menu.
$('.dashButton.active').removeClass('active');
$(this).addClass('active');
$('.dashView.open').removeClass('open');
//Get the attr2
if ( event.target.id == '#1') {
var attr2 = '.mainDashWrap';
}
else { var attr2 = '.editProfile' }
switchDashViews(attr2);
});
function switchDashViews(newSect) {
//close active section
$('.dashView.open').slideUp('2000', function() {
$('.dashView.open').removeClass('open');
$(newSect).slideDown('2000', function() {
$(newSect).addClass('open');
});
});
};
I think this.id won't work. ~~You want to convert this to a jQuery object via $(this) then use the attr() method to retrieve the 'id'. So something like...~~
EDIT
Turns out this.id does work! Didn't notice the id="#1" you had in your HTML tags. Yep, as others have pointed out, that'll be the culprit.
Using Bootstrap
<ul class="nav nav-pills nav-stacked col-sm-2 hidden" id="menu">
<li role="presentation" id="LiNewsFeed">News Feed</li>
<li role="presentation" id="LiStatusUpdate">Update Status</li>
<li role="presentation" id="LiWriteWall">Post On Wall</li>
<li role="presentation" id="LiNotifications">Notifications</li>
<li role="presentation" id="LiLogOut">Logout</li>
</ul>
In Javascript, I am disabling some of the <li> like the following:
$('#LiNewsFeed').addClass('disabled');
The Item in the List actually LOOKS disabled, when when I click on it, it actually calls the javascript function, therefore, what I need is to disable the <a href> not just the <li>
I tried adding this after $(document).ready:
$(".nav li.disabled a").click(function () {
return false;
});
But it's not really doing anything.
What I need is to disable the <a href> directly after disabling <li> in my Js code, and not to depend on a click event...
Seems like there is no way to disable an <a href>, so I need a way around it
Any help would be appreciated.
use below code. check working example JSFIDDLE
$(".nav li.disabled a").each(function(){
$(this).attr('href','javascript:void(0);');
});
As you are disabling LI in javascript (runtime), you should use .on to bind events on disabled links:
$(".nav").on('click', 'li.disabled a', function () {
return false;
});
I would check on every link click if the parent has the disabled class.
$('.nav li a').click(function () {
if($(this).parent('li').hasClass('disabled')) {
return false;
}
return true;
});
EDIT, following more info from OP I would suggest the following:
$('.nav li a').each(function() {
var $this = $(this);
// store reference of 'href' attr in case link is re-enabled
$this.data('href', $this.attr('href'));
if ($this.parent('li').hasClass('disabled')) {
// remove href attribute disabling click
$this.removeAttr('href');
} else {
// restore href
$this.attr('href', this.data('href'));
}
});
This code should be run after you add/remove the disabled class on li elements.
EDIT 2 - Rather than you calling functions from the href of <a> links, you could do something like the following:
var events = {
'#LiNewsFeed': 'GetNewsFeed',
'#LiStatusUpdate': 'StatusUpdate'
'#LiWriteWall': 'WriteOnWall',
'#LiNotifications': 'GetNotifications',
'#LiLogOut': 'LogOut'
};
for (var selector in events) {
if (events.hasOwnProperty(selector)) {
try {
$(selector).click(function () {
// assuming function is global
if (typeof window[events[selector]] === 'function') {
// call function
window[events[selector]]();
}
// this is needed if the a element still has a href attr
return false;
});
} catch (e) {
console.log('Invalid Selector');
}
}
}
This way you can control the calling of the function, and check whether it should be called without altering the element, perhaps stick an
if (!$(this).parent('li').hasClass('disabled')) {
...
}
around the function call.
can you convert the a into span?
(code not tested)
$(".nav li.disabled a").replaceWith(function() { return "<span>" + this.innerHTML + "</span>"; });
The $(".actionsAdListnTo").click function is getting fired twice.
I tried various solutions posted in StackOverflow but nothing worked.
What is the reason of twice firing any pointers please.
How to avoid this?
$(".actionsAdListnTo").click(function (e) {
$('#actionsAdListnTo').slideToggle();
});
$(".ddlAddListinTo li").click(function () {
var urlstring = "../ActionTypes";
var ddlselectedVal = $(this).attr('id');
var $form = $("#frmPostToEmailReports");
var selectedListinsCount = selected_Listings.length;
var SelectedMlsnums = selected_Listings.join();
if (ddlselectedVal != "None" && ddlselectedVal != "select") {
//*********** To Cart Functionality
if (ddlselectedVal == 'Tocart') {
if (selectedListinsCount > 500) {
if ($('#errmesg').length == 0) {
$('.messageCenter').append('<span id="errmesg" class ="errmesg"> <span class="messageIcon"></span><span>The maximum number of listings you may select To Add to cart is 500.</span></span>');
return false;
}
} else {
$.post(urlstring,
function (data) {
$(window.open(urlstring, '_blank', 'width=750, height=400')).load(function (e) {
var $formCopy = $("#frmPostToEmailReports").clone();
$($formCopy).append('<input id="SelectedMlsnums" name="SelectedMlsnums" type="hidden" value="' + SelectedMlsnums + '">');
// Here "this" will be the popup window. insert a form element into the popup window.
$(this.document).find("#divfrmInfo").html($formCopy);
e.preventDefault();
});
});
}
}
}
});
HTML :
<div class="actionsAdListnTo">
<span> Add Listing To</span>
<ul id="actionsAdListnTo" class="ddlAddListinTo" style="display: block;">
<li id="Tocart">To CART</li>
<li id="Toportal">To Portal</li>
<li id="SaveListings">Save Listing</li>
</ul>
</div>
The click on li bubbles to its parents, one of them being <div class="actionsAdListnTo">, so the parent's click handler is also called. Try to stop propagation of the click on li:
$(".ddlAddListinTo li").click(function (e) {
e.stopPropagation();
...
In this case it looks it would be more correct to target the link only for the toggle and not the outer div. Be as specific with your selectors as possibe, similar to this:
$(".actionsAdListnTo a#select").click(function (e) {
$('#actionsAdListnTo').slideToggle();
});
If you want to be more specific without an id using the structure, you could do it simlar to:
$(".actionsAdListnTo > span:first > a").click(function (e) {
$('#actionsAdListnTo').slideToggle();
});
Anyway, the way your HTML is structured there is no need to have the toggle triggered by the div as only the link should react to it.
DEMO - Getting more specific with the selector
What I see here is that you are defining two events in the same place, the second one on a child.
$(".actionsAdListnTo").click( function(e){
...
});
$(".ddlAddListinTo li").click(function () {
...
})
Maybe you can use e.sTopPropagation() in the second one, or e.preventDefault()
I want a background image to change with the onclick attribute on html link tag. But its not working.
<ul>
<li>Home </li>
<li>Achivement</li>
<li>Career</li>
<li>Message</li>
<li>opportunity</li>
<li>Register
<li></li>
</ul>
<script type="text/javascript">
function one(){
$('body').css('background-image','url(image/back1.jpg)');
}
function two(){
$('body').css('background-image','url(image/back2.jpg)');
}
function three(){
}
function four(){
} </script>
as you can see I tried passing a function on the onclick attribute and I have already defined these function on the bottom already and still the background image wont change. I have checked the directory where the images are they are correct. and I havent defined any background image on my css so. I need help and its driving me crazy.
A couple things:
You need to include the jQuery library (in case you did not already)
You need to prevent the default action because it is a link
You need to functionalize it for reuse.
Example:
<script type="text/javascript">
$(function(){
$('a').on('click',function(e){
var href = this.href.split('='),
img;
// prevents following to the link location
e.preventDefault();
// determines which background image
switch(href[1]){
case 'Home':
img = 'back1.jpg';
break;
case 'Achievement':
img = 'back2.jpg';
break;
case 'Career':
img = 'back3.jpg';
break;
case 'Message':
img = 'back4.jpg';
break;
case 'Opportunity':
img = 'back5.jpg';
break;
}
// assigns background-image
$('body').css({backgroundImage:'url(image/'+img+')'});
});
});
</script>
This will allow great reuse, and eliminate the need for the inline onclick= declarations.
You have an href along with the click. You will need to specify your link as
<li>Home </li>
You will need to redirect to the page through javascript. Otherwise you are in essence asking it to go to redirect you to the URL and call your javascript but if the redirect happens how would you even see what the javascript execution yields?
Remove your inline script and all your functions and try this instead:
$(function () {
$('ul li a').on('click', function (e) {
e.preventDefault)();
$('body').css('background-image', 'url(image/back' + $(this).closest('li').index() + '.jpg)');
});
});
If you just want to target the first 4 li you can add to my code a if($(this).closest('li').index() < 5){ change background };
About the links you have, if you want to use them
Try to use this stetment for jQuery element:
$(function() {
$('elementLink').on('click', function(e){
e.preventDefault();
$('body').css('background-image','url(image/back1.jpg)');
});
});
It should be like this:
onclick="one(); return false;"
when you click a link, the new page loads, so you have to prevent this behavior by writing return false
You can also write
onclick="return one();"
and javascript:
function one(){
$('body').css('background-image','url(image/back1.jpg)');
return false;
}
I would always try to keep the image src decision out of the code, and move it into the CSS file. Something like:
// could be good to keep your url params as lower case as a convention, then this
// options object could be skipped and you'd just use the param as the classname
var options = {
'Home': 'home',
'Achievement': 'achievement'
};
$("ul li a").click(function(e){
e.preventDefault();
var href = $(this).attr("href");
if(href[1])
{
$("body").addClass(options[href[1]]);
}
});
then in your css file
body.achievement
{
background: url("/images/some_img.png");
}
body.home
{
background: url("/images/some_img2.png");
}
That way when you want to update the srcs, or styles, you do't have to go searching through the src
p.s. I haven't run the code above, but hopefully you get the idea :)
I have been trying to change some things with the Flexslider v2 to fit my needs.
I have been trying to use jQuery to target the parent li of the img class="active" because i want to give it a class of selected but I have not been very successful
<ol class="foo">
<li>
<img src="bar.png" class="active"> <-- This class changes img elements depending on the active slide
</li>
<li>
<img src="bar.png">
</li>
<li>
<img src="bar.png">
</li>
</ol>
I came up with something like this:
$(document).ready(function() {
$('.foo li').children().each(function(index, value) {
if($(value).hasClass('active')) {
$(this).parent('li').addClass('selected');
} else {
$(this).parent('li').removeClass('selected');
}
});
});
and it works in the console, but it does nothing within my main.js file.
LIVE DEMO
Simple like one line:
$('.foo li').find('img.active').closest('li').addClass('selected');
Or if you really need it:
LIVE DEMO
$('.foo li').find('img').each(function(index, el) {
if($(el).hasClass('active')) {
$(el).closest('li').addClass('selected');
} else {
$(el).closest('li').removeClass('selected');
}
});
jQuery API Documentation - Closest
Wrap it i document.ready like this in your main.js and then it should work as expected.
You got it worked in console because all elements are loaded when you runt the script.
$(function(){
$('.foo li').children().each(function(index, value) {
if($(value).hasClass('active')) {
$(this).parent('li').addClass('selected');
} else {
$(this).parent('li').removeClass('selected');
}
});
});
Use closest():
$(this).closest('li'),addClass('selected');
Add $(document).ready(function(){
$(document).ready(function(){
$('.foo li').children().each(function(index, value) {
if($(value).hasClass('active')) {
$(this).parent('li').addClass('selected');
} else {
$(this).parent('li').removeClass('selected');
}
});
});
Check the similar question HERE
$('.foo > li').removeClass('selected').each(function() {
if($(this).find('img').hasClass('active')) {
$(this).addClass('selected');
}
});
Why use .each() ? When we can achieve our goal without it.
$(".foo li img.active").parent().addClass("selected");