JavaScript do something if one of four buttons is pressed - javascript

So, I'm working on a JavaScript project and now I need to find a way, how it can do the if commands, if I press one of four buttons. The code looks basically like this:
i=1
if(i==1){
[[...]]
$("#button1").click(function() {
i++
}
}
if(i==2) {
[[..]]
}
I thought JavaScript would check the if(i==2), see, that i is 2 and do the actions, but it doesnt...

You may use switch case with different button onClick. And call different function from there.
$('button').on('click', function () {
var i = 0;
switch ($(this).attr('id')) {
case "btn1": i+=1; break;
case "btn2": i+=2; break;
case "btn3": i+=3; break;
case "btn4": i+=4; break;
}
console.log(i);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="btn1">1</button>
<button id="btn2">2</button>
<button id="btn3">3</button>
<button id="btn4">4</button>

This solution uses jquery (I noticed you are already using it).
You need to be able to uniquely identify individual buttons, if you add an attribute to each with an index then this is possible.
Once you have this unique identifying attribute you can create click events for individual buttons with the line: $("button[btn-ind='2']").click( function() { ... });. Alternatively you can apply a general click event for any button and differentiate within that click event by checking the attribute (i.e. the value of $(this).attr("btn-ind").
Buttons 1 and 2 have their own click events in the code below.
Buttons 3 and 4 only have a a click event via the general button selector.
Let me know if this isn't what you wanted.
$("button[btn-ind='1'").click( function() {
console.log($(this).text() + " clicked");
});
$("button[btn-ind='2'").click( function() {
console.log($(this).text() + " clicked");
});
$("button").click( function() {
if ( $(this).attr("btn-ind") == "3" ) {
console.log($(this).text() + " clicked");
} else if ( $(this).attr("btn-ind") == "4") {
console.log($(this).text() + " clicked");
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button btn-ind="1">Button 1</button>
<button btn-ind="2">Button 2</button>
<button btn-ind="3">Button 3</button>
<button btn-ind="4">Button 4</button>

I think you're getting wrong the underlying event pattern. You are trying to use simple procedural programming to distinguish the pressed button, but this doesn't even make sense.
You should attach a different event handler to each button and then simply do what that button is supposed to do:
<button type="button" id="button1">1</button>
<button type="button" id="button2">2</button>
<button type="button" id="button3">3</button>
<button type="button" id="button4">4</button>
<script>
$("#button1").on("click", () => {
// button 1 was pressed, do what you must
};
$("#button2").on("click", () => {
// button 2 was pressed, do what you must
};
$("#button3").on("click", () => {
// button 3 was pressed, do what you must
};
$("#button4").on("click", () => {
// button 4 was pressed, do what you must
};
</script>
A much smaller code footprint can be achieved by parameterizing the buttons through an HTML attribute such as data-*. Do not use arbitrary, invented attributes, they are not HTML5 compliant. Here I use data-command attributes to show that indices are not necessary:
<button type="button" data-command="start">1</button>
<button type="button" data-command="faster">2</button>
<button type="button" data-command="slower">3</button>
<button type="button" data-command="stop">4</button>
<script>
// attach event to all buttons with a data-command attribute
$("button[data-command]").on("click", () => {
// distinguish by data-command attribute
switch ($(this).data("command"))
{
case "start":
// perform the "start" action
break;
case "faster":
// perform the "faster" action
break;
case "slower":
// perform the "slower" action
break;
case "stop":
// perform the "stop" action
break;
default:
throw "unrecognized command (was \"" + $(this).data("command") + "\")";
}
};
</script>

Related

Disable button with javascript

I have a button. The button works fine. After I have pressed the button, then it shall not be possible to press the button again. It will be best if the button looks diabled.
I have already tried with document.getElementById("id").disabled = true; but I can't make this work.
PHP code for the button. The code makes a list of buttons. Each button has id= 1, 2, 3 etc.
if($_COOKIE["sorterdb"]=='GR' || empty($_COOKIE["sorterdb"])){$dblinjer[$i]['nrlink']='<span id="para'.$i.'"></span><div class="s-12 l-12"><button type="button" id="'.$i.'" value="'.$dblinjer[$i]['loebid'].'_'.$dblinjer[$i]['tid'].'_'.$dblinjer[$i]['utcstart'].'" onclick=baadimaal("baadimaal",this)>'.$dblinjer[$i]['buttonnrsejl'].'</button></div>';}
javascript:
function baadimaal(str,el) {
var x = el.value
var id = el.getAttribute("id")
const xhttp = new XMLHttpRequest();
xhttp.onload = function() {
document.getElementById("container"+id).innerHTML = this.responseText; //her placeres svaret, som kommer tilbage fra hide-ajax-svar filen
}
xhttp.open("GET", "hide-ajax-svar.php?funk=" + str + "&para=" + x + "&i=" + id); //overfør str og x til hide-ajax-svar filen
xhttp.send();
}
You can set the button's disabled property to false (see Sütemény András's answer), but that may not work in all browsers. You can also remove the listener, however that doesn't make the button look disabled.
So a belt and braces approach is to do both, e.g.
window.onload = function() {
// Listener
function clickFn() {
console.log('I\'ve been clicked! But no more…');
// Make button appear disabled
this.disabled = true;
// Remove the listener
this.removeEventListener('click', clickFn);
}
// Add the listener to the button
document.getElementById('b0').addEventListener('click', clickFn, false);
};
<button id="b0">Click me</button>
Note that if using setAttribute as in:
button.setAttribute('disabled', true);
the second argument is required but its value is irrelevant (it can be false, 'foo bar', 42, whatever). Regardless of the value, the element will be disabled, which is a hangover from ancient times when boolean attributes were added to HTML. Their presence alone does the job, they don't take a value (e.g. <button disabled>foo</button> creates a disabled button).
To unset the attribute (i.e. to enable the button again), use removeAttribute.
If you have a button like this:
<button class="button" id="1">Button 1</button>
<button class="button" id="2">Button 2</button>
<button class="button" id="3">Button 3</button>
You can add javascript eventlistener, do the job, than disable:
const buttons = document.querySelectorAll(".button")
buttons.forEach((item) => {
item.addEventListener("click", ()=>{
// DO SOMETHING WHITH YOUR BUTTON
console.log(`You've clicked on ${item.id} and now I'm gonna disable it.`)
// disable
item.disabled = true;
})
})
And depending on your code, maybe you should add "removeEventListener" on your button.

Click Function using AJAX Jquery Javascript

I am making a movie review web site as a project for school, and I want to put a click function on the image movie cover which will load the details and reviews of that movie. The code I'm using works but does not seem practical. The parameter in my loadReviews function is the movie ID for the database.
$(document).ready(function () {
$("#cover1").click(function () { loadReviews(1); });
$("#cover2").click(function () { loadReviews(2); });
$("#cover3").click(function () { loadReviews(3); });
$("#cover4").click(function () { loadReviews(4); });
$("#cover5").click(function () { loadReviews(5); });
$("#cover6").click(function () { loadReviews(6); });
$("#cover7").click(function () { loadReviews(7); });
$("#cover8").click(function () { loadReviews(8); });
$("#cover9").click(function () { loadReviews(9); });
$("#cover10").click(function () { loadReviews(10); });
$("#cover11").click(function () { loadReviews(11); });
$("#cover12").click(function () { loadReviews(12); });
});
As you can see I am writing each one manually. I tried using a for loop like this but does not work the way I thought.
for (i = 1; i < 12; i++) {
$("#cover" + i).click(function () { loadReviews(i); });
}
Using the loop it makes each image load the details of the same (#12) movie. Each image is assigned the class 'cover1', 'cover2' etc. I want some sort of 'loop' to automatically bind each click event to the correct image cover. I'm using a generic handler in Visual Studio 15. We must use ajax and jquery to update the page without a postback, this is how I am getting the movies and reviews.
If I need to show more code let me know. Thanks!
You could get away with having just one click handler and store the identifier as a data attribute. So your repeated HTML element might be something like this:
<div class="cover" data-movieid="1">
...
</div>
<div class="cover" data-movieid="2">
...
</div>
etc.
Then assign a single click handler and within that handler get the identifier from the element which was clicked. Something like this:
$(document).ready(function () {
$('.cover').click(function () {
var movieID = $(this).data('movieid');
loadReviews(movieID);
});
});
Depending on what loadReviews() does, you can probably make the whole thing simpler. Instead of giving everything ids and only using those in your selectors, from any given clicked element you can use jQuery to query the DOM and find the relative element you need without using an id.
If the HTML can't be changed
$("[id^=cover]").click(function () {
var rev = parseInt(this.id.replace(/\D+/g, ''));
loadReviews(rev);
});
Instead of using IDs for each cover I would recommend using a "cover" class and a data parameter with the id.
<div class"cover" data-movieid="1"></div>
and the js code would look like:
$(document).ready(function () {
$(".cover").click(function () { loadReviews($(this).data('movieid')); });
});
Using the loop it makes each image load the details of the same (#12) movie.
This happens because when the loop ends the value of the variable is always the last while the event will happen in future.
Two ways to solve it (Immediately-invoked function expression):
function loadReviews(i) {
console.log(i);
}
for (i = 1; i < 5; i++) {
(function(i) {
$("#cover" + i).on('click', function (e) {
loadReviews(i);
});
}(i));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="cover1">Cover 1</button>
<button id="cover2">Cover 2</button>
<button id="cover3">Cover 3</button>
<button id="cover4">Cover 4</button>
<button id="cover5">Cover 5</button>
The second way is based on the id (i.e: get the last part id: remove the cover string):
function loadReviews(i) {
console.log(i);
}
for (i = 1; i < 5; i++) {
$("#cover" + i).click(function () {
loadReviews(this.id.replace('cover', ''));
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="cover1">Cover 1</button>
<button id="cover2">Cover 2</button>
<button id="cover3">Cover 3</button>
<button id="cover4">Cover 4</button>
<button id="cover5">Cover 5</button>
You are facing the typical "callback inside look" context problem.
Let's check the code.
Having this:
$("#cover1").click(function () {
loadReviews(1);
});
Means that the code inside the function will be run only when the click event occurs, and not when the event is attached, so the runtime will go this way:
// First, attaches the event
$("#cover1").click(function () {
// This will be run when user clicks, so will be called last
loadReviews(1);
});
// The runtime will continue right BEFORE the click callback is run
So in your loop the runtime will go this way:
for (i = 1; i < 12; i++) {
// var i value starts from 0. And attaches the click event
$("#cover" + i).click(function () {
// Runs after all the loop is done (when the i value is 12)
loadReviews(i);
});
// loop continue BEFORE the content of the click callback is run
}
One fast way to fix your loop is to call a function with the variable declared inside the function, so it will be never changed by external actions.
function attachClick(id) {
// This will be run on each loop, creating a id variable
// that will be unique for this context
$("#cover" + id).click(function () { loadReviews(id); });
}
for (i = 1; i < 12; i++) {
// Call the function passing the i variable as parameter
attachClick(i);
}
And the way that you will se a lot around there is by creating anonymous functions (does exactly the same as above but without creating a named function elsewhere):
for (i = 1; i < 12; i++) {
(function(id) {
$("#cover" + id).click(function () {
loadReviews(id);
});
})(i);
}
Those are the fastest ways of modifying your code to have a working one, but when working with events that way, the best is to attach only one event to the parent, capture the element clicked and get the id from there. The less events attached, the faster is everything.
function loadReviews(i) {
console.log(i);
}
for (i = 1; i < 5; i++) {
(function(i) {
$("#cover" + i).on('click', function (e) {
loadReviews(i);
});
}(i));
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="btn btn-primary" id="cover1">Cover Primary</button>
<button class="btn btn-success" id="cover2">Cover Success</button>
<button class="btn btn-danger" id="cover3">Cover Danger</button>
<button class="btn btn-warning" id="cover4">Cover Warning</button>
<button class="btn btn-info" id="cover5">Cover Info</button>

Perform click event for only one button under a CSS class

I have some JavaScript to execute logic i.e. doSomething() when a button is clicked. I know the class of the buttons, but there are multiple buttons on the page with this same class. The problem with my code below is that the doSomething() function is executed once for every button on the page when I only want it to execute one time only.
var myButtonClass = $(".my-button-class");
if (myButtonClass) {
myButtonClass.click(function (event) {
if (someCondition) {
doSomething();
}
});
}
I know it would be better to select by button div, but the button div names all vary based on how many there are (i.e. #my-button-div1, #my-button-div2, etc.) and the number of buttons is indefinite.
Is there a way to only do this event once? I don't care which button in the class happens to be clicked, I just need the event to fire once and then it's done.
UPDATE: To be clear, I still want the logic to execute if the user clicks another button on the page again, so I don't want to completely unbind the event. I just don't want it to execute once for every button on the page. For example, let's say I have 4 buttons. Right now it's doing something like the following when just one button is clicked:
alert!
alert!
alert!
alert!
I only need ONE of those alerts. Basically, whenever the user clicks any of the buttons on the page, I need it to go alert! only once per click.
Revised so that you don't have weird if statements, and allows for other click handlers to happily work if binded elsewhere
UPDATED:
var clickHandler = function handleClick(event) {
doSomething();
}
var bindClicks = true;
function doSomething() {
alert('alert!');
}
function doTheBinding() {
if (bindClicks) {
$('.my-button-class').on('click', clickHandler);
bindClicks = false;
}
}
// as many times as you want but it will still call once
doTheBinding();
doTheBinding();
doTheBinding();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button class="my-button-class">Click me!</button>
<button class="my-button-class">Click me!</button>
<button class="my-button-class">Click me!</button>
<button class="my-button-class">Click me!</button>
You can use on() and off() to bind and unbind the event on an element respectively.
$('.my-button-class').on('click', function (event) {
if (someCondition) {
doSomething();
// Unbind the event on all the elements having the class
$('.my-button-class').off('click');
// To unbind the event on only the clicked element
// $(this).off('click');
}
});
Sidenote: if (myButtonClass) { will always evaluate to true. jQuery returns an object even when the element is not found and an object is always truthy. To check if an element exists in DOM, use length property on the jQuery object $('someSelector').length > 0.
If you give the handler a local boolean variable that is protected with a closure, you can create a function that will execute only once. See this SO answer.
Run the code snippet below to see it in action.
$(".my-button-class").click(function() {
var executed = false;
return function() {
if (!executed) {
executed = true;
doSomething();
}
};
}());
function doSomething() {
alert("You should only see me once!");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="my-button-class">Click me!</button>
<button class="my-button-class">No click me!</button>
UPDATE: To address a different issue of the click event getting bound more than once. Just do a similar thing with:
var bind = function() {
var bound = false;
return function() {
if (!bound) {
bound = true;
$(".my-button-class").click(function() {
if (someCondition)
doSomething();
});
}
};
}();
bind();
bind(); // won't execute second time
var someCondition = true;
function doSomething() {
$("#output").append("<br>alert!");
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="my-button-class">Click me!</button>
<button class="my-button-class">No click me!</button>
<span id="output"></span>

Bind button to a Javascript case/action

I am new to Javascript, and i run into some big problems. I got some functions, which I can type into a text field and press enter, and the functions works. But i have created 4 buttons, which i want to connect to the actions.. i got 4 actions: "UP","DOWN","LEFT" and "RIGHT".
This is the js fiddle over my code: http://jsfiddle.net/n24gQ/
I have made the buttons like this but I dont know what to write inside the OnClick tag?
<div id="gamebuttons">
<button id="up" button onClick="">UP</button>
<button id="down" button onClick="">DOWN</button>
<button id="left" button onClick="">LEFT</button>
<button id="right" button onClick="">RIGHT</button>
</div>
I hope you can understand what my problem is. I made 4 javascript cases which I want to bind to 4 html buttons if possible.. :) It is the cases: "frem" "tilbage" "hoejre" and "venstre" i need to bind.. Sorry not everything in the code is english, but it should be understandable..
Fiddle
You can simply write the function name you've defined for the buttons into the onclick attribute, e.g. like this:
<button id="up" type="button" onclick="alert('UP'); return false;">UP</button>
However, as your buttons already have id's you can also check if one of those id's got clicked without the need of onclick in your markup:
JavaScript:
var buttonUp = document.getElementById('up');
buttonUp.onclick = function() { myFunction(); return false; }
jQuery:
$('#up').on('click', myFunction());
Instead of using inline handlers (bad practice) or multiple handlers for each button, I would use event delegation on your button wrapper, like so
$('#gamebuttons').on('click', 'button', function() {
/* get the id attribute of the clicked button */
var button_id = this.id;
case (button_id) {
"UP" : /* code for up button */ break;
"DOWN" : /* code for down button */ break;
"LEFT" : /* code for left button */ break;
"RIGHT" : /* code for right button */ break;
}
});
Please pass the function name inside the OnClick tag
for example if you want to associate playGame function to DOWN button
write
<button id="down" onclick="playGame();">DOWN</button>
I think these below changes will give you solution.
Instead of the first button, you need to bind events to all of the buttons which you required. Currently, querySelector() getting only first button to bind events. So, use querySelectorAll()
Replace this code
var button = document.querySelector("button");
button.style.cursor = "pointer";
button.addEventListener("click", clickHandler, false);
button.addEventListener("mousedown", mousedownHandler, false);
button.addEventListener("mouseout", mouseoutHandler, false);
With below code
var gamebuttonslist=document.querySelectorAll("#gamebuttons button");
for (var vitem=0;vitem<gamebuttonslist.length;vitem++) {
if (typeof gamebuttonslist[vitem] != "undefined" && gamebuttonslist[vitem] != null) {
gamebuttonslist[vitem].style.cursor = "pointer";
gamebuttonslist[vitem].addEventListener("click", clickHandler, false);
gamebuttonslist[vitem].addEventListener("mousedown", mousedownHandler, false);
gamebuttonslist[vitem].addEventListener("mouseout", mouseoutHandler, false);
}
}

How can i get one button to do multiple tasks depending on how many times it has been clicked? (Javascript)

How can i get one button to do multiple tasks depending on how many times it has been clicked? (Javascript)
For example button is clicked - alert "button clicked once" button gets clicked again - alert "button clicked twice" button is clicked again - alert" button has been clicked three times!"
Sorry if its a noob question, the reason is I AM A NOOB!!!
Fiddle demo: http://jsfiddle.net/h9DbF/
in js:
var clickTimes = 0;
function doSomethingOnClick() {
clickTimes++;
switch(clickTimes) {
case 1:
alert('Button clicked once');
break;
case 2:
alert('Button clicked twice');
break;
default:
alert('Button clicked ' + clickTimes + ' times');
}
//Do something else
}
in html:
<button onclick="doSomethingOnClick()">Press me</button>
You could create a var that will increment when the button is clicked, and you can switch that var so you can do an action depending on the number of clicks for example:
var clicks = 0;
function someFunction(){
clicks++;
switch (clicks){
case 1:
//do something when its clicked only once
break;
}
}
And thats it.

Categories

Resources