How to make the function only runs once in javascript - javascript

How to make the function only runs once per button?
if clicks in "click me" only works once, and the same for the other buttons
Order not to put much code, I put an example..:
http://jsbin.com/apexod/1/watch
<html>
<head>
<title></title>
</head>
<body>
<input type="button" value="click me" onclick="hello()"><br>
<input type="button" value="click me1" onclick="hello()"><br>
<input type="button" value="click me2" onclick="hello()">
<script>
function hello(){
alert("hello");
}
</script>
</body>
</html>

Change your onclick handlers so that the function can reference the element clicked.
<input type="button" value="click me" onclick="hello.call(this)"><br>
<input type="button" value="click me1" onclick="hello.call(this)"><br>
<input type="button" value="click me2" onclick="hello.call(this)">
Then change the function to remove the handler.
function hello(){
alert("hello");
this.onclick = null;
}

You can just remove the onclick
<html>
<head>
<title></title>
</head>
<body>
<input type="button" value="click" onclick="hello(this)"><br>
<input type="button" value="click1" onclick="hello(this)"><br>
<input type="button" value="click2" onclick="hello(this)">
<script>
function hello(btn){
alert("hello");
btn.onclick = function(){};
}
</script>
</body>
</html>

It’s easier to manage if you add event listeners in the script (it’s also consider good practice to separate behaviour from presentation):
Demo: http://jsfiddle.net/4N4ur/
<input type="button" value="click">
<input type="button" value="click1">
<input type="button" value="click2">​
<script>
var inputs = document.getElementsByTagName('input');
for(var i=0; i<inputs.length; i++) {
inputs[i].onclick = function() {
hello();
this.onclick = null; // reset the handler
}
}
function hello() {
alert('hello';
}
</script>

on click of buttton call the function below with button id or name as param
<script>
function hello(caller){
if (caller == 'button1' && $("#button1clicked").val() != '1')
{
// Your code to execute for the function
alert("hello");
// set value for button1clicked
$("#button1clicked").val("1");
}else {
// do nothing
}
}
</script>
Add the above conditions for no of buttons

While the above scenario and answers are all very specific to click handlers, the answer to the original question how to make a function that only runs once is generally done using a wrapper function, similar to the UnderscoreJS .once method:
function once(fn) {
var called = false;
return function() {
if (!called) {
called = true;
fn.apply(this, arguments);
}
}
}
The above implementation would only allow the original function to be invoked once, and it would pass through the context and arguments of the later invocation. This would then be used as:
var oneTimeFn = once(function() {
console.log('I was called.');
});
oneTimeFn();
//-> I was called.
oneTimeFn();
//-> undefined

Related

How can I have a jQuery onclick function return the element instead of the event?

I have a function called deleteTask which currently just does console.log(this)
<input type="button" value="Delete Task" onclick="deleteTask()"/> (note that this in a jQuery function, not in a HTML file) returns [object Window]
while del.onclick = deleteTask; (where del is the input button) returns the object that was clicked, in this case, <input>
How can I have the jQuery version output similarly to the pure JS one?
You could use Function#call, but it is generally better to use addEventListener.
function deleteTask() {
console.log(this)
}
<input type="button" value="Delete Task" onclick="deleteTask.call(this)" />
In jQuery you'd set it up like this:
html:
<input type="button" value="Delete Task" data-role='delete' />
script:
$(document).ready(function() {
$('[data-role=delete]').click( deleteTask )
})
function deleteTask() {
// element clicked is this -- or if you want it ready for JQ: $(this)
}

Trigger script only when user press in submit button

I am executing a script through a function
<script language="javascript">
function showVariantDetail(str) {
url = "insurancemodel.php?ncvd=" + str;
getRequest(url, "txtVariantDetails");
}
</script>
The script is executing perfectly through
<div id="txtVariantDetails">
</div>
But i want the script to execute when the user press in submit button
<div class="search-box-left"></div>
<div class="search-box-right">
<input name="" type="submit" value="Calculate" class="red-btn" />
</div>
can anyone guide on how to ensure when only the user presses in submit button then the txtVariantDetails script to be processed only
Thanks
try jquery on click
$('#submitDemo').on("click",function() {
// your stuff
});
You can use click handler for the submit input.
$("input[type=submit]").on("click",function(event){
event.preventDefault();
showVariantDetail(str);
}
If you do not want to deal with jQuery:
let redButton = document.querySelector(".red-btn");
redButton.addEventListener("click",function(e){
e.preventDefault();
let buttonValue = redButton.value;
showVariantDetails(buttonValue);
});
Change Html Like below
<div class="search-box-left"></div>
<div class="search-box-right">
<input type="button" value="Calculate" class="red-btn" />
</div>
JS
<script language="javascript">
function showVariantDetail(str) {
url = "insurancemodel.php?ncvd=" + str;
getRequest(url, "txtVariantDetails");
}
$(document).on('click','.red-btn',function() {
// var str="" //get your string here
showVariantDetail(str)
});
</script>

How to change a global variable inside jQuery selectors?

I'm developing a website, which is using jQuery.Inside this code I need to change the value of a variable inside a Jquery selector and get the changed value after it.Is it possible to do that?How can I achieve this?If possible, could show me a snippet/example code?
I've tried declaring the variable global, but without success too.
var index;
$(document).ready( function(){
$("#myButton1").click(function(){ //selector number 1
index = 1;
});
$("#myButton2").click(function(){//selector number 2
index = 2;
});
//after, i need the value of the index for another selector
//look this next selector is fired at the same time as the previous one!
$("button[id^=myButton"+index+"]").click( function(){ //selector number 3
...
}
}
How can I make the selector number 1 or 2 fire after the selector number 3?Is it possible?
Javascript executes code asynchronously. In other words, whole code executes at the "same time." So first, it will execute var index;. Since the jQuery .click is waiting for you to click the button, it will skip both of the .click functions and move on to the alert. Since index is undefined, it will say index=undefined. To fix that, move the alert's inside the .click function so that the alert will execute after you click the button.
var index;
$("#button1").click(function() {
index = 1;
alert("index = " + index);
});
$("#button2").click(function() {
index = 2;
alert("index = " + index);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="button1"></button>
<button id="button2"></button>
Or you could do it this way:
var index = 0;
$("#button1").click(function() {
index = 1;
});
$("#button2").click(function() {
index = 2;
});
setTimeout(function() {
alert("index = " + index);
}, 5000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="button1"></button>
<button id="button2"></button>
The above method basically executes the alert after 5 seconds, so you can change the value of index as many times as you want in those 5 seconds. The default value is 0, but if you click the first button within those 5 seconds, the value of index changes to 1. Same for the second button.
The things that happen when you click one of the buttons are those you define inside the click-handler function (see here):
$("#button1").click(function(){
window.index = 1; // only this line!!!
});
Your call to alert() resides inside the ready-funtion and is therefore only called when the page is loaded. You need to put the alert inside the click handlers to call it "on click". Doing so, all three versions should work. Should look like this:
$("#button1").click(function(){
index = 1;
alert(index);
});
After your edit:
Same thing here: the selector string after you comment is created at the time of the page load, before any button is clicked. and never again after that.
At that moment, it evaluates to "button[id^=myButtonundefined]" because index has no defined value yet. T## is function therfore will be executed whenever you click a button whose ID starts with myButtonundefined - probably never.
Everything you want to achieve, for which you need the value of index you need to execute inside the click-handler function. e.g.:
$(document).ready( function(){
$("#button1").click(function(){
$("button[id^=myButton1]").click( function(){
...
});
});
$("#button2").click(function(){
$("button[id^=myButton2]").click( function(){
...
});
});
}
or you could try the following approach, which installs a click-handler on all myButton...'s and therein checks if the corresponding button... has been clicked before:
var index;
$(document).ready( function(){
$("#button1").click(function(){
index = 1;
});
$("#button2").click(function(){
index = 2;
});
//after, i need the value of the index for another selector:
$("button[id^=myButton]").click( function(){
if (this.id == 'myButton'+index) {
...
}
}
}
How to change a global variable inside jQuery selectors?
Don't use a global variable in this instance. You have a chance of a variable collision with any other code (jQuery or any other script you use). You can simply place index inside your document ready and use it in your example code and it will work without any chance of collision.
$(document).ready( function(){
var index;
$("#button1").click(function(){
index = 1;
});
$("#button2").click(function(){
index = 2;
});
//after, i need the value of the index for another selector:
$("button[id^=myButton"+index+"]").click( function(){
});
$('.js-getcurrentvalue').on('click', function() {
$('#currentvalue').val(index);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="button" class="js-getcurrentvalue" value="Get Current Value of Index"/><input type="text" id="currentvalue" /><br/>
<input type="button" id="button1" value="button1" /><br/>
<input type="button" id="button2" value="button1" /><br/>
But at the same time, the selector $("button[id^=myButton"+index+"]").click( function(){ }); fires.So, both are executed at the same time.I need that the second selector execute always after the first selector.Do u know how can I accomplish this?
This is not the original question you asked. Please read what an XY Problem is so your future questions can be answer correctly.
Highly recommended reading: Decouple your HTML, CSS and Javascript.
First we need to understand that each of these statements that attach an event handler onto an element all run before the event handler can be executed. So in my previous example the following events are registered:
$("#button1").click()
$("#button2").click()
$("button[id^=myButton]").click();
$('.js-getcurrentvalue').on('click')
You'll notice that I've done what any compiler would do and reduce the variable into it's actual value. At the time the event handler is attached, index has no value. Since this isn't what you want, you could write it like:
$("button").click(function() {
var $this = $(this);
var id = $this.prop(id);
if ($this.is("[id^=myButton"+index+"]") {
// do something as index changes
}
});
But it's really ugly and introduces an abstraction of a value to used to compare. It's also very tightly coupled, that is we have to place an event on any object we want to change index and we have to write more code for each button. Yikes. Instead we can use classes and the data-attribute with data() to simplify and make this more robust.
$(document).ready( function(){
var selector;
$(".js-enable-button").on('click', function(){
selector = $(this).data('selector');
});
$('.js-enable-me').on('click', function() {
var $this = $(this);
if ($this.is(selector)) {
alert($this.val());
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="button" class="js-enable-button" value="Enable button -->" data-selector="#button1" />
<input type="button" class="js-enable-me" id="button1" value="Am I working?" /><br/>
<input type="button" class="js-enable-button" value="Enable button -->" data-selector="#button2" />
<input type="button" class="js-enable-me" id="button2" value="Or am I working?" /><br/>
Now the code is not limited to an Id. It's also not limited to a single selector. You could go crazy and just by adding only html the following continues to work for all elements. Notice I've added no additional code.
$(document).ready( function(){
var selector;
$(".js-enable-button").on('click', function(){
selector = $(this).data('selector');
});
$('.js-enable-me').on('click', function() {
var $this = $(this);
if ($this.is(selector)) {
alert($this.val());
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="button" class="js-enable-button" value="Enable button -->" data-selector="#button1" />
<input type="button" class="js-enable-me" id="button1" value="Am I working?" /><br/>
<input type="button" class="js-enable-button" value="Enable button -->" data-selector="#button2" />
<input type="button" class="js-enable-me" id="button2" value="Or am I working?" /><br/>
<br/>
<input type="button" class="js-enable-button" value="I enable the three below me using id" data-selector="#id1,#id2,#id3" /></br>
<input type="button" class="js-enable-me" id="id1" value="id1" /><br/>
<input type="button" class="js-enable-me" id="id2" value="id2" /><br/>
<input type="button" class="js-enable-me" id="id3" value="id3" /><br/>
<br/>
<input type="button" class="js-enable-button" value="I enable the three below me using a class" data-selector=".enable" /></br>
<input type="button" class="js-enable-me enable" value="I'm .enable 1" /><br/>
<input type="button" class="js-enable-me enable" value="I'm .enable 2" /><br/>
<input type="button" class="js-enable-me enable" value="I'm .enable 3" /><br/>

SelectAll does not call Event Handler

Please see the JavaScript below:
<html>
<head><title></title></head>
<body>
<script type = "text/javascript">
function Test()
{
alert('got here');
}
function SelectAll() {
var frm = document.forms[0];
for (i = 0; i < frm.elements.length; i++) {
frm.elements[i].checked=true;
}
}
</script>
<form>
<input type="checkbox" name="Test1" onClick="Test()"/>
<input type="checkbox" name="Test2" onClick="Test()"/>
<input type="checkbox" name="Test3" onClick="Test()"/>
<input type="checkbox" name="Test4" onClick="SelectAll()"/>
</form>
</body>
</html>
The alert box appears if I click either: Test1, Test2 or Test3. When I click Test4 I expect the alert to appear three times (once for Test1; once for Test2 and once for Test3). However, this does not happen. The event handler is not called at all. Why is this?
How can I amend the HTML so that the event handler is called three times.
You need to trigger onclick also:
frm.elements[i].onclick();
To avoid last element from click you need to reduce length in for-loop by 1, so final code should be:
function SelectAll() {
var frm = document.forms[0];
for (i = 0; i < ( frm.elements.length - 1 ); i++) {
frm.elements[i].checked=true;
frm.elements[i].onclick();
}
}

Multiple JavaScript Buttons (Variables)

I'm just beginning JavaScript, and I was wondering how to make different buttons do different things. So far, I can make one button do one thing, but how do I make a second button do a different thing? Here's the coding:
<html>
<head>
<script type="text/javascript">
function show_prompt()
{
var name=prompt("Your Name");
if (name!=null && name!="")
{
alert("Thanks for clicking " + name + "!");
window.top.location.replace("http://www.google.com");
}
}
</script>
</head>
<body>
<ul>
<li>
<input type="button" onclick="show_prompt()" value="Button One" />
</ul>
</body>
</html>
I will guess you meant like doing different things with different buttons but from the same function:
JavaScript:
function myFunction(str) {
if(str.length > 3){
alert("big");
}else{
alert("small");
}
}
HTML:
<input type="button" onclick="myFunction('test');" value="Button 1" />
<input type="button" onclick="myFunction('hi');" value="Button 2" />
In case my assumption is wrong, just create different functions and replace the button's onclick with their respective function
Define another function and bind the second button to it!
function alert_hi() {
alert("Hi!");
}
<input type="button" onclick="alert_hi()" value="Button Two" />
If that catches your interest I highly recommend Eloquent Javascript.
Making the second button do something is basically identical to making the first do something. It'd just be two functions and two buttons. I think this is what you're asking about.
<html>
<head>
<script type="text/javascript">
function doSomething()
{
// Do something when button one is clicked
}
function doSomethingElse()
{
// Do something else when button two is clicked
}
</script>
</head>
<body>
<input type="button" onclick="doSomething()" value="Button One" />
<input type="button" onclick="doSomethingElse()" value="Button Two" />
</body>
</html>
If you're serious about learning.. you can read up about Event Registration models.
in the case of your example.
js
var btn1 = document.getElementById('btn1'),
btn2 = document.getElementById('btn2');
btn1.addEventListener('click', show_me, false); // i am not IE friendly
btn2.addEventListener('click', show_me, false); // you can replace show_me with any function you would like.
function show_me() {
alert(this.value + ' was clicked'); // this references the element which the click event was invoked on.
}
html
<input type="button" id="btn1" value="Button One" />
<input type="button" id="btn2" value="Button Two" />

Categories