I've written some JavaScript/jQuery code that adds a users email to my newsletter database. There is a "subscribe" button to start the process, but I also wanted the user to be able to hit return for usability.
Weirdly, the code works for both the button and when the return key is hit in that the email is added to the database, but the callback function which just displays an alert is only triggered when the button is hit, not when the return key has been pressed.
$('#newsletter_button').click(function(event) {
newsletterSignup();
});
$('#newsletter_email').bind('keyup', function(event) { newsReturn(event); });
function newsletterSignup() {
var email = $.trim($('#newsletter_email').val());
if(!validateEmail(email)) {
alert('Please enter a valid email');
return false;
} else {
// add email to database
$.post('newsletterSignup.php',
{ email: email },
function(data) {alert(data);}
);
$('#newsletter_email').val("");
}
}
function newsReturn(evt) {
if (evt.keyCode == 13) {
newsletterSignup();
}
}
The function has to work the same no matter how it's been called surely! Like I say the post function is obviously being called both times because the email is being added to the database.
The only thing I can think of is that it's something to do with events. Not sure what though.
Browser behaviour for what happens when Enter is pressed is quirky. Whether the submit button is considered to be ‘clicked’ on Enter press varies between browsers and also depends on (a) the number of buttons in the form, and (b) the number of text inputs in the form. Typically when there is one text field and one button, the button won't be considered ‘successful’, you won't get a click event, and the button's name/value pair wouldn't be included in the submitted form values.
Additionally, trapping Enter keypresses in input fields is unreliable and shouldn't be done. This will fire in various circumstances when the Enter press shouldn't submit the form (eg when IMEs are in use), won't fire in places that should submit the form (eg some other element in the form has focus), and again there are browser differences.
So avoid all this pain: always bind to the submit event on the <form> containing the elements, instead of trying to second-guess what UI events should trigger that submission.
The first thing I can think of is evt.keyCode -- try using evt.which (a jQuery property which unifies the different browser behaviors).
Edit: Now I noticed the second alert. Your code is a tad messy, let's clean it up and see if the problem persists:
$('#newsletter_button').click(newsletterSignup);
$('#newsletter_email').keyup(newsReturn);
function newsletterSignup(e) {
e.preventDefault();
var email = $.trim($('#newsletter_email').val());
if (!validateEmail(email)) {
alert('Please enter a valid email');
} else {
// add email to database
$.post('newsletterSignup.php',
{ email: email },
function (data) { alert(data); }
);
$('#newsletter_email').val('');
}
return false;
}
function newsReturn(e) {
if (e.which === 13) {
newsletterSignup.apply(this, arguments);
}
}
Also, I don't know what your markup looks like, but if you were to use a form:
<form action="newsletterSignup.php" method="post" id="newsletter-form">
<input type="text" id="newsletter-email" name="newsletter_email"/>
<button type="submit">Go-go-gadget!</button>
</form>
Then you can skip the keyup stuff:
$('#newsletter-form').submit(newsletterSignup);
function newsletterSignup(e) {
e.preventDefault();
var email = $.trim($('#newsletter-email').val());
if (!validateEmail(email)) {
alert('Please enter a valid email');
return false;
} else {
// add email to database
$.post(this.action,
{ email: email },
function (data) { alert(data); }
);
$('#newsletter-email').val('');
}
return false;
}
Plus, people will be able to sign up even if you have a JavaScript problem on the page.
Related
I have a form which is submitted using Ajax.
If a checkbox is checked (receive latest offers and such), I would like to prevent the form from being submitted, if the fields are not filled out.
If the checkbox is not checked, then I don't care if the fields are filled out, and the form can be submitted even if empty.
The problem I'm currently having is, that the form is being submitted even if the checkbox is checked and the fields are empty.
I tried return false, event.stopImmediatePropagation(), event.stopPropagation() and event.preventDefault();. None of them prevent the form from submitting.
function check() is attached to the submit button.
Any and all advice is welcome.
If I can provide any additional information, let me know.
Thank you
function check (event) {
if (adverts.checked === true){
// if the email field is valid, we let the form submit
if (!fname.validity.valid) {
// If it isn't, we display an appropriate error message
showNameError();
return false; //event.preventDefault()//etc etc
}
if (!email.validity.valid) {
showEmailError();
return false; //event.preventDefault()//etc etc
}
};
};
setTimeout(function() {
document.getElementById("allow").addEventListener("click", sendAjax);
}, 1);
<button id="allow" onclick="check()">
<span id="a"></span>
</button>
As chandan suggested, I edited function check() and it works.
RollingHogs answer should also work, but the button I'm using is not type submit, as a few other ajax functions need to run before the form is submitted, so I can not accept that.
Anyway, this is the code that does the job:
function check (event) {
if (adverts.checked === true){
// if the email field is valid, we let the form submit
if(!fname.validity.valid && !email.validity.valid){
showNameError();
showEmailError();
}else if (!fname.validity.valid) {
// If it isn't, we display an appropriate error message
showNameError();
}else if(!email.validity.valid) {
showEmailError();
}else{
sendAjax();
}
}else{
sendAjax();
};
};
I guess the problem is that you stop button.onclick from propagation, not form.onsubmit. Try moving check() from onclick to onsubmit:
<form id="fname" ... onsubmit="check(event)">
<button id="allow" type="submit"></button>
</form>
Function check() should work without any edits then.
Also, see code from this question
I have a button outside of the form that when pressed, submits my form. That form has an event on it for onSubmit that fires off and then just does some form checks, making sure fields are present. At the end of the form, I return true and nothing happens. Can't seem to figure this out. Appreciate the extra set of eyes. I did verify that that function is being called and makes it all the way past the checks, just nothing happens. Here's the code:
$(document).on('click','.but_addTask',function(e){
e.preventDefault();
$('#addTaskForm').submit();
});
$(document).on('submit','#addTaskForm',function(e){
e.preventDefault();
var description = $('#description').val();
var dueDate = $('#dueDate').val();
if(!$('.taskClientID').length){
alert('Please add client(s) to task');
$('#taskClientSearch').focus();
return false;
}
if(description==""){
alert("Please enter a description")
$('#description').focus();
return false;
}
if(!$('.taskAuditorID').length){
alert('Please add owner(s) to task');
$('#taskOwnersSearch').focus();
return false;
}
if(dueDate==""){
alert("Please enter a dueDate")
$('#dueDate').focus();
return false;
}
console.log('made it!');
return true;
});
You already called e.preventDefault(); at the start of the callback, which suppresses the default behaviour of the event (in this case of course, that behaviour is to submit). By the time you return true it's too late.
If you remove that line, you should be ok.
Docs: https://api.jquery.com/event.preventdefault/
I have a field with about eight required fields. I have some code that only enables a button if all fields are validated. Then, I have a method that checks to see if all fields are valid - only then is the button enabled.
$("#FirstName").on("keyup blur", function () {
if ($("#FirstName").length > 0) {
if ($("#FirstName").valid()) {
isFirstNameValid = true;
}
else
isFirstNameValid = false;
checkIfAllFieldsAreValid();
}
})
The issue is that the required validation field is throwing an error when I tab to the next field, because the "keyup blur" event is firing on the next field even before I start typing. What event prevents this behavior from happening?
You can leave the submit button enabled and check when the user clicks it if the form is valid or not
$("#btnCreateMyAccount").on("click", function () {
if ($("#CreateAccountForm").valid()) {
return false;
}
else
{
//submit the data
}
})
Try checking if any of the inputs are empty before validating the form.
if($("your input field").val()=="") {
return;
}
Image of form that uses AJAX & JS
I've currently got a maintainer that uses AJAX so when I type a number into the "Order No" field the "Calc" field then gets updated with the "Account" associated with the Order No. It all works however the "Calc" field doesn't fill with the account number until a click away from the Order No field has been done which means that if you were to press the enter key after typing the number the calc is still blank when the checks were made to see if the account and calc numbers are the same.. If you were to type the number then click the "Accept" button the update is then done so the checks then work as expected. So I was wondering if there is a way so that this field could get updated without an extra click.
One solution I came up with was by doing the checks such as account==calc and calc != "" twice so it would run a function where the check would always say that the calc field is blank (as it hasn't updated at this point) which would return an alert saying "Blank" then after returning the alert it would run another function which is exactly the same to do the check again and this time it would work as expected but once the alert is taken out its as if it hasn't got that moments wait which allows for the Calc field to be updated in time.
Its hard for me to post all the code as I use a system that does all the AJAX behind the scenes for you but let me try explain how the AJAX works. Whatever you put in the Order No field will be sent to an external retrieval application that would check to see what account number is associated with the order no and then return it to the Calc field. If then the account and the calc field numbers match submit the form else say its an incorrect order number for that specific customer.
Here are the two JavaScript functions:
function testerRun() {
var abc = ('${row.CUSN760?html}').toString();
var def = document.getElementById("CALCULA001").value;
if (abc == def && abc != "") {
//alert("Order Number & Account Number Match!");
document.getElementById('FORM_M07052').submit();
return true;
} else if (document.getElementById('ORDN760').value == "") {
document.getElementById('FORM_M07052').submit();
return true;
} else {
//alert("Blank First Step!");
finalStep();
}
}
function finalStep() {
if (document.getElementById("CALCULA001").value == "") {
alert("Customers Account Details Need Amending..");
return false;
} else {
var abc = ('${row.CUSN760?html}').toString();
var def = document.getElementById("CALCULA001").value;
if (abc == def && abc != "") {
//alert("Order Number & Account Number Match!");
document.getElementById('FORM_M07052').submit();
return true;
} else if (document.getElementById('ORDN760').value == "") {
document.getElementById('FORM_M07052').submit();
return true;
} else {
alert("Order Number & Account Number Do Not Match!");
return false;
}
}
}
And here is where the script is called:
<input class="btn btn-primary accept" id="btnaccept" name="btn_accept" onclick="testerRun();return false" type="submit" value="Accept" />
#Shreyas Sorry there is no blur or change as im using a system called MRC and so they use behind the scenes AJAX scripts to handle thigns like this what I don't have access too so I need some sort of work around. Its only an issue when the user clicks enter in the order no field after entering the order number without doing anything else on the form as it doesn't update until the order number is deselected.
document.getElementById('ORDN760').onkeydown = function(event){
if (event.which == 13 || event.keyCode == 13) {
document.getElementById('ORDN760').blur();
testerRun();
}
}
Function call not working though doesn't seem to do anything just sits there after blur.
Add a keypress handler on the Order No field, which listens for the Enter key, and submits the form when Enter is pressed.
document.getElementById('ORDN760').onkeydown = function(event){
if (event.which == 13 || event.keyCode == 13) {
document.getElementById('ORDN760').blur();
return false;
}
}
I am writing a search function much like the [cmd+f] function in a browser. I have everything working but I want the enter key on press to cycle through the results through the page. I also have arrow buttons that call the function I wrote and they work. I prevented the default behavior of enter using:
$('form').keydown(function (event) {
if (event.keyCode == 13) {
event.preventDefault();
return false;
}
});
I am using this code to call the function on enter:
$('form').keyup(function (event) {
if (event.keyCode == 13) {
nextSearch();
}
});
It works for the first result but I think it resets the global variable I use to mark the place. The only logical answer I can think of is that pressing enter now refreshes the JavaScript. Is there a way to prevent this?
I use these global variables to keep track:
window.luCurrentNumber = 0;
window.luLastActive = 0;
If I understand you corrected, you the arrow keys and the enter keys to tab instead of performing their default. Here is an example of a function that I use to treat the Enter key as a tab, which I wrote because users kept hitting the enter key and accidentally submitting the page.
//Make enter key is pressed, tab instead of submitting.
$('body').on('keydown', 'input, select', function (e) {
var self = $(this)
, form = self.parents('form:eq(0)')
, focusable
, next
;
if (e.keyCode == 13) {
focusable = form.find('input,a,select,button').filter(':visible');
next = focusable.eq(focusable.index(this) + 1);
if (next.length) {
next.focus();
} else {
form.submit();
}
return false;
}
});
Though it's not exactly what you are trying to do, I think it should set you on the right path.