adding and removing a class upon slidetoggle - javascript

I have created a 3 x 2 grid of squareish buttons that are monotone in colour. I have a slidetoggle div that pops down inbetween both rows of 3 and as it does so it pushes the content down of the rest of hte page, this is all working perfectly so far.
But i have made a class (.active) thats css is the same as the :hover state so that when i hover over a button the coloured version replaces the monotone version, however i have tried to add some js to make the colour (.active) stay on once i have clicked on a certain button so that you can see which button (product) the slidedown div relates to and the rest are still in monotone around it...
The .active code below works perfectly to turn the bottons colour on and off when you click that one button, but i have set it up so that if one button's div is open and you click on a different one, the open one closes and then the new one opens. This feature however throws off the balance of the code i have for the .active state here. When you have say button 1 open and you click button 1 to close, this works fine, the color goes on and then off, but if yo uhave button 1 open and click on button 2, button 1's div closes and opens button 2's div but then botton 1 stays in colour as button 2 turns to colour. the order is thrown off...
I need to add some js to say, that only one button can be in color (.active) at a time, or that if one is .active it must be turned off before the new one is turned on... Please help :)
$(document).ready(function(){
$("a.active").removeClass('active'); //<<this .active code &
$("#product1").click(function(){
if($(this).parent('a').hasClass('active')){ //<<<this .active code
$(this).parent('a').removeClass('active'); //<<
}else{ //<<
$(this).parent('a').addClass('active'); //<<
} //<<
$("#product2box").slideUp('slow', function() {
$("#product3box").slideUp('slow', function() {
$("#product4box").slideUp('slow', function() {
$("#product5box").slideUp('slow', function() {
$("#product6box").slideUp('slow', function() {
$("#product1box").stop().slideToggle(1000);
//do i need
//something here??
});
});
});
});
});
});
And here is the HTML
<div id="row1">
<a href="#!" class="active"><span id="product1">
<div id="productblueheader">
<div id="productlogosblue1"></div>
</div>
<div id="productstitle">Stops all spam and unwanted email.</div>
<div id="producttext">With over 8 million users ******* is the leading in anit-spam software on the market today! Sort all your spam issues in one place now!</div>
</span></a>
<a href="#!" class="active"><span id="product2">
<div id="productblueheader">
<div id="productlogosblue2"></div>
</div>
<div id="productstitle">The easiest email encryption ever.</div>
<div id="producttext">In todays world, we won’t enter personal details in to untrusted websites, but we send personal information via regular (insecure) email all the time.</div>
</span></a>
<a href="#!" class="active"><span id="product3">
<div id="productblueheader">
<div id="productlogosblue3"></div>
</div>
<div id="productstitle">The easiest email encryption ever.</div>
<div id="producttext">****** is a revelation in security and ease of use. Get the best protection against viruses, spyware, scam websites and other threats.</div>
</span></a>
</div>
(then the same for row2 products 4-6)

you use .each() method of jquery and find .active class to remove it,
and then add .active class.
$(this).parent('a').each(function(){
$(this).removeClass('active');
});
$(this).parent('a').addClass('active');

This ought to work, but I couldn't test it without the relevant HTML:
$(document).ready(function () {
$("#product1").click(function () {
$("a.active").removeClass('active');
$(this).parent('a').toggleClass('active'));
$("#product2box").slideUp('slow', function () {
$("#product3box").slideUp('slow', function () {
$("#product4box").slideUp('slow', function () {
$("#product5box").slideUp('slow', function () {
$("#product6box").slideUp('slow', function () {
$("#product1box").stop().slideToggle(1000);
});
});
});
});
});
});
});
Also, there would probably be a better way to write all those sliding up functions. Do they really need to go on by one by the way?

$(document).ready(function() {
$(".producthandler").click(function() {
var ctx = $(this);
var productboxId = ctx.children().eq(0).attr("id");
ctx.toggleClass('active');
$("#" + productboxId + "box").stop().slideToggle(1000);
$(".producthandler").each(function() {
var ctx = $(this);
var producthandlerId = ctx.children().eq(0).attr('id');
if (productboxId !== producthandlerId) {
ctx.removeClass('active');
$("#" + producthandlerId + "box").slideUp(1000);
}
});
});
});

Related

JavaScript making users click before executing next action

We do currently have a button which does send an action to an API. This is a giveaway app. What I want to achieve: We have multiple sponsors in the database. (Multiple links). The button should be only available, if each link is clicked.
How am I able to do this with multiple links? I've thought about it when we had like one link, we could set a variable to true. How are we able to do this with multiple ones?
Here's how I'd handle it.
First, assign each link a unique class. Then create an array that contains the classes for each link you wish to be clicked. Then you can check if each of these links have been clicked by checking if their class is in the respective array:
var required_links = ["one", "two", "three"];
var count = 0;
$(document).on("click", ".link", function() {
if ($.inArray(this.classList[1], required_links) != -1 && !$(this).hasClass("clicked")) {
console.log("User clicked link '" + this.classList[1] + "' for the first time.");
count++;
$(this).addClass("clicked");
}
if (count == required_links.length) {
console.log("All links clicked");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="link one">Link 1</div>
<div class="link two">Link 2</div>
<div class="link three">Link 3</div>
In the above snippet, I'm checking for the presence of the clicked class. Once clicked, the element has the class added, so it can't be clicked again. This ensures that you have to click each link, rather than simply being able to click the same element multiple times.
Note that I'm using <div> tags in the above example, but the same theory will work by simply affixing the relevant classes to the <a> tag instead.
Hope this helps! :)
I know you might not need another solution, but this might be a little easier to maintain based off of how many links you have. You can have as many links as you want, just make sure they have a class="required".
As you click on each link, that class is removed. Once there are no more links with class="required", the button/link becomes clickable.
$(function() {
$( ".required" ).click(function() {
$(this).removeClass("required");
if ($( ".required" ).length == 0) {
$( "button" ).prop("disabled", false);
$( "button" ).text("Well maybe now you can.");
}
});
$( "button" ).click(function() {
// second check to deter the tricksters
if ($( ".required" ).length == 0) {
window.location.href = "http://www.gosomewherecool.com/"
}
});
})
.required {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You gotta click me! <br>
Oh and me! <br>
Me too! <br>
<button disabled>
Can't click me yet!
</button>

Hide a div if an element has been clicked twice in a row, else Show

I have several items in my navigation bar, and a div next to it, ie:
<nav>
<a id="a"></a>
<a id="b"></a>
<a id="c"></a>
</nav>
<div id="menu-col"></div>
If the same link is clicked twice in a row, I want to hide #menu-col. If not, I want #menu-col to remain visible.
I'm not a javascript guy so I tried this:
var lastClicked;
$('nav a').on('click', function(e) {
alert(e.target.id + " - " + this.lastClicked);
if (e.target.id == this.lastClicked) {
$('#menu-col').hide();
this.lastClicked = '';
}
else {
$('#menu-col').show();
this.lastClicked = e.target.id;
}
});
Then I remembered that javascript assigns references, and not values. So when I did this.lastClicked = e.target.id; I'm assigning a reference to my element's id, then on the next click I make that e.target.id == ''.
In javascript, what would be the proper way of closing a box if the same link is clicked twice, and if not making sure the box is visible.
You can achieve this using toggleClass() to set a state class on the clicked a and also using toggle() on the .menu-col to show or hide it based on that state class. Try this:
$('nav a').click(function(e) {
e.preventDefault();
var $a = $(this);
$a.toggleClass('active').siblings().removeClass('active');
$('.menu-col').toggle($a.hasClass('active'));
});
.menu-col {
display: none;
}
.active {
color: #C00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<a id="a" href="#">a</a>
<a id="b" href="#">b</a>
<a id="c" href="#">c</a>
</nav>
<div class="menu-col">menu-col</div>
As long as you keep those ids unique across you app (which you should be doing anyway) the approach you've chosen isn't wrong. Any primitive in javascript is actually stored by value. Those primitives are string, number, boolean, and symbol. For more info see here https://developer.mozilla.org/en-US/docs/Glossary/Primitive
I would suggest something like this, you should have some kind of condition in which the div shows after it has been hidden.
$('nav a').dblclick(function(event) {
event.preventDefualt();
alert($(this).attr('id'));
$('#menu-col').toggle();
});
Something like that should be exactly what you are looking for, like I said though, there should be a condition in which it shows itself again, I made it a toggle so any double click on any 'nav a' element will cause it to show/hide the div.
Just for the sake of an option. Here is another way for double clicks(clicked twice in a row).
Using ondblclick event.
Double-click me.

Trying to do a:active to stay on untill other link is clicked

What I'm trying to do is this: I have two links hot/update. When hot is clicked it should turn red and update to be black. When update is clicked it should turn red and hot to be black.
This works on a Fiddle, but not on my website.
I was able to find various answers on SO, as this seems like a common thing to ask. I was implementing one by one, but none of them works. They seem to work fine in fiddle but not on my web.
HTML:
<div id="Space" >
<ul>
<li role="presentation" class="sort">
<a class="link" href="/?sort=score&page=1" style="text-decoration:none;">hot</a>
</li>
<li role="presentation" class="date">
<a class="link" href="/?sort=date&page=1" style="text-decoration:none;">update</a>
</li>
</ul>
</div>
JavaScript:
$(function() {
var links = $('a.link').click(function() {
links.removeClass('active');
$(this).addClass('active');
});
});
CSS:
a.link.active { color: red; }
a, a:visited { color: black }
Right now, this does what a:active does, it won't stay red.
var links = does not do what you think it does.
You are thinking it is doing this:
var links = $('a.link');
But, since you're assigning it to the actual click event, it's not resulting in that selector.
You need to revise your code as follows:
// This is a "safer" document ready, to prevent conflicts with other $ libraries
jQuery(function($) {
$('a.link').click(function() {
// Remove the class from all other links
$('a.link').removeClass('active');
// Add the class to _just this link_
$(this).addClass('active');
});
});
Or, a version that preserves the var links:
// This is a "safer" document ready, to prevent conflicts with other $ libraries
jQuery(function($) {
// Assign all links to the "links" variable
var links = $('a.link');
links.click(function() {
// Remove the class from all other links
links.removeClass('active');
// Add the class to _just this link_
$(this).addClass('active');
});
});
Here's a working fiddle: https://jsfiddle.net/cale_b/tqzt8f7s/1/
So to clarify you want certain buttons to be highlighted based on whether or not the url has a certain query. Highlight sort if url contains /?sort=score&page=1 and highlight date if url contains /?sort=date&page=1.
To do this all you need to do is search for each of those strings inside of your page's (window.location.search). The code for such a thing would be.
const highLightWhat = (window.location.search).search('sort=score') !== -1 ? 'Highlight sort' :
(window.location.search).search('sort=date') !== -1 ? 'Highlight date' :
'Highlight Nothing';
This flag then can be used as a reference to highlight one 'a' tag or another.
I hope this helped! (:
Try this javaScript once
$(function() {
$('a.link').click(function(event) {
event.preventDefault();
$('a.link').removeClass('active');
$(this).addClass('active');
});
});

Show/Hide Content without reloading the page

I have three content boxes that i want to show and hide using controls.
The HTML is as follows:
<div id="leermat1">
Content here
<a class="pag-next">Next</a>
<a class="pag-prev">Previous</a>
</div>
<div id="leermat2">
Content here
<a class="pag-next">Next</a>
<a class="pag-prev">Previous</a>
</div>
<div id="leermat3">
Content here
<a class="pag-next">Next</a>
<a class="pag-prev">Previous</a>
</div>
I have the two anchors pag-next and pag-prev that will control which of the content divs should be visible at any given point:
I want to write jquery such as, when #leermat1 'pag-next' is clicked, it hides #leermat1 and shows #leermat2. Then when #leermat1 is hidden and #leermat2 shows, when '.pag-next' is clicked, it hides #leermat2, and shows #leermat3.
Also the 'pag-prev' should work the same way.
I started with the following but dont know where to go from here.
$(document).ready(function() {
$('.pag-next').on('click',function() {
$('#leermat1').addClass('hide');
$('#leermat2').addClass('show');
});
});
One more thing is that the '.pag-next' should stop functioning after it has shown #leermat3.
You need this
$('[class^=pag-]').click(function() {
var elem = $('[id^=leermat]').filter(":visible"); // take the visible element
var num = Number(elem[0].id.match(/\d+$/)[0]); // take the number from it
var step = $(this).is('.pag-next') ? 1 : -1; // ternary operator
$('#leermat'+ (num + step)).show(); // show next or back
elem.hide(); // hide the visible element
});
Looks like in your anchor tag you have not given it a class.
Next
You then go on in your JQuery code to add a click function to a class which does not exist.
$('.pag-next').on('click',function()
Try adding class="pag-next" to your anchor tag.
This is what worked for me through a little trial and error. Although I am not sure if this is the most efficient solution.
$('#leermat1 .pag-next').on('click',function(){
$('#leermat1').addClass('hide');
$('#leermat1').removeClass('show');
$('#leermat3').addClass('hide');
$('#leermat3').remove('show');
$('#leermat2').addClass('show');
});
$('#leermat2 .pag-next').on('click',function(){
$('#leermat1').removeClass('show');
$('#leermat2').addClass('hide');
$('#leermat2').removeClass('show');
$('#leermat3').addClass('show');
});
$('#leermat2 .pag-prev').on('click',function(){
$('#leermat2').addClass('hide');
$('#leermat2').removeClass('show');
$('#leermat1').addClass('show');
$('#leermat3').removeClass('show');
});
$('#leermat3 .pag-prev').on('click',function(){
$('#leermat3').addClass('hide');
$('#leermat2').addClass('show');
$('#leermat1').addClass('hide');
$('#leermat3').removeClass('show');
$('#leermat1').removeClass('show');
});

CSS/Javascript Mouseover Popup box

I have table cell with a javascript/css content box that pops up upon mouseover.
There are 20 cells on the page. Everything is working correctly, in that when you mouseover the product link, you see the content box. However, I want to put a LINK inside the content box that the user can click on if they choose. So, the popup box has to stay up long enough for the user to mouseover to click the link.
Really, I want the OnMouseOver to stay open until either a second or two has gone by and/or the user OnMouseOver's another cell.
The problem I'm having is that the pop up box doesn't stay open (due to OnMouseOut) to click the link. If I turn OnMouseOut off (which I tried), then all the pop up boxes just stay open, so this doesn't do the job either.
My CSS looks like this:
<style type="text/css" title="">
.NameHighlights {position:relative; }
.NameHighlights div {display: none;}
.NameHighlightsHover {position:relative;}
.NameHighlightsHover div {display:block;position:absolute;width: 15em;top:1.3em;*top:20px;left:70px;z-index:1000;}
</style>
And the html:
<td>
<span class="NameHighlights" onMouseOver="javascript:this.className='NameHighlightsHover'" onMouseOut="javascript:this.className='NameHighlights'">
Product 1
<div>
# of Votes: 123<br>
% Liked<br>
<a href="product review link>See User reviews</a>
</div>
</span>
</td>
So, how can I make the pop up box stay open long enough to click on the link, but also make it disappear if another content box is activated?
Thanks in advance.
You have to improve your HTML markup for this task, need to get rid of inline event handlers:
<span class="NameHighlights">
Product 1
<div>
# of Votes: 123<br>
% Liked<br>
See User reviews
</div>
</span>
Then you have to bind your events to all .NameHighlights spans:
var span = document.querySelectorAll('.NameHighlights');
for (var i = span.length; i--;) {
(function () {
var t;
span[i].onmouseover = function () {
hideAll();
clearTimeout(t);
this.className = 'NameHighlightsHover';
};
span[i].onmouseout = function () {
var self = this;
t = setTimeout(function () {
self.className = 'NameHighlights';
}, 300);
};
})();
}
http://jsfiddle.net/3wyHJ/
So the idea is to use setTimeout method.
Notes: I used querySelectorAll which is not supported by IE7, if you need to support it then you can use any of implementations of the getElementsByClassName method.
In case anyone is looking for a jQuery version of the accepted answer:
var t;
$(function(){
$('span.NameHighlights').mouseover(
function(e){
hideAll();
clearTimeout(t);
$(this).attr('class', 'NameHighlightsHover');
}
).mouseout(
function(e){
t = setTimeout(function() {
//$(this).attr('class', 'NameHighlights');
hideAll();
}, 300);
}
);
});
function hideAll() {
$('span.NameHighlightsHover').each(function(index) {
console.log('insde hideAll');
$(this).attr('class', 'NameHighlights');
})
};
jsFiddle

Categories

Resources