Reputation: 401
I have a function written to open / close a div using a placeholder for a hyperlink.
<a class="button" onclick="show('click-drop')">Open</a>
The onclick
event then opens the div.
I have this onclick
to close it:
<a class="button" onclick="hide('click-drop')">Close</a>
What I would like to do is have a single placeholder for a hyperlink that switches between the two onclick
events. So onclick=show
would switch to onclick=hide
and vice versa.
I have looked everywhere and cannot find a straightforward solution for my situation.
Here's specifically what I am working with.
function show(target) {
document.getElementById(target).style.height = '300px';
}
function hide(target) {
document.getElementById(target).style.height = '0px';
}
<a class="button" onclick="show('click-drop')">Open</a>
<div id="click-drop" style="height:0px">
<a class="button" onclick="hide('click-drop')">Close</a>
</div>
Click Open
and it opens / expands inline height style. Click Close
and it closes.
I need to have the onclick
toggle, but with Open
changing to Close
and reverse.
It would be ideal to keep the placement of the links. So the Open
link outside the link is hidden until the Close
link within the div is clicked.
I appreciate any feedback.
Upvotes: 0
Views: 12885
Reputation: 150
After you create your element
var elem = document.querySelector('.js-switch');
var init = new Switchery(elem);
Bind your OnClickMetod
to init.switcher
like this
$(init.switcher).on('click', OnClickMetod);
Upvotes: 0
Reputation: 3911
It's possible to save button's state inside its context. And then, depending on its state call appropriate functions.
function toggle() {
this.state = !this.state; // false - open; true - closed; default = false (because is not initialized yet)
this.innerHTML = this.state ? 'Close' : 'Open';
if(this.state) {
open();
} else {
close();
}
}
function open() {
alert("Opened");
}
function close() {
alert("Closed");
}
<a class="button" onclick="toggle.call(this)">Open</a>
<a class="button" onclick="toggle.call(this)">Open</a>
<a class="button" onclick="toggle.call(this)">Open</a>
Upvotes: 1
Reputation: 33496
Here is another answer in case you want to use toggle
on multiple buttons. This solution uses the button to store the state of its target, and so it uses toggle.call()
to modify the value of this
within toggle
.
It's inspired by jQuery.toggle()
and Yuriy Yakym's answer.
for (i = 1; i <= 3; i++) {
var button = document.getElementById("button"+i),
target = document.getElementById("target"+i);
// wrapped in closure because https://stackoverflow.com/q/8909652/5743988
(function(_button, _target) {
_button.onclick = function() {
toggle.call(_button, _target);
}
})(button, target);
}
function toggle(target) {
this.func = this.func || hide; // if "func" is undefined, assign "hide"
this.func.call(target); // execute "func"
this.func = this.func === hide // make "func" call the other thing next time
? (this.innerHTML = "Show", show) : (this.innerHTML = "Hide", hide);
}
function hide() {
this.oldDisplay = window.getComputedStyle(this).display;
this.style.display = "none"; // better than "height = 0px"
}
function show() {
this.oldDisplay = this.oldDisplay || "block";
this.style.display = this.oldDisplay;
}
button, div {
display: inline-block;
}
<button id="button1">Close</button>
<div id="target1">Hello World!</div>
<br>
<button id="button2">Close</button>
<div id="target2">Hello Again World!</div>
<br>
<button id="button3">Close</button>
<div id="target3">Hello Again Again World!</div>
Upvotes: 2
Reputation: 401
I figured out a straightforward solution for this.
When the open link is clicked and the div opens I need the open link to disappear and a close link displayed as a separate element. The same event should work in reverse i.e. close link closes div and displays open link.
While the original code I am working with uses an inline height property to control the open and close, the example below uses display property.
function show(target) {
document.getElementById(target).style.display = 'block';
}
function hide(target) {
document.getElementById(target).style.display = 'none';
}
function hideButton() {
var x = document.getElementById("open");
x.style.display = "none";
var x = document.getElementById("close");
x.style.display = "";
}
function showButton() {
var x = document.getElementById("open");
x.style.display = "";
var x = document.getElementById("close");
x.style.display = "none";
}
<a class="button" onclick="show('click-drop');hideButton()" id="open">Open</a>
<div id="click-drop" style="display:none">
<a class="button" onclick="hide('click-drop');showButton()" id="close" style="display:none">Close</a>
</div>
Here it is in the wild - http://iemajen.com/scripts/mssa/
With this in place I have two more questions.
Should I just open a new topic for the last question?
Upvotes: 0
Reputation: 33496
You could dynamically change the onclick
event of the button, but it's already awkward enough that you're using HTML to describe functionality. It would do you even better if you kept all functionality in the JavaScript. Something like this:
var button = document.getElementById("button");
var target = document.getElementById("target");
button.innerHTML = "Close";
button.onclick = function() { hide(target); };
function hide(target) {
console.log("hiding");
target.style.display = "none";
console.log(target);
button.innerHTML = "Open";
button.onclick = function() { show(target); };
}
function show(target) {
target.style.display = "block";
button.innerHTML = "Close";
button.onclick = function() { hide(target); };
}
<button id="button">Close</button>
<div id="target">Hello World!</div>
Upvotes: 2
Reputation: 869
Either the jQuery toggle or the toggleClass methods should the trick for you.
Edit, per requested, an example:
Say you have a CSS class that looks like this, based on the OP:
.info-box {
height: 300px;
}
By using $('#myTarget').toggleClass('info-box')
, you will be removing that class or adding it. If you don't have it, you'll add it. If you do have it, you'll remove it. Just like that.
So, a working example I just threw together is here, and it implements toggle()
by itself without the need to add any classes, which I believe still accomplishes what the OP was seeking resolution for.
https://jsfiddle.net/bbh9m478/1/
Hope that helps!
Upvotes: 0