I am trying to use an onClick event in JavaScript and am running into a problem. I want to make a button that changes its id, click handler, and text back and forth when it is clicked - I want it to become a completely different button when clicked the first time, but then revert back to the original button when clicked the second time.
My idea was to write one event handler for the original button being clicked which changes it to the second button and I put this in the function "change()". I also had planned on writing one separate event handler for the new button being clicked which changes it to the original button and I put this in the function "changeBack()".
The problem is that when I click on the original button one time, change() gets called and within it changeBack() automatically gets called exactly when the onClick is defined for the new button and right before the innerHTML is changed. I commented out some of the original lines and put an alert in to illustrate this unwanted behavior. I think somehow the click is still active when the new button gets created, thus forcing it to call changeBack() even though the new button was never clicked. Any help on this would be great. Thank you.
<script type="text/javascript">
function change() {
var x = document.getElementById("button");
x.id = "alternateButton";
x.onClick = changeBack();
x.innerHTML = "Click to Change Me Back";
}
function changeBack() {
var x = document.getElementById("alternateButton");
alert('hi');
//x.id = "button";
//x.onClick = change();
//x.innerHTML = "Click Me";
}
</script>
<button id="button" onClick="change()">Click Me</button>
Events are bound to the elements and not to the ID attribute. Both the handlers are always executed when you click the button.
Also it is a good idea to avoid binding handlers using inline event handlers.
// Find the elemnt
var btn = document.getElementById('button');
// Data attribuet to keep tab of whether it is clicked or not
btn.dataset.clicked = "1";
// Attach event
btn.addEventListener('click', change);
function change() {
var txt = 'Click to Change Me Back';
// Will give you the truthy/falsy value
if(!!this.dataset.clicked) {
this.dataset.clicked = "";
// First implementation
} else {
this.dataset.clicked = "1";
txt = "Click Me";
// The other case
}
this.innerHTML = txt;
}
Check Fiddle
The above comment by Sushanth got me started on the right track by using a truth tester. However, the same problem about the mouse came up - it captures the mouse longer than I want it to (even when using onmousedown). Because of this, right when the new button gets created the old one replaces it, so the new button is never seen. Also, by changing the element's id, I ran into some really strange things such as the program stopping completely if I use an alert - and not continuing after I close the alert, but when I delete the alert, the entire program runs. I guess it's better to leave the ID's alone and only use them as a reference and change the styles dynamically with DOM access rather than the style tag and control other parts of the page using the button by referencing other functions in the switch statement (I'm really new to JavaScript so I'm not sure how else it is done).
Because of these issues but with Sushanth's comment idea, I used two testers: one for which button is currently being shown, and one for the mouse having been pressed or released. I also had some strange issues when putting the code in the header instead of the bottom of the body. Finally, I had to use some custom properties. I hope this helps anybody that wants to use a button that changes its appearance and functionality back and forth as you click on it.
<button id="button1" onmousedown="transformButton1()" onmouseup="release()">Click Me</button>
<p id="one">One</p>
<p id="two">Two</p>
<p id="three">Three</p>
<script type="text/javascript">
var x = document.getElementById("button1");
x["clicked"] = 0;
x["released"] = 1;
function transformButton1() {
var x = document.getElementById("button1");
if (x["released"] == 1) {
switch (x["clicked"]) {
case 0:
x["clicked"] = 1;
x["released"] = 0;
// Other function calls to change other elements on the page, for example:
document.getElementById("two").innerHTML = "I've Changed!!!!!";
x.innerHTML = "Click to Change Me Back";
break;
case 1:
x["clicked"] = 0;
x["released"] = 0;
// Other function calls to change other elements on the page, for example:
document.getElementById("two").innerHTML = "Two";
x.innerHTML = "Click Me";
break;
}
}
}
function release() {
document.getElementById("button1")["released"] = 1;
}
</script>
JSFiddle
Related
I have many buttons and also one popup div which includes short or long content depended on value from a map.
Case 1: If content is hidden(windows.onload, it is hidden), if any button is clicked, the content should be visible then if same button is clicked, the content should be hidden again.
Case 2: If content is visible due to a clicked button, if any button(except same button like in case 1) is clicked, the content should not be hidden, keep being visible.
In the code below, i could manage to handle case 1 but not case 2. I think, i need to make a comparison function between first and last time called values of buttons but i cant find the way of storing first value so i cant make a comparison.
Should i use "JavaScript Closures" because i think that it may work.https://www.w3schools.com/js/tryit.asp?filename=tryjs_function_closures5
if i should, is there any workaround? i prefer to use another method rather than to use Closures because i dont understand logic of "Closures" enough for now.
Thank you.
function infoFunc(clicked_value) {
let infoText = "";
let control = "q1";
for (let qvalue of questionDetails.keys()) {
if (clicked_value == qvalue) {
let y = questionDetails.get(qvalue);
infoText = `<p>${y}</p>`;
document.getElementById("questioninfoDiv").innerHTML = infoText;
}
}
popupcontrolFunc(clicked_value, control);
}
/* Functions: " control of information popup" */
function popupcontrolFunc(clicked_value, control) {
if (control == clicked_value) {
popupTrueOrFalse();
} else {
popupTrue();
control = clicked_value;
}
}
function popupTrueOrFalse() {
let popup = document.getElementById("questioninfoDiv");
popup.classList.toggle("show");
}
function popupTrue() {
let popup = document.getElementById("questioninfoDiv");
popup.classList.toggle("show", true);
}
<button type="button" id="questionInfoimg" value="${key}" onClick="infoFunc(this.value)"><img src="question-mark.svg"
alt="Info_Mark">
</button>
edit: i guess, i need to make it more clear. Please check out the https://jsfiddle.net/GrayCollar/odnhgkpx/22/
Actually, i think, i need a algorithm and a way to use that algorithm like "js closures". i am not sure about "js closures", just try to explain what i need.
You don't need closures.
The this keyword will do the trick. According to Mozilla Developer Network,
When a function is used as an event handler, its this is set to the element on which the listener is placed (some browsers do not follow this convention for listeners added dynamically with methods other than addEventListener()).
This will not work in strict mode. In that case, you will have to pass an event object into the function, which looks like so.
element.addEventListener(eventString, function(e){
//e is the event object
});
This event object has a currentTarget property, which is basically the element that the event is target to, which in this case is the button that is clicked. All put together, it looks like this:
function eventHandler(e){
//use e.currentTarget
}
element.addEventListener(eventString, eventHandler);
I shortened my code dramatically but below relays the point pretty efficiently, I'm trying to get the variable "Monitor" to update if the buttons pressed. I can get the variable through to my code if I put all of my code inside of the "button.onclick" function. However, my code won't run until I press the button. I need my code to run and if a button is pressed it updates my code.
<form name="form1">
<span id="buttons">
<input type="button" name="button1" value="funny1"/>
<input type="button" name="button2" value="funny2"/>
</span>
</form>
<script type="text/javascript">
var Monitor, buttonsDiv=document.getElementById("buttons");
Monitor = "funny1"
for (var i=1; i<=2; i++) {
var button = document.form1["button" + i];
button.onclick = function() {
buttons.Monitor = this.value;
};
/*lots of my own code that runs
inside of my for loop waiting
to reference monitor for an update*/
</script>
Hopefully the following code will get you going in the right direction. Instead of wiring up all the events per button, I think you were trying to get it so each button would then call into a function that would set the value of Monitor.
var Monitor = "funny1";
//selecting all elements named button
var buttons = document.querySelectorAll('input[type="button"]');
//For each of the buttons wire up an event listener
for(var i=0, length=buttons.length; i < length;i++)
{
//create a reference shorthand
var button = buttons[i];
//add the event listener for a click
button.addEventListener('click', function(event)
{
//on the event look at the event's target property to find the element that invoked the click
Monitor = event.target.value;
console.log(Monitor); //Output the value of monitor the the console
});
}
This code first finds all the inputs with type=button. I suggest you perhaps give the inputs a class instead to make the selector clearer, your choice. Secondly, I loop through the buttons and wire an event up for each one. The event then sets the value of the Monitor variable.
http://jsfiddle.net/wcf4c/
i am programming in java script to set two button in Gmail page.
i have done it.In that button click event,i have to insert some content.
button creation code:
var btnEncrypt=document.createElement('input');
btnEncrypt.type='button';
btnEncrypt.value='Encrypt';
btnEncrypt.id='btn11';
var btnDecrypt=document.createElement('input');
btnDecrypt.type='button';
btnDecrypt.value='Encrypt';
btnDecrypt.id='btn10';
and the onclick function is,
btnEncrypt.onclick = function()
{
className1 = document.getElementsByClassName('aa')[0].innerHTML;
};
btnDecrypt.onclick = function()
{
className1 = document.getElementsByClassName('bb')[0].innerHTML;
document.getElementsByClassName('bb')[0].innerHTML=decodeData;
};
in first time, i would click the both btnEncrypt and btnDecrypt button it will correctly triggered btnEncrypt.onclick and btnDecrypt.onclick.But again i click the btnDecrypt button are not invoked.
i remove each line from that onclick and check,after i got the problem.
document.getElementsByClassName('bb')[0].innerHTML=decodeData;
using the above line in buttonclick,hereafter only btnDecrypt and btnEncrypt not invoked.
note:both buttons are placed in that bb class using like bb.appendchild(buttons)
How can i resolve that?
Thank u.
I used this code to change the class of an html-element when an onclick-event occurs. The change occurs(i.e. the text color changes) but the change is not stable, it goes back to the styling of its previous class, and my javascript code doesn't seem to have any effect.
function submitrequest(){
var x = document.forms["signupform"]["name"].value;
if(x.toString().length <= 0){
var y = document.getElementById("nametd");
y.className = 'change';
}
}
What should I do to make this effect permanent?
You do not have to define a click-handler to notice that a button of a form was clicked.
A form can have an submit-button:
and when this button is clicked an submit event is fired for the form.
Furthermore when an user do not clicks on the button and just presses enter then a submit-event is fired too. So you handle both situations automatically.
I suggest that you define you function that way:
window.onload = function(){
document.getElementById('signupform').addEventListener('submit',function(e){
changeClassOfNametd();
e.preventDefault(); // this prevents the side from being reloaded by the script.
});
};
function changeClassOfNametd(){
var nameValue = document.forms["signupform"]["name"].value;
if(nameValue){ // when value is "" (zero, no signs) it is false anyway
var y = document.getElementById("nametd");
y.className = 'change';
//y.classList.toggle('change'); you can toggle classname "change" too
// which works that way class="unchange" -> class="unchange change"
// you have to define appropriate css-classes for toggle.
}
}
The Code above works whereever you put it into your html-file.
By the name of the function it is called on a form submission.
Because the form submits and it goes back to the original that was set when the new page loads.
If you want to maintain that, you would have to apply the class on the next page load. Most developers will do that with the serverside. If you do not actually want the form to submit, cancel it.
I can't seem to get this to work in JavaScript. I've tried using plain old JavaScript and also JQuery but nothing seems to work.
Here's my situation:
I have this PopUp "Panel" and in it I have a Button. The button has an event listener for click and I want that handler to fire off a custom event that the Panel will listen for. This is because I need to handle all the logic of the button click in the Panel.
Here's what I'm doing:
Before I launch the Panel I call a constructor for my "Class":
function PopUpStageAsssignmentTaker(content) {
PopUpStage.call(this);
this.allPagesAdded = false;
this.questionsCreated = [];// will be an array of pages that will be submitted
this.listLabel = null;
addAssignmentTakerParts.call(this);
this.popUpDiv.addEventListener("assignmentTakingSubmitEvent", handleAssignmentSubmit, true);
function handleAssignmentSubmit(event) {
alert("YESSS!");
}
}
This does quite a bit but just know that in the call to PopUpStage it creates the div that represents the Panel and saves that in this.popUpDiv. So I add a event listener to this.popUpDiv listening for some custom event that I'm making up.
Later on I have code that creates the content in the Panel and we have something like this:
SubmitQuestionTakingPage.prototype.makeContent = function(question) {
var questionWrapper = getQuestionWrapper();
var submitDiv = document.createElement("section");
submitDiv.innerHTML = "Pressing Submit will cause this Assignment to be submitted and you will be unable to make any changes after that. If this " +
"Assignment is automatically graded you will receive a Grade upon clicking submit. If this Assignment is not automatically submitted you must wait" +
" for the creator of this Assignment to assign you a Grade. To continue, please press Submit.";
submitDiv.setAttribute("class", "separatedSmaller");
questionWrapper.appendChild(submitDiv);
var submitButton = document.createElement("input");
submitButton.setAttribute("type", "submit");
submitButton.setAttribute("class", "fancyButton");
submitButton.addEventListener("click", handleSubmitButtonClick);
questionWrapper.appendChild(submitButton);
return questionWrapper;
};
function handleSubmitButtonClick(event) {
var event = document.createEvent("Event");
event.initEvent("assignmentTakingSubmitEvent", true, true);
window.dispatchEvent(event);
// $(this).trigger("assignmentTakingSubmitEvent");
}
So we create some content and in it we create a button that has a listener for click. In the click handler you can see how I fire off the event.
Problem: I'm reading that this does not work in IE under version 9+. What can I do in to make it work in all browsers? Is there a way?