Return value from a function returns undefined - javascript

I have an html which has a form that a user could enter url if the value of the input text has www. in it i will create a variable and return it to the function then pass it to the ajax but it seems that when I check it(ajaxData var) in the console it says undefined.
<form action="" id="defaultForm">
<input type="text" id="url">
<button id="submit">Submit</button>
</form>
JS:
$(function () {
function myreturnValue() {
$('#defaultForm').submit(function () {
var w = 'www.';
var current = $('#url').val();
var appendW = w + current;
if (current.match('www.')) {
console.log('it already consists of www');
var returnValue = 'site_url:' + current; //site_url:www.domain.com or http://
console.log(typeof returnValue);
return returnValue;
} else {
var returnValue = 'site_url:' + appendW; //www+url
console.log(current);
console.log(appendW);
console.log(returnValue);
return returnValue;
}
}); //end submit
}
var ajaxData = myreturnValue();
console.log(typeof ajaxData);
var data = 'data:{' + ajaxData + '}';
});
then in the ajax I will pass the data variable. I hope my explanation is kinda clear.

Currently in your code, myreturnValue function only execute a code to register an event listener to your form, without return value (your return statement will only be triggered on submit event), so that's why it will return undefined at the first time.
Try this:
Put your url detect logic in myreturnValue function
Then put a code to prevent default submit event to be fired
Finally register a event listener for submit button.
And your original regex www. means match www with one other character, like wwww. and www0. will be valid. You may consider changing it to other regex like this one
$(function() {
function myreturnValue() {
var w = 'www.';
var current = $('#url').val();
var appendW = w + current;
if (current.match(w)) {
console.log('it already consists of www');
var returnValue = 'site_url:' + current; //site_url:www.domain.com or http://
console.log(typeof returnValue);
return returnValue;
} else {
var returnValue = 'site_url:' + appendW; //www+url
console.log(current);
console.log(appendW);
console.log(returnValue);
return returnValue;
}
}
$('#defaultForm').submit(function(e) {
e.preventDefault();
});
$('#submit').on('click', function() {
var data = 'data:{' + myreturnValue() + '}';
console.log(data);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="" id="defaultForm">
<input type="text" id="url">
<button id="submit">Submit</button>
</form>

A few problems here.
Calling $('#defaultForm').submit(function () { binds a submit handler to the form. It does not submit the form nor execute the function. Please familiarize yourself with the documentation.
Your myreturnValue() doesn't return anything. You only have one top level line which is the above submit binding. Not only is it not executed, but return inside that function does not propagate up like you're expecting it to. Returning inside an event handler won't do anything in any context.
Don't declare vars inside if branches in general.
Here's a quick attempt to reorganize this code, but with this many problems the corrected code may depend on your specific needs.
(function () {
$('#defaultForm').submit(function (event) {
// prevent default form submit
event.preventDefault();
var w = 'www.';
var current = $('#url').val();
var appendW = w + current;
var value;
if (current.match('www.')) {
console.log('it already consists of www');
value = 'site_url:' + current; //site_url:www.domain.com or http://
console.log(typeof returnValue);
} else {
value = 'site_url:' + appendW; //www+url
console.log(current);
console.log(appendW);
console.log(returnValue);
}
var data = 'data:{' + ajaxData + '}';
// Do whatever you want with data here
});
// If you want to now submit the form by hand...
$('#defaultForm').submit();
});

In your code, the myreturnValue() is only return the returnValue of the function in Submit. 'myreturnValue' function return anything because it doesn't any return value.
You executed unnecessary function to get the ajaxData.
To get the ajaxData, You only need to
$('#defaultForm').submit(function () {
contents
}
If fix the code simple...
$('#defaultForm').submit(function () {
var returnValue;
var w = 'www.';
var current = $('#url').val();
var appendW = w + current;
if (current.match('www.')) {
console.log('it already consists of www');
returnValue = 'site_url:' + current; //site_url:www.domain.com or http://
console.log(typeof returnValue);
} else {
returnValue = 'site_url:' + appendW; //www+url
console.log(current);
console.log(appendW);
console.log(returnValue);
}
console.log(typeof returnValue);
var data = 'data:{' + ajaxData + '}';
console.log('data : ', data)
});
Please, Note : http://codepen.io/onyoon7/pen/mRdJJV

Related

How can i use same private variable in 2 functions

So im having 2 functions. Problem is in styep_id variable. I know that i can just declare it in second functions, but then he wont take out data from first function. So the question is how i can use the same variable without lost data on him
P.S It shouldn't be public variable, cos it wont work. It wont hold the data.
function delete_estimate_position_type() {
var estpt_tr_jqobj, estpt_action_links_td_jqobj, styep_id, authenticity_token, request_url, stya_id;
styep_id = $(this).attr("styep_id");
// Ja ir tikko kā pievienots, tad tikai izmetīsim ārā no DOM
if (!styep_id == "") {
estpt_action_links_td_jqobj = $(this).parent();
estpt_tr_jqobj = estpt_action_links_td_jqobj.parent();
stya_id = $("td.service-type-est-position-estimate-position-type-name>input.stya-id-for-styep", estpt_tr_jqobj).val();
estpt_tr_jqobj.remove();
show_stya_delete_link_if_possible(stya_id);
remove_estpgt_if_has_no_estpt($(this).attr("estpgt_id"));
}
}
And
function save_configuration(){
var estpt_for_estpgt = "";
// Pārbaudam vai visām tāmes pozīciju grupām ir norādītas tāmes pozīcijas
$('.estpt-for-estpgt').each(function(){
if ($(this).find('tr.action_record_tr').size() == 0){
estpt_for_estpgt = this;
return false;
}
})
if (estpt_for_estpgt == "") {
var form = $(this).closest('form');
form.submit();
// Dzēsīsim ārā no datu bāzes
authenticity_token = $("#authenticity_token").val();
request_url = "/service_type_est_positions/" + styep_id + "/destroy_from_service_type_config";
$.post(request_url, { authenticity_token: authenticity_token}, process_service_type_est_position_delete, "json");
} else {
$.alerts.okButton = 'Labi';
jError("Vismaz vienai Tāmes pozīciju grupai nav norādīta neviena Tāmes pozīcija!", "Kļūda");
}
return false;
}
function remove_estpgt_if_has_no_estpt(estpgt_id) {
// Paskatīsimies vai eksistē kāda tāmes pozīcija
if ($("#estpt_for_" + estpgt_id + ">tr:first").size() == 0) {
$("#estpgt_" + estpgt_id).remove();
$("#estpt_tr_for_" + estpgt_id).remove();
}
}
call your second function within the first and pass the variable as an argument:
function delete_estimate_position_type() {
save_configuration(styep_id)
}
function save_configuration(id){
request_url = "/service_type_est_positions/" + id + "/destroy_from_service_type_config";
}
You can use like this
function delete_estimate_position_type() {
var estpt_tr_jqobj, estpt_action_links_td_jqobj, styep_id, authenticity_token, request_url, stya_id;
styep_id = $(this).attr("styep_id");
// your other code goes here.....
// Your variable pass as argument
remove_estpgt_if_has_no_estpt($(this).attr("estpgt_id"),styep_id.val() );
}
}
// Get it from argument.
function remove_estpgt_if_has_no_estpt(estpgt_id,styep_id ) {
// Paskatīsimies vai eksistē kāda tāmes pozīcija
if ($("#estpt_for_" + estpgt_id + ">tr:first").size() == 0) {
$("#estpgt_" + estpgt_id).remove();
$("#estpt_tr_for_" + estpgt_id).remove();
}
}
Another option is set it in hidden field.
// html
<input type = "hidden" id="styep_id_newval" value="">
// End of html
function delete_estimate_position_type() {
var estpt_tr_jqobj, estpt_action_links_td_jqobj, styep_id, authenticity_token, request_url, stya_id;
styep_id = $(this).attr("styep_id");
// your other code goes here.....
$("#styep_id_newval").(styep_id.val());
// Your variable pass as argument
remove_estpgt_if_has_no_estpt($(this).attr("estpgt_id"),styep_id.val() );
}
}
Now you can easily access code using anywhere.
$("styep_id_newval").val();

Is there a way to stop Form from executing action and wait for ajax to complete executing?

Before customers can proceed to paypal, I have a quick check on the database to see if the items still available,. The problem im having is that while Ajax is executing. function check_availability continue executing and returns true to the Form onsubmit before the completion of Ajax. To fix that problem I kept calling the same function within. But I dont think that is the best possible option.
Here is the code:
<form onsubmit="return check_availability(0,0,1)" action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post" id="pp1">
function ajax_paypal(orders){
var htpr = new XMLHttpRequest();
var url = "Hi there";
var val = "orders="+orders;
htpr.open("POST", url, true);
htpr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
htpr.onreadystatechange = function(){
if(htpr.readyState == 4 && htpr.status == 200){
var sold_out_ids = htpr.responseText;
check_availability("continue", sold_out_ids, 0);
}
};
htpr.send(val);
}
function check_availability(str, sold_out_ids, n) {
if (str === "continue") {
if (sold_out_ids > 0) {
alert("One of your items has sold out! Sorry for any inconvenience");
location.reload();
return false;
} else {
return true;
}
}else if(n === 1){
var orders = [];
var x = document.cookie.split(';'); // your array of cookies
var i = 0;
x.forEach(item => {
//to make sure that item contains "order"
if (item.indexOf('order') > -1) {
var val = item.split("=");
orders[i] = val[1]+"o";
i++;
}
});
ajax_paypal(orders);
}
check_availability(0, 0, 0);//I keep calling this until Ajax is completed
}
You can use following code snippet to solve. This will be called on submit but before actual submit happen if you return true from here form will get submit to paypal. If you return false form won't get submit.
$('#pp1').submit(function() {
var submitOrNot=await callcheck_availability();
return true; // return false to cancel form submit
});
async function callcheck_availability(){
//your function goes here
}
for more on async await read this page on MDN

Stop form from redirecting?

This question has been asked and answered quite a few different times. I've searched around SO and couldn't find a solution that worked. I tried e.preventdefault() and return false. Neither worked. Then I saw that I need to go back to AJAX and can't use a promise and I refuse to do so and I refuse to think that there isn't a way to do it with promises.
Anyway,
Code:
var submitDataForm = function () {
console.log("button called");
var email = document.getElementById('email');
var first = document.getElementById('first-name');
var last = document.getElementById('last-name');
var web = document.getElementById('domain');
var city = document.getElementById('city');
var obj = document.getElementById('obj');
var describe = document.getElementById('describe');
var brandpower = document.getElementById('brandpower');
if (email.checkValidity() && first.checkValidity() && web.checkValidity() && city.checkValidity() && obj.checkValidity()) {
var emailV = email.value;
var firstV = first.value;
var webV = (web.value == undefined) ? 'null' : web.value;
var cityV = city.value;
var objV = obj.options[obj.selectedIndex].value;
var describeV = (describe && describe.options && describe.selectedIndex) ? describe.options[describe.selectedIndex].value : describe.value;
var brandpowerV = (brandpower && brandpower.options && brandpower.selectedIndex) ? brandpower.options[brandpower.selectedIndex].value : brandpower.value;
var radio = jQuery('input[name="dealer"]:checked').val();
jQuery.post("/form-one/?" + "email=" + emailV + "&first=" + firstV +
cityV + "&domain=" + webV + "&obj=" + objV + "&describe=" + describeV + "&brandpower=" + brandpowerV +
"&radio=" + radio, function () {
console.log("data sent");
})
.done(function () {
console.log("data success");
})
.fail(function () {
console.log("data failed");
})
.always(function () {
console.log("data finished");
email.value, first.value, web.value, city.value, obj.value, describe.value, brandpower.value = "";
//window.location.href = "/";
});
} else {
$('#error').css('display', 'block').delay(5000).queue(function (next) {
jQuery('#error').fadeOut('slow').css('display', 'none');
});
}
}
<button id="next" class="green-button" onClick="submitDataForm()">Next</button>
Again, I'm trying to have the form do nothing but submit data (will add custom events later) without refresh or reload.
Thank you!
event.preventDefault does indeed work. As nnnnnn pointed out, you dont show where you tried it but I suspect that you were not using it correctly, more than likely, you were not passing the event into the handler and e or event (whatever you named it) was actually undefined. Here is an example of one way to use it properly:
$('.ajax-submit').click(function(event) {
event.preventDefault();
console.log("button called");
//... all your other code here
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="">
<button id="next" class="green-button ajax-submit" > Next</button>
</form>

How to return false from a main function after an ajax callback?

I perform an edit to ensure against duplicate emails by making an ajax call and supplying a callback. If a duplicate exists, I want to return false from submit event. Is there an elegant way to achieve this without setting async=false? What I tried (see emailCallback) is not working.
submit event
EDIT (included the rest of the submit handler).
$("#form-accounts").on("submit", function (e) {
e.preventDefault();
if (!$(this).get(0).checkValidity()) return false;
if (!customValidation(true, false)) return;
checkDupEmail(emailCallback);
function emailCallback(result) {
if (result) return (function () { return false } ());
}
if ($("#submit").text() == "Create Account") {
var formData = $("#form-accounts").serialize().replace("''", "'");
ajax('post', 'php/accounts.php', formData + "&action=create-account", createSuccess);
function createSuccess(result) {
if (isNaN(result)) {
showMessage(0, result);
return;
}
localStorage.setItem("account-id", result);
debugger
setUsertype($("input[name=user-type]:checked").val());
showMessage(1, "Account Created");
};
return
}
var rString = randomString(32, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
function randomString(length, chars) {
var result = '';
for (var i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
return result;
};
var anRandom = randomString(14, rString);
$("#code").val(anRandom);
console.log("v-code=" + anRandom);
$("#submit").css({ 'display': 'none' });
$("#verify").css({ 'display': 'block' });
var subject = "Writer's Tryst Verification Code"
$("#subject").val(subject);
var msg = "This mail is intended for the person who requested verification of email ownership at Writers-Tryst (" + getWriterTrystURL() + ").\n\n" + "Double click on the code below and then copy it. Return to our website and and paste the code.\n\nYour verification code: \n\n" + anRandom;
$("#msg").val(msg);
var formData = $("#form-accounts").serialize().replace("''", "'");
ajax('post', 'php/sendmail.php', formData, successMail, "create-account error: ");
function successMail(result) {
$("#ver-email-msg").val("An email has been sent to you. Double-click the verification code then copy and paste it below.").css({ 'display': 'block' });
}
});
function checkDupEmail(callback) {
var data = {};
data.action = "validate-email";
data.email = $("#email").val();
ajax('post', 'php/accounts.php', data, emailSuccess);
function emailSuccess(result) {
if (parseInt(result) > 0) {
showMessage(0, "The email address is in use. Please supply another or login instead of creating a new account.")
callback(true);
} else callback(false);
}
}
Instead of passing a callback, why don't you just submit the form when your Ajax call completes successfully?
$("#form-accounts").on("submit", function (e) {
// Always cancel the submit initially so the form is not submitted until after the Ajax call is complete
e.preventDefault();
...
checkDupEmail(this);
...
});
function checkDupEmail(form) {
var data = {};
data.action = "validate-email";
data.email = $("#email").val();
ajax('post', 'php/accounts.php', data, function(result) {
if (parseInt(result) > 0) {
showMessage(0, "The email address is in use. Please supply another or login instead of creating a new account.")
} else {
form.submit();
}
}
}
A better approach than that would be to submit your form using Ajax. That would eliminate the need for two calls to the server.

Javascript 'onbeforeunload()' not working with a function call

I have this script below which is used in a survey. The problem I have is, onbeforeunload() works when I don't call a function inside it. If I make any function call(save_survey() or fetch_demographics()) inside it, the browser or the tab closes without any prompt.
<script type="text/javascript">
$(document).ready(function() {
$('#select_message').hide();
startTime = new Date().getTime();
});
loc = 0;
block_size = {{ block_size }};
sid = {{ sid }};
survey = {{ survey|tojson }};
survey_choices = '';
startTime = 0;
demographics_content = {};
function save_survey(sf)
{
var timeSpentMilliseconds = new Date().getTime() - startTime;
var t = timeSpentMilliseconds / 1000 / 60;
var surveydat = '';
if(sf==1)
{ //Success
surveydat = 'sid='+sid+'&dem='+JSON.stringify(demographics_content)+'&loc='+loc+'&t='+t+'&survey_choice='+JSON.stringify(survey_choices);
}
if(sf==0)
{ //Fail
surveydat = 'sid='+sid+'&dem='+json_encode(demographics_content)+'&loc='+loc+'&t='+t+'&survey_choice='+json_encode(survey_choices);
}
//Survey Save Call
$.ajax({
type: 'POST',
url: '/save_surveyresponse/'+sf,
data: surveydat,
beforeSend:function(){
// this is where we append a loading image
$('#survey_holder').html('<div class="loading"><img src="/static/img/loading.gif" alt="Loading..." /></div>');
},
success:function(data){
// successful request; do something with the data
$('#ajax-panel').empty();
$('#survey_holder').html('Success');
alert("Dev Alert: All surveys are over! Saving data now...");
window.location.replace('http://localhost:5000/surveys/thankyou');
},
error:function(){
// failed request; give feedback to user
$('#survey_holder').html('<p class="error"><strong>Oops!</strong> Try that again in a few moments.</p>');
}
});
}
function verify_captcha()
{
// alert($('#g-recaptcha-response').html());
}
function block_by_block()
{
var div_content ='<table border="0" cellspacing="10" class="table-condensed"><tr>';
var ii=0;
var block = survey[loc];
var temp_array = block.split("::");
if(loc>=1)
{
var radio_val = $('input[name=block_child'+(loc-1)+']:checked', '#listform').val();
//console.log(radio_val);
if(radio_val!=undefined)
survey_choices += radio_val +'\t';
else
{
alert("Please select one of the choices");
loc--;
return false;
}
}
for(ii=0;ii<block_size;ii++)
{
//Chop the strings and change the div content
div_content+="<td>" + temp_array[ii]+"</td>";
div_content+="<td>" + ' <label class="btn btn-default"><input type="radio" id = "block_child'+loc+'" name="block_child'+loc+'" value="'+temp_array[ii]+'"></label></td>';
div_content+="</tr><tr>";
}
div_content+='<tr><td><input type="button" class="btn" value="Next" onClick="survey_handle()"></td><td>';
div_content+='<input type="button" class="btn" value="Quit" onClick="quit_survey()"></td></tr>';
div_content+="</table></br>";
$("#survey_holder").html(div_content);
//return Success;
}
function updateProgress()
{
var progress = (loc/survey.length)*100;
$('.progress-bar').css('width', progress+'%').attr('aria-valuenow', progress);
$("#active-bar").html(Math.ceil(progress));
}
function survey_handle()
{
if(loc==0)
{
verify_captcha();
$("#message").hide();
//Save the participant data and start showing survey
fetch_demographics();
block_by_block();
updateProgress();
$('#select_message').show();
}
else if(loc<survey.length)
{
block_by_block();
updateProgress();
}
else if(loc == survey.length)
{
//Save your data and show final page
$('#select_message').hide();
survey_choices += $('input[name=block_child'+(loc-1)+']:checked', '#listform').val()+'\t';
//alert(survey_choices);
//Great way to call AJAX
save_survey(1);
}
loc++;
return false;
}
</script>
<script type="text/javascript">
window.onbeforeunload = function() {
var timeSpentMilliseconds = new Date().getTime() - startTime;
var t = timeSpentMilliseconds / 1000 / 60;
//fetch_demographics();
save_survey(0);
return "You have spent "+Math.ceil(t)+ " minute/s on the survey!";
//!!delete last inserted element if not quit
}
</script>
I have checked whether those functions have any problem but they work fine when I call them from different part of the code. Later, I thought it might be because of unreachable function scope but its not the case. I have tried moving the onbeforeunload() at the end of script and the problem still persists. Wondering why this is happening, can anyone enlighten me?
I identified where the problem was. I am using json_encode instead of JSON.stringify and hence it is crashing(which I found and changed already in sf=1 case). That tip with debugger is invaluable. Also, its working fine even without async: false.
Thank you again #AdrianoRepetti!

Categories

Resources