buttons that calls two actions - javascript

I wanted to create a button that shows the pop up to show the user that the OTP code has sent to their mobile phone, and also be able to link it to another "Verify OTP Code" page to let the user type in the verification code that is sent to their mobile phone. How do I create a button that calls two functions when it is being clicked? I tried the code below and it is not working at all. Can someone provide me an answer on how to create a button that calls two actions when it is clicked?
This my button in the HTML code:
<div class="col-md-12">
<div class="form-group">
<input type="text" id="number" name="phone" class="form-control" placeholder="Phone Number" required>
<br>
<div id="recaptcha-container"></div>
<button id="verify"class="block"type="button" onclick="one(); phoneAuth();">
Send Verification Code
</button>
</div>
</div>
This is my JavaScript code:
window.onload = function () {
render();
};
function render() {
window.recaptchaVerifier = new firebase.auth.RecaptchaVerifier('recaptcha-container');
recaptchaVerifier.render();
}
function one() {
window.location.href = 'insert.php';
}
function phoneAuth() {
//get the number
var number=document.getElementById('number').value;
//phone number authentication function of firebase
//it takes two parameter first one is number,,,second one is recaptcha
firebase
.auth()
.signInWithPhoneNumber( number, window.recaptchaVerifier )
.then(
function ( confirmationResult ) {
//s is in lowercase
window.confirmationResult = confirmationResult;
coderesult = confirmationResult;
console.log(coderesult);
alert("Message sent");
}
)
.catch(
function (error) {
alert(error.message);
}
);
}
function codeverify() {
var code = document.getElementById('verificationCode').value;
coderesult
.confirm(code)
.then(
function ( result ) {
alert("Phone Number Verified");
var user=result.user;
console.log(user);
}
)
.catch(
function ( error ) {
alert(error.message);
}
);
}

Just make one function buttonClicked() and set it onClick of the button:
function buttonClicked()
{
phoneAuth();
codeverify();
}
When the button is clicked, this function will run and fire the two inner functions. Make sure, that you place it after the both definitions of phoneAuth() and codeverify().

you are already sent to insert.php before you can do the phoneAuth().
So I would suggest you use ajax for calling insert.php like this
function one(){
$.ajax({
url: insert.php,
method: 'YOUR_METHOD_POST_GET_OR_OTHER',
success: function(result){
//Do something with the response if you want
},
error: function(xhr, status, error){
//Show error or something here
}
});
}

There are many ways to achieve what you're after...but my preference is simply to write a "controller function" that executes as many subfunctions as you need:
function one() {
// does the first thing
}
function two() {
// does another thing
}
function controller() {
one();
two();
}
<button id="verify" class="block" type="button" onclick="controller();">
That all being said, you CAN call multiple functions with your onclick. But I think the problem you're facing is that the first function you call (one()) is requesting another page (window.location.href). When your function executes, you're effectively leaving the page and unloading the javascript from memory. In other words, you may be aborting the the page/script before the second function has a chance to execute. You need to change the order of your functions, use a controller function and execute your functions within the controller in the appropriate order...or use ajax/async methods in your functions. Also...make sure you have spaces between all your html attributes in your button tag. You didn't have spaces between id, class, and type...and that might be causing the failure as well.
Additionally, this question has been answered before...

How do I create a button that calls two functions when it is being
clicked?
To add one or multiple event listeners to a DOM element, use addEventListener
See: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
To remove one or multiple event listeners from a DOM element, use removeEventListener
See: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener
With the above in mind, a clean, unobtrusive replacement for the inline attribute:
onclick="one(); phoneAuth();"
would be:
const verifyButton = document.getElementById('verify');
verifyButton.addEventListener('click', one, false);
verifyButton.addEventListener('click', phoneAuth, false);

Related

How to make JavaScript run after an ajax request updates HTML

My code involves fetching some data using jQuery's Ajax. I then append the result I get from the server to html (in form of buttons). All buttons have a class name mybutton. A separate JavaScript file handles the button click events. Everything works okay for the first Ajax call but I then get an error on second Ajax call. The Ajax calls are made at an interval
HTML code
<button class="mybutton">Button 1</button>
Javascript Code in a SCRIPT1.js file
document.addEventListener("DOMContentLoaded", ready);
function ready() {
let buttons = document.querySelectorAll(".mybutton");
buttons.forEach((button) => {
button.addEventListener("click", () => {
//do some stuff
console.log("I was Clicked");
});
});
}
jQuery CODE in a SCRIPT2.js file
$(document).ready(() => {
//append the html to add more buttons after some time
setInterval(() => {
$.ajax({
method: "GET",
url: "/getButtons",
async: true,
success: function (data, status, xhr) {
data.forEach((item) => {
$("body").append(
'<button class="mybutton">' + item + "</button>"
);
});
const scriptsrc = document.createElement("script");
scriptsrc.setAttribute("type", "text/javascript");
scriptsrc.setAttribute("src", "//script location here");
$("head").append(scriptsrc);
},
});
}, 10000);
});
The JavaScript attached to the buttons only fires up only once after the first Ajax request.The second time I get an error:
Uncaught SyntaxError: Identifier 'buttons' has already been declared
Can you try with the following script? To clarify if the 'let buttons' is issue or the ready() function is overriding the existing one.
document.addEventListener("DOMContentLoaded", init_fun);
function init_fun() {
document.querySelectorAll(".mybutton").forEach((button) => {
button.addEventListener("click", () => {
//do some stuff
console.log("I was Clicked");
});
});
}
Updated due to the comment.
In this case, if you are injecting the script1 after your ajax call, you will have multiple script tags which include multiple variables with the same name.
Instead of adding the whole script, call the function after the success callback of the ajax call. That should avoid multiple variable issues.

How to prevent executing javascript code before data is entered in jquery dialog form

I'm trying to develop reusable function based on a jQuery dialog form, as a replacement for JS prompt. I need user to input data before other JS code is executed (the AJAX request that follows depends on the input of the user).
The function should read one text field and return the value entered if OK button or Return are pressed.
I managed to create the function with callback and it is working, except it doesn't wait for the user to react and the code after the function is executed.
I understand that jQuery calls are asynchronous and tried versions with deferred option, but that didn't work either.
Is there any way to make my code wait for the user input before it continues executing? Of course, the ideal solution would be to use like var userInput = getTxtField(....);
Update:
The function getTxtField is triggered by other user actions (buttons): renameFile, renameFolder, addFile etc.
Update #2 Problem solved
Thanks to #SuperPrograman's suggestion I started thinking with the logic of asynchronous execution. The original code was developed with value = prompt(...) approach and the AJAX code was at the bottom of the single function. I simply took the AJAX code in a separate function and now it works as expected. I've updated the JS code at the bottom.
My code is the following
....
<div class='hidden' id='dialog-newName' title=''>
<label id='label-txtField' for="txtField"></label>
<input type="text" name="txtField" id="txtField" value="" class="text ui-widget-content ui-corner-all">
</div>
....
function getTxtField (title, label, defVal, callBack) {
$('#label-txtField').text(label);
$('#txtField').val(defVal);
$( '#dialog-newName' ).dialog({
modal: true, closeOnEscape: false,
height: 200, width: 500,
title: title,
buttons: {
OK: function() {
callBack('OK', $('#txtField').val());
$(this).dialog( "close" );
},
Cancel: function() {
$('#txtField').val('');
//callBack('Cancel', ''); // not necessary
$(this).dialog( "close" );
}
},
});
}
...
switch (action) {
case 'action1':
// user pressed button for Action1
console.log('before dialog getTxtField ');
getTxtField('Action1', 'Label1', 'defaultValue1', function(buttonP, result) {
console.log(buttonP + ' value=' + result); // prints OK
});
// executed before input finished
console.log('after dialog getTxtField returnVal=' + newName + ')');
break;
case 'action2':
// ....
break;
}
// proceed with AJAX request for selected action
...
//=========================
// working code
//=========================
$('.selector').click ( function() {
var frmId = $(this).closest('form').attr('id');
var action = $(this).attr('ajaxAction');
var form = $('#theForm')[0];
var ajaxData = new FormData(form);
switch action {
case 'actions that do not require function getTxtField':
ajaxData.append(specific data for the action);
ajaxCall (frmId, ajaxData);
break;
case 'actions that with function getTxtField':
getTxtField('Titlexx', 'Labelxx', 'defaultValuexx', function(buttonP, result) {
// process result
ajaxData.append(specific data for the action);
ajaxCall (frmId, ajaxData);
});
break;
}
})
function ajaxCall (id, data) {
// standard ajax code
}
Since my comment helped, I'll add answer for quick access.
Basically you want to format code so everything that comes after dialog runs inside callback directly or is initiated from the callback.
So assuming a simple getTxtField prompt method taking a message and a callback function, instead of:
stuffBeforePrompt();
getTxtField('stuff', function() { });
stuffAfterPrompt();
You'll just need:
stuffBeforePrompt();
getTxtField('stuff', function() {
stuffAfterPrompt();
});
Perhaps you could make some solution using 'threads' or workers where you run prompt on separate thread and sleep main until result (or vice versa); but I doubt that would be worth the slight usage convenience.

whacky closures and ajax questions

I'm super confused by my code. Let me show what it looks like:
$(document).ready(function ($) {
var customer_exists = false;
$.get(window.additional_parameters.customer_exists_url, "json")
.done(function () {
customer_exists = true;
})
.always(function () {
// Don't make request to buy clickable until we know if the customer exists
$('#request-to-buy').on('click', function(e) {
request_to_buy(customer_exists);
});
});
function request_to_buy(customer_exists) {
response = can_request_to_buy();
response.done(function (response) {
if (customer_exists) {
// Actually create the request on the server
$.post(window.additional_parameters.request_to_buy_url,
{'ticket_id': window.additional_parameters.ticket_id},
"json")
.done(function (response) {
request_to_buy_success(response);
})
.fail(function () {
var message = handle_ajax_response(response);
show_ajax_message(message);
});
} else {
show_pre_stripe_popup();
}
})
.fail(function (response) {
var error_message = handle_ajax_response(response);
show_ajax_message(error_message, 'danger');
});
}
$(document).ready(), we set a variable called customer_exists. This variable guides the path of the code afterwards and is pretty important. If the $.get AJAX request is successful, it's true, otherwise it remains it default value of false. After the AJAX response, we attach a click event to "#request-to-buy." My goal here is to create a closure and pass in the value of customer_exists that was just set. This doesn't happen.
A good portion of the time ( I had it work correctly once or twice ), when I inspect request_to_buy in the debugger, I can see that customer_exists is a jQuery click event. why ??? Shouldn't it take on the value of the customer_exists from the surrounding scope of where the function was created? Can anyone explain what is going on here?
Thank you
EDIT: Here's a little more information that describes how it works sometimes...
The first time that I click '#request-to-buy', the handler is
function(e) {
request_to_buy(customer_exists);
}
This is what we would expect. e contains the click event, customer_exists retains it's value, and everything works inside request_to_buy.
Every time I click '#request-to-buy' after the first, instead of the above function being called, request_to_buy is called directly, and instead of passing in customer_exists in the first parameter, the click event is passed in instead. I hope this helps someone.
You should be able to do this without the need for the cumbersome outer var customer_exists.
For example :
$(document).ready(function ($) {
$.get(window.additional_parameters.customer_exists_url, "json").then(function () {
// Don't make request to buy clickable until we know if the customer exists
$('#request-to-buy').on('click', request_to_buy);
}, function() {
$('#request-to-buy').on('click', show_pre_stripe_popup);
});
function request_to_buy(e) {
e.preventDefault();
can_request_to_buy().then(function(response) {
// Actually create the request on the server
$.post(window.additional_parameters.request_to_buy_url, {
'ticket_id': window.additional_parameters.ticket_id
}, "json").then(request_to_buy_success, function() {
show_ajax_message(handle_ajax_response(response));
});
}).fail(function(response) {
show_ajax_message(handle_ajax_response(response), 'danger');
});
}
}
show_pre_stripe_popup will also be passed an event and you may need to do e.preventDefault(); there too.
You will need to check that the correct parameters are passed to the various error handlers. I can't verify them.
If it still doesn't work, then you must suspect other code that's not included in the question, for example the function can_request_to_buy().
var customer_exists = false;
Declare this outside of ready block.

Simple Javascript Calling function not working/don't know how to get it to work

I'm trying to call a function and not the alert and I thought it was as easy as just doing something like this: FunctionsName(); and delete the alert(''); but it's not working for me :(
Can someone please look at the code I have below and tell me what is wrong ?
Thank you so much!!
<script type="text/javascript">
var comper;
function checkComper() {
var onResponse = function(comperNow) {
if (comper === undefined) {
comper = comperNow;
return;
}
if (comper !== comperNow) {
// show a message to the visitor
alert("New Info Added"); // <--*** I WANT TO TAKE THIS OUT AND CALL $("#append").click(function(e)
comper = comperNow;
}
};
$.get('getlastupdate.php', onResponse);
}
var tid = setInterval(checkComper, 2000);
$(function() {
var $table = $("table.tablesorter");
$("#append").click(function(e) {
e.preventDefault();
$.get('updatetable.php', function(data)
{
$table
.find('tbody')
.html('')
.append(data);
$table.trigger("update", [true]);
});
});
/*........ and so on.... */
</script>
What about changin that :
alert("New Info Added");
to that :
$('#append').trigger('click');
It will simulate a click and trigger the function.
One thing important to distinguish:
alert("New Info Added") is a function. Actually, alert() is a function, being passed the parameter "New Info Added".
$('#append').click(function(e) { is not a function, at least, not in the same way. $('#append') is a jQuery selector function, which selects all elements with an id of "append". $('#append').click() is a function that sets a click event on all elements returned in the selector.
What the whole syntax of $('#append').click(function(e) { means is on its own a syntax error. What you're doing is telling the elements found in the selector what their click function should be. But the function(e) { says that it's the start of the code of the function. That line of code isn't complete until the ending }) - the } closing the function declaration and the ) closing the call to click.
So, you can't simply replace alert("New Info Added"), which is a complete function call, with $('#append').click(function(e) {, because it's a syntax error - you haven't completed the function(e) declaration, nor the click function call. You can trigger the click function, as Karl's answer told you. Or, you can use the shortcut:
$('#append').click()
Note that this is a full proper sentence, and can therefore replace the alert.

Javascript , event handler is always called, even if the event is not raised

i have the following code which extends the JQuery and adds a method to the JQuery:
$.fn.attachWithMessage = function () {
$(this).focusin(showMessage());
}
function showMessage() {
alert('hi');
}
so I can use that code as follows :
<input type="text" name="name" id="textbox" />
$(document).ready(function () {
$("#textbox").attachWithMessage ();
});
when I load the page for the first time, a message box shows up with ('hi') message.
even if I didn't click in the text box.
I also tried the click event, and the message still shows automatically.
any ideas ??
The issue here is that when you pass showMessage() as a parameter to focusin, the function showMessage is executed and the return value is passed to focusin.
Instead you need to pass a reference to the function (without the paranthesis).
Use the following code to extend:
$.fn.attachWithMessage = function () {
$(this).focusin(showMessage);
}
Working example# http://jsfiddle.net/eXEP5/
EDIT:
If you want to pass a parameter to showMessage then try this:
$.fn.attachWithMessage = function () {
var param1 = "Some Param";
$(this).focusin(function(){
showMessage(param1); //Make sure showMessage is modified accordingly for the parameters.
});
}
just remove the parenthesis
$(this).focusin(showMessage());
should be
$(this).focusin(showMessage);
Hope this helps

Categories