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>
Related
I used to host a website at carrd.co with the pro plus plan. I chose the expensive plan because of the possibility to download the website and host it on an own server.
What I did not know, was that this did not include server-side code.
My problem is, that I have the front end code, but every PHP code I try fails to interact with this code. Since I can only develop with Java, I cannot get to a solution by myself.
The issue is that I do not know what the next step is to make this code work on my server so that it successfully sends me an email when this form is submitted by a user. I do not have any backend code and do not know where to start.
1) where can i put a PHP file to answer to this request? How do i have to name it?
2) how can i parse the arguments?
3) how do i have to format the answer from the php script to the ajax script?
Could you guys please help here? Thanks a lot!!!
(i might even be able to solve this with some good hints if you cannot be bothered to provide a full solution! I'm thankful for any advice!)
The frontend code:
Form:
<form id="form02" method="post">
<div class="inner">
<div class="field"><input type="text" name="name" id="name" placeholder="Name"
maxlength="128"/></div>
<div class="field"><input type="email" name="email" id="email"
placeholder="Email" maxlength="128"/></div>
<div class="field"><input type="text" name="fname" id="-fname" placeholder="Fname"
maxlength="128"/></div>
<div class="field"><textarea name="message" id="message" placeholder="Message"
maxlength="16384"></textarea></div>
<div class="actions">
<button type="submit">Send Message</button>
</div>
</div>
<input type="hidden" name="id" value="form02"/>
</form>
Script:
function form(id, settings) {
var _this = this;
this.id = id;
this.mode = settings.mode;
this.method = settings.method;
this.success = settings.success;
this.preHandler = ('preHandler' in settings ? settings.preHandler : null);
this.failure = ('failure' in settings ? settings.failure : null);
this.optional = ('optional' in settings ? settings.optional : []);
this.$form = $('#' + this.id);
this.$form.addEventListener('submit', function (event) {
_this.submit(event);
});
this.$form.addEventListener('keydown', function (event) {
if (event.keyCode == 13 && event.ctrlKey) {
event.preventDefault();
event.stopPropagation();
_this.submit(event);
}
});
var x = $('#' + this.id + ' input[name="' + settings.hid + '"]');
if (x) {
x.disabled = true;
x.parentNode.style.display = 'none';
}
this.$submit = $('#' + this.id + ' button[type="submit"]');
this.$submit.disabled = false;
};form.prototype.notify = function (type, message) {
if (message.match(/^(#[a-zA-Z0-9\_\-]+|[a-z0-9\-\.]+:[a-zA-Z0- 9\~\!\#\#$\%\&\-\_\+\=\;\,\.\?\/\:]+)$/)) location.href = message; else alert((type == 'failure' ? 'Error: ' : '') + message);
};
form.prototype.submit = function (event) {
var _this = this, result, handler, fd, k, x, $f, $ff;
event.preventDefault();
if (this.$submit.disabled) return;
result = true;
$ff = this.$form.elements;
for (k in $ff) {
$f = $ff[k];
if ($f.type != 'text' && $f.type != 'email' && $f.type != 'textarea' && $f.type != 'select-one') continue;
if ($f.disabled) continue;
if ($f.value === '' || $f.value === null) {
if (this.optional.indexOf($f.name) !== -1) continue;
result = false;
} else {
x = '';
switch ($f.type) {
case 'email':
x = "^([a-zA-Z0-9\\_\\-\\.\\+]+)#([a-zA-Z0-9\\- \\.]+)\\.([a-zA-Z]+)$";
break;
case 'select':
x = "^[a-zA-Z0-9\\-]$";
break;
default:
case 'text':
case 'textarea':
x = "^[^\\<\\>]+$";
break;
}
result = result && $f.value.match(new RegExp(x));
}
if (!result) break;
}
if (!result) {
this.notify('failure', 'Missing and/or invalid fields. Please try again.');
return;
}
if (_this.method == 'get') {
_this.$form.submit();
return;
}
if (x = $(':focus')) x.blur();
this.$submit.disabled = true;
this.$submit.classList.add('waiting');
handler = function (values) {
var x, k, data;
data = new FormData(_this.$form);
if (values) for (k in values) data.append(k, values[k]);
x = new XMLHttpRequest();
x.open('POST', ['', 'post', _this.mode].join('/'));
x.send(data);
x.onreadystatechange = function () {
var result = false, message = 'Sorry, something went wrong. Please try again later.', alert = true, o;
if (x.readyState != 4) return;
if (x.status == 200) {
o = JSON.parse(x.responseText);
if (o) {
if ('result' in o) result = (o.result === true);
if (('message' in o) && o.message) message = o.message;
if ('alert' in o) alert = (o.alert === true);
}
}
_this.$submit.classList.remove('waiting');
if (result) {
_this.$form.reset();
if (alert) window.alert(message); else _this.notify('success', (_this.success ? _this.success : message));
} else {
if (alert) window.alert(message); else _this.notify('failure', (_this.failure ? _this.failure : message));
}
_this.$submit.disabled = false;
};
};
if (_this.preHandler) (_this.preHandler)(_this, handler); else (handler)();
};
new form('form02', {mode: 'contact', method: 'post', hid: 'fname', success: '#contact-done',});
An html form normally uses an action parameter to specify a url for the script to submit the form data to. However it looks like your javascript code is hard-coded to create an ajax post back to a url at /post/contact, which may explain why the examples you have tried do not work.
Yes, you do need a script of some kind on your server to process the response, but it doesn't have to be PHP - whatever your hosting provider supports, and whatever is capable of handling what you want to do with the data.
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
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.
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!
I am trying to explicitly get the system properties from my table but it is not working. I can see that the URL is returning all the data including these fields if I use https://myservice.azure-mobile.net/tables/todoitem?__systemProperties=* but on the code I cannot get it as item.__version or item.version. I have tried adding todoitemtable = WindowsAzure.MobileServiceTable.SystemProperties.All; but no success! I have also looked at http://azure.microsoft.com/en-us/documentation/articles/mobile-services-html-validate-modify-data-server-scripts/ but this is adding a new column instead of using the existing system columns.
$(function() {
var client = new WindowsAzure.MobileServiceClient('https://ib-svc-01.azure-mobile.net/', 'key');
var todoItemTable = client.getTable('todoitem');
// = WindowsAzure.MobileServiceTable.SystemProperties.All;
// Read current data and rebuild UI.
// If you plan to generate complex UIs like this, consider using a JavaScript templating library.
function refreshTodoItems() {
var query = todoItemTable.where({ complete: false });
query.read().then(function(todoItems) {
var listItems = $.map(todoItems, function(item) {
return $('<li>')
.attr('data-todoitem-id', item.id)
.append($('<button class="item-delete">Delete</button>'))
.append($('<input type="checkbox" class="item-complete">').prop('checked', item.complete))
.append($('<div>').append($('<input class="item-text">').val(item.id))
.append($('<span class="timestamp">'
+ (item.createdAt && item.createdAt.toDateString() + ' '
+ item.createdAt.toLocaleTimeString() || '')
+ '</span>')));
});
$('#todo-items').empty().append(listItems).toggle(listItems.length > 0);
$('#summary').html('<strong>' + todoItems.length + '</strong> item(s)');
}, handleError);
}
function handleError(error) {
var text = error + (error.request ? ' - ' + error.request.status : '');
$('#errorlog').append($('<li>').text(text));
}
function getTodoItemId(formElement) {
return $(formElement).closest('li').attr('data-todoitem-id');
}
// Handle insert
$('#add-item').submit(function(evt) {
var textbox = $('#new-item-text'),
itemText = textbox.val();
if (itemText !== '') {
todoItemTable.insert({ text: itemText, complete: false }).then(refreshTodoItems, handleError);
}
textbox.val('').focus();
evt.preventDefault();
});
// Handle update
$(document.body).on('change', '.item-text', function() {
var newText = $(this).val();
todoItemTable.update({ id: getTodoItemId(this), text: newText }).then(null, handleError);
});
$(document.body).on('change', '.item-complete', function() {
var isComplete = $(this).prop('checked');
todoItemTable.update({ id: getTodoItemId(this), complete: isComplete }).then(refreshTodoItems, handleError);
});
// Handle delete
$(document.body).on('click', '.item-delete', function () {
todoItemTable.del({ id: getTodoItemId(this) }).then(refreshTodoItems, handleError);
});
// On initial load, start by fetching the current data
refreshTodoItems();
});
I was trying to access the system properties from within the API scripts and found this and thought it was useful and relevant: http://www.brandonmartinez.com/2014/10/22/retrieve-system-properties-in-azure-mobile-services-javascript-backend/
Basically you can do this (example from the post):
myTable.read({
systemProperties: ['__createdAt', '__updatedAt'],
success: function(tableEntries) {
// So on and so forth
}
}