Hello I got a question regarding changing elements in the DOM. I got a situation that whenever I click on the button it will show a div. After 2 seconds the initial div is replaced by another div which also got a function call that removes the div again.
Now comes the tricky part. What I want is that whenever I hide the div again, the third click on the button will show the div again.
Let me explain a bit more. Imagine that I got the following situation:
First mouse click on button 1 (Result: shows red div)
Second mouse click on button 1 (Result: hide red div)
Third mouse click on button 1 (shows the div again)
The third bullet is the tricky one. How can I do that? Because when I click for the third time on button 1 it does not show anything anymore because I did not change it back to the original state
The code that I have so far JSFIDDLE
function Test(){
var target = window.event.target || window.event.srcElement;
console.log(target);
var content = arguments[0];
console.log(content);
$( "body" ).append( "<div class='red'>"+content+"</div>" );
setTimeout(function(){
$( ".press" ).replaceWith( "<button class='press' onclick='UnTest()'>button 1</button>" );
}, 2000);
}
function UnTest(){
$( ".red").remove();
}
Please note that due to implementation restrictions I can not check within my Function if the button is clicked (eq. $(".red").click())
There are a few ways you could accomplish this, but a quick solution might be just toggling the onclick attribute of the button (rather than replacing it entirely).
// In setTimeout
setTimeout(function(){
$('.press').attr('onclick', 'UnTest()');
}, 2000);
function UnTest(){
$( ".red").remove();
$('.press').attr('onclick', 'Test("one")');
}
https://jsfiddle.net/2mvqmtwq/1/
This will also allow you to add multiple .red divs (similar to the original fiddle) and then remove with a single click (which another answer does not take into account, instead treating it as a simple visibility toggle).
Edit: For multiple buttons/instances (per your comment), you'll need an identifier of sort. Your original code made it easy by declaring the target, which we can use. Let's say we have three buttons:
<button class="press" onclick="Test('one')">button 1</button>
<button class="press" onclick="Test('two')">button 2</button>
<button class="press" onclick="Test('three')">button 3</button>
Our updated JS doesn't change too much, other than referencing the string value we passed (which you declare as content):
setTimeout(function(){
$(target).attr('onclick', 'UnTest("' + content + '")');
}, 2000);
As well as referencing the target you've declared at the top (which allows us to keep each button instance unique).
Here's the updated fiddle with all the changes I made (additional parameters, scoped class names for the red boxes, etc):
https://jsfiddle.net/2mvqmtwq/9/
Use a variable to count the number of clicks, which is initially equal to 0. Then, each time you click the button, you increase the variable by 1 and check if the variable is odd or even. If it's odd, you add the div, if it's even you remove the div:
var clicked = 0;
function Test() {
clicked++;
var content = arguments[0];
if (clicked % 2 === 1) {
$("body").append("<div class='red'>" + content + "</div>");
} else {
$(".red").remove();
clicked = 0;
}
}
Fiddle: https://jsfiddle.net/2mvqmtwq/5/
Tip: you can reset the variable back to 0 when it's even.
Here's a dead simple fix. I think we can do this whole thing a lot more cleanly with some refactoring. But since you mention implementation restraints, I don't want to offer a solution that might break those restraints.
Simply add logic to your UnTest() function
function UnTest(){
$( ".red").remove();
$( ".press" ).replaceWith( "<button class='press' onclick='Test(\"hello\")'>button 1</button>" );
}
How about writing some clean code, avoiding inline event handlers?
What you could probably do is:
First click: add the div
Next click onwards: check if the div already exists. If yes, simply toggle it's display as opposed to removing it.
This is only a demo as to how this could be done. This one also works for multiple buttons/divs. As I said earlier, I have removed inline event handlers and added the div class and function params as data-attributes. Feel free to edit the code to suit your needs.
$(document).on("click", ".press", function() {
var $this = $(this);
var $div = $("div." + $this.data("class"));
if ($div.length) {
$div.toggle();
return;
}
$( "body" ).append( $("<div/>", {
'class': $this.data("class"),
'html': $this.data("param")
}) );
});
button{ margin:10px}
div {
width:200px;
height:50px;
}
.red {
background-color:red;
}
.blue {
background-color:blue;
}
.green {
background-color:green;
}
.orange {
background-color:orange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="press" data-param="one" data-class="red">button 1</button>
<button class="press" data-param="two" data-class="blue">button 2</button>
<button class="press" data-param="three" data-class="green">button 3</button>
<button class="press" data-param="four" data-class="orange">button 4</button>
Related
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>
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.
I need help with this JS code for my wordpress theme.
First part is when it looks for h4 heading and if it has certain text it wraps all paragraphs below this h4 into div (which hides all paragraphs into fading section) and adds "button" (which is span):
var tutustu = 'TUTUSTU';
var syvenny = 'SYVENNY';
$('.article_content h4').each(function(){
if($(this).text() == tutustu)
{
$(this).nextUntil("h4").wrapAll('<div class="expand" />').parent().append('<span id="expand">show more</span>');
}
else if($(this).text() == syvenny) {
$(this).nextUntil("h4").wrapAll('<div class="expand" />').parent().append('<span id="expand">show more</span>');
}
});
Second is when user clicks on "button" div (that we wrapped into all paragraphs early) will get another class (to basicaly reveal all the paragraphs) and remover button:
$('span#expand').click(function() {
$(this).parent('.expand').removeClass('expand').addClass('expanded');
$(this).remove();
});
What I need is after paragraph text is revealed I want to have button to click on and everything goes back like in 1st part.
I came up with something like this:
$('span#expanded').click(function() {
$(this).parent('.expanded').removeClass('expanded').addClass('expand');
});
But it doesn't work (
Help is much appreciated
Use event Delegation and .toggleClass() instead of .addClass() and .removeClass()
$(document).on("click" , "span#expanded" , function() {
$(this).parent().toggleClass('expanded expand');
});
$('#expanded').on('click', function(e) {
$(this).parent().toggleClass('expanded expand');
e.preventDefault();
});
i am trying to make a colour change when a button is clicked and i managed to do this however i want to change the colour of not just the main content container but more containers how do i do this?
function changeblackandwhite(objDivID) {
if(document.getElementById(objDivID).style.color=='black'){
document.getElementById(objDivID).style.color='white';
document.getElementById(objDivID).style.backgroundColor='black';
}
else if(document.getElementById(objDivID).style.color=='white'){
document.getElementById(objDivID).style.color='black';
document.getElementById(objDivID).style.backgroundColor = 'white';
}
else{
document.getElementById(objDivID).style.color='black';
document.getElementById(objDivID).style.backgroundColor='white';
}
}
<img src="images/colour.jpg" title="Change Text/Backgroud Colors">
There are dozens of ways you can accomplish this.
You could change the argument of your function to be an array of strings. You could also reduce the complexity of your function as well
<script type="text/javascript">
changeblackandwhite = function() {
for( var idx=0; idx < arguments.length; idx++) {
var tgtDiv= document.getElementById(arguments[i]);
if(tgtDiv.style.color=='black'){
tgtDiv.style.color='white';
tgtDiv.style.backgroundColor='black';
}
else{
tgtDiv.style.color='black';
tgtDiv.style.backgroundColor='white';
}
}
};
</script>
<img src="images/colour.jpg" title="Change Text/Backgroud Colors">
As another reader questioned - you can do this with jQuery in a single line.
With jQuery, you can declare the elements in question to have a class attribute.
Using jQuery, you can then do something like:
$('div.someClass').css({'color': 'black', 'background-color': 'white'});
The argument to jQuery can be a class based selector, an id based selector, or any other selector you choose.
If you are open to jquery and you assign 1 class in common with these two divs you can do the following:
This should get you started (see this jsfiddle): I changed the fiddle to include a neater solution where clicking on the button adds and removes classes on the containers which allows you to set multiple attributes including the text color in one quick call.
<div class='container'>
</div>
<div class='container'>
</div>
<button id="changeColor" type="button">Change Color </button>
<script type="text/javascript">
$(document).ready( function() {
$('#changeColor').click( function() {
if ($('.container').hasClass("blackContainer")){
$('.container').addClass("whiteContainer");
$('.container').removeClass("blackContainer");
} else {
$('.container').removeClass("whiteContainer");
$('.container').addClass("blackContainer");
}
});
});
</script>
//CSS
.blackContainer {
background-color: black;
color: white;
}
.whiteContainer {
background-color: white;
color: black;
}
I made a jsfiddle for you to play around with jsfiddle
I also did the javascript/jQuery in a similar way as the OP since it usually helps them understand.
As stated above, there are several different ways to do this, I've done but one.
The document.ready function sets up an event listener for the object to be clicked, most of the time this is how you'll see events coded. So when the link is clicked, it calls the function with the string name of the object the listener is for.
$(document).ready(function() {
$("#changeit").click(function(){
changeblackandwhite("Maincontainer");
})
});
After the event listener is assigned, it will call the function below when the link is clicked on.
// Here's your function, put the current color in a var, check if it's black
// if black, change colors, else make it black.
function changeblackandwhite(objDivID) {
var curColor = $("#" + objDivID).css("color");
if( curColor == 'rgb(0, 0, 0)'){
$("#"+objDivID).css({'color':'white','background-color':'black'});
} else {
$("#"+objDivID).css({'color':'black','background-color':'ghostwhite'});
}
}
update at the bottom
There are 4 divs that are set to look like toggle buttons. When a button is toggled on:
-it is animated as a pressed button,
-it retrieves some content and it places that content into a box, and then
-it returns a value of 1 to an array.
(no problem.)
Problem:
When there is already one button button pressed, I don't understand how to toggle the first button off without also turning the other one off or affecting the other buttons. How can I pass the output of one button to the others so they know who they have to turn off when they turn on?
My solution thus far has been to create 2 arrays:
var arrayValues [ a, b, c, d]; //the values of each button state: [0,0,0,0] <-all off | all on-> [1,1,1,1]
var addedValues = [a + b + c + d]; //the values of each array item added together: [0+0+0+0]= 0 <-all off | all on-> [1,1,1,1]=4
and then
if (addedValues = 0) {
console.log("cool, nothing is pressed yet. I am going to return true, but where does that return value go? How can I access it?");
return true;
} else if (addedValues > 1) {
console.log("ok I now know that at least one button has already been pressed, but how can I tell the other buttons which one was already pressed?");
}
For example if the first button is toggled on
arrayValues = [1,0,0,0]
and now the second button has been toggled on so it says
arrayValues = [1,1,0,0]
but how can I pass that information into all of the buttons? This next part is obviously flawed but it's the only thing I could think of doing:
} else if(addedValues >= 2) {
arrayValues[0] = arrayValues[0] - 1;
arrayValues[1] = arrayValues[1] - 1;
arrayValues[2] = arrayValues[2] - 1;
arrayValues[3] = arrayValues[3] - 1;
}
so now, the only values that are not negative are the two buttons in active states... but that does nothing for because we already knew that. How can I tell the buttons which button to subtract 1 from without affecting any of the other buttons?
Update: To see the madness in context http://jsfiddle.net/Luhring/EjW7A/23/
*update: *
Just to clarify: the buttons aren't only just toggling their appearances, they're changing other content displayed on the page:
When you click each button the content changes. each button has 1 original group of original content that is toggled on/off with the button. like changing the channel on a tv screen with a remote control.
so if button 1 is pressed, when button 2 is pressed button 1 must turn off (removing its' content and animating back up to its' original position) in order to allow button 2's stuff to display.
shout out to #nbrooks for writing 4 lines of code that more or less did as much as I did in +100. Still not solved but his is WAY more efficient than mine (you can see his version here: http://jsfiddle.net/EjW7A/20/ ) )
Updated Demo, according to new reqs: http://jsfiddle.net/EjW7A/24/
$(function() {
$('.plain').click(function() {
var newClassName = $(this).is('.selected') ? '' : this.id;
if ($(this).is('#content')) return;
$(this).toggleClass('selected', 1000);
$('#content').attr('class', 'plain '+newClassName);
$('.selected').not(this).removeClass('selected');
});
});
Update to your fiddle demo
The best way to do this is just give the elements a common class, to which you can bind a click handler and a css rule. This will accomplish your function of only having one button being pressed at a time, plus the ability to turn it on/off without affecting the others.
Javascript (jQuery):
$(function() {
$('.plain').click(function() {
$(this).toggleClass('selected');
$('.selected').not(this).removeClass('selected');
});
});
HTML
<div id="a" class="plain">
<p>A</p>
</div>
CSS
.plain {
width: 200px; height: 200px; margin: 20px; text-align:center; float: left;
font-size: 100px; color:#fff; background-color:red;
}
p { margin-top: 25%; margin-bottom:25%; }
.selected { background-color: blue; }
If you are doing the submitting with JavaScript, then this should be a much simpler approach: http://jsfiddle.net/EjW7A/15/
HTML
<div id="a" class="a1 toggleButton">
<p>A</p>
</div>
<div id="b" class="b1 toggleButton">
<p>B</p>
</div>
<button id ="test">test</button>
JavaScript
jQuery(function() {
jQuery(".toggleButton").click(function() {
jQuery(".toggleButtonToggled").removeClass("toggleButtonToggled");
jQuery(this).addClass("toggleButtonToggled");
});
jQuery("#test").click(function() {
var value = jQuery(".toggleButtonToggled:first").attr('id');
alert("Toggled button is: "+ value);
});
});