How to disable event.preventDefault() if submition is correct? - javascript

I want to redirect to the homepage and flash a message using flask, and I think I need to disable the preventDefault() function:
login_form.addEventListener("submit", (event) => {
event.preventDefault();
axios.post(login_form.action, {
username: login_form.username.value,
password: login_form.pass.value
}).then((response) => {
if (response.data["returnval"] === "wrong-crd")
{
_alert.innerHTML = "Username or password is incorrect";
_alert.hidden = false;
}
else
{
window.location.href = "/";
}
});
});
The code works but I can't flash a message, how can I disable the preventDefault() function.
My flask code:
#app.route("/login", methods=["GET", "POST"])
def login():
if request.method == "GET":
return render_template("login.html")
else:
username = request.json.get("username")
password = request.json.get("password")
cursor.execute("SELECT * FROM Users WHERE username = %s", (username,))
returned = cursor.fetchall()
if len(returned) == 0:
return jsonify(returnval="wrong-crd")
if check_password_hash(returned[0][3], password):
session.permanent = True
session["userId"] = returned[0][0]
flash("Logged in!")
return redirect("/")
else:
return jsonify(returnval="wrong-crd")

Since AJAX is asynchronous, it means that it takes time to get the response after you submit your request.
If you do not prevent default event on the start, it will usually trigger that default event BEFORE you even receive your response.
You can do something like this :
Make a function that will make a popup message, something like this :
function pushNotification(message){
alert(message);
}
We are going to be using localStorage to store popup messages that need to be shown.
So firstly we are going to add a small code to your main javascript file that will trigger the function that we just made :
let nextMSG = localStorage['nextMessage'];
if(nextMSG!=undefined && nextMSG!=""){
pushNotification(nextMSG);
localStorage['nextMessage']="";
}
Now all you have to do is modify your code so that :
a) - When the response fails(user doesn't log in), you call pushNotification() function directly
b) - When the user logs in, you firstly change value of localStorage['nextMessage'] to a value that you want the user to see after redirect, and then redirect the user to wanted location.

You could just call login_form.submit() to proceed with the default submission if the field values are correct.
login_form.addEventListener("submit", (event) => {
event.preventDefault();
axios.post(login_form.action, {
username: login_form.username.value,
password: login_form.pass.value
}).then((response) => {
if (response.data["returnval"] === "wrong-crd")
{
_alert.innerHTML = "Username or password is incorrect";
_alert.hidden = false;
}
else
{
login_form.submit();
}
});
});

Related

How to show error in View if the Controller fails ? ASP.NET MVC

On the server-side I have a transaction which returns a JsonResult:
public JsonResult DoStuff(Guid id, string userInputText)
{
var product = _repository.Product(id); //busines logic
//Only a specific product must have userInputText <= 10 characters.
//Other products may have as many characters as the user wants.
if(product == Enum.SpecificProduct && userInputText.Count() > 10)
{
//The user input text comes from the View...
//If it has more then 10 characters, need to send the errorMessage to the View.
return Json(new { success = false, errorMessage = "error message" }, JsonRequestBehavior.AllowGet);
}
//Otherwise, do stuff on the product...
//and return success at the end.
return Json(new { success = true });
}
On the other hand, on the client-side I have this:
using (Ajax.BeginForm("DoStuff", ajaxOptions))
{
<span>Enter the text:</span>
#Html.TextArea("userInputText", new { onkeyup = "SyncContents(); return false;" })
<input type="submit" value="Add" />
<!-- error message should be displayed here-->
}
This is the AjaxOptions:
var ajaxOptions= new AjaxOptions
{
OnSuccess = "reload",
OnFailure = "FailMessage"
};
If the entered text have more then 10 characters, when the "Add" button is pressed, the Controller is being executing the code on the server-side and fails, how can I get the errorMessage from there and use it here, in the View, to inform the user ?
I tried to alert a message:
<script>
function FailMessage() {
alert("Fail Post");
}
</script>
But no pop-up "Fail post" appears.
Best regards.
The problem here is the Ajax helper thinks all your responses are successful. Your controller action is returning HTTP 200 so there isn't a problem.
https://msdn.microsoft.com/en-us/library/system.web.mvc.ajax.ajaxoptions.onfailure(v=vs.118).aspx#P:System.Web.Mvc.Ajax.AjaxOptions.OnFailure
AjaxOptions.OnFailure Property
This function is called if the response status is not in the 200 range.
So you'll need to use the success handler and explicitly check the JSON success parameter.
Or have your action change the HttpStatusCode for the response.
if (notValid)
{
Response.StatusCode = 400; // Bad Request
return Json(new { success = false, errorMessage = "error message" }, JsonRequestBehavior.AllowGet);
}
But for a validation error here I'd just check the for an error in the success handler.
And yes, you should validate on the client and on the server.

Javascript, ajax and django not redirecting page and returning value as text

I am trying to make a Django and Ajax based Login View with Mobile Number verification via a One Time Password (OTP). When the User signups, his mobile number is sent an OTP, which he has to enter and confirm.
Now, let's say the user did not authenticate his mobile number before and now tries to login into the website, I want him to first verify the mobile number via the OTP that was sent to his mobile number and then he can further log into the site.
My code for signup in views.py is:
def signup(request):
if request.method == "POST":
first_name = request.POST.get("fname")
last_name = request.POST.get("lname")
mobile = request.POST.get("telephone")
email = request.POST.get("email")
password = request.POST.get("password")
try:
#mobilecheck = Customer.objects.get(mobile=mobile)
emailcheck = Customer.objects.get(email=email)
except ObjectDoesNotExist:
user = Customer.objects.create_user(email, password, mobile=mobile, first_name=first_name, last_name=last_name, is_active=False)
otp = randint(1000,9999)
message = "Verification code for Delimedy.com is : " + str(otp)
mOTP = MobileOTP(customer=user, otp=otp)
mOTP.save()
sendotp(mobile, message)
user = authenticate(username=email, password=password)
auth_login(request, user)
return HttpResponse("success")
else:
return HttpResponse("conflict")
else:
return render(request, "registration/signup.html", {
"title":"Signup",
})
And code for login in views.py is :
def login(request):
auth_logout(request)
if request.method == "POST":
email = request.POST.get("email")
password = request.POST.get("password")
user = authenticate(username=email, password=password)
if user is not None:
auth_login(request, user)
if user.is_active:
return HttpResponse("success", content_type="text/plain")
else:
return HttpResponse("notverified", content_type="text/plain")
else:
return HttpResponse("mismatch", content_type="text/plain")
else:
return render(request, "registration/login.html", {
"title":"Login to Delimedy"
})
And the contents of my .js file for the Ajax function calling is:
$('#login-button').on('click', function(){
var preloader = $('#overlay-screen');
preloader.removeClass('hide');
var redirectTo = $(this).attr("rel");
var email = $('#email');
if(email.val().length == 0) {
email.removeClass('valid');
email.addClass('invalid');
preloader.addClass('hide');
return;
}
var password = $('#password');
if(password.val().length == 0) {
password.removeClass('valid');
password.addClass('invalid');
preloader.addClass('hide');
return;
}
var csrf_token = $("input[name=csrfmiddlewaretoken]").val();
var rememberme = $('#remember').is(':checked');
var dataString = 'email='+email.val()+'&password='+password.val()+'&csrfmiddlewaretoken='+csrf_token;
$.ajax
({
type: "POST",
url: "/account/login/",
data: dataString,
cache: false,
success: function(data)
{
preloader.addClass('hide');
if(data == 'email_blank') {
email.removeClass('valid');
email.addClass('invalid');
return;
}
else if(data == 'password_blank') {
password.removeClass('valid');
password.addClass('invalid');
return;
}
else if(data == 'success') {
window.location.href = "/";
}
else if(data == 'notverified') {
window.location.href="/account/login/"
}
else if(data == "mismatch") {
alert("Mobile Number and Password doesn't match.");
}
else {
alert(data);
}
}
});
});
The problem with the login form is that, If try to login and the login is successful, instead of redirecting to the page, it opens a page with the text "success" and let's say the user is registered and not active but tries to login, does not get redirected to verifyotp page but a page with just "notverified" written. How do I fix it?
rather than: return HttpResponse("success", content_type="text/plain")
You should have: return redirect(myurl)
https://docs.djangoproject.com/en/1.9/topics/http/shortcuts/#redirect
Don't know if it is the question, but django will refresh current page after a click on the button, to prevent this you could add in js:
return false;
or
e.preventDefault();

Javascript function "does not exist". Bad syntax but can't see it

The javascript is supposed to handle form submission. However, even if called with
script src="js/registerform.js"> Uncaught ReferenceError: sendreg is not defined .
The function is called onclick. Can be reproduced on www.r4ge.ro while trying to register as well as live edited. Tried jshint.com but no clue.
I will edit with any snips required.
function sendreg() {
var nameie = $("#fname").val();
var passwordie = $("#fpass").val();
var emailie = $("#fmail").val();
if (nameie == '' || passwordie == '' || emailie == '') {
alert("Please fill all the forms before submitting!");
} else {
// Returns successful data submission message when the entered information is stored in database.
$.post("http://r4ge.ro/php/register.php", {
numeleluii: nameie,
pass: passwordie,
mail: emailie
}, function(data) {
alert(data);
$('#form')[0].reset(); // To reset form fields
setTimeout(fillhome, 1000);
});
}
}
function sendpass() {
var oldpassw = $("#oldpass").val();
var newpassw = $("#newpass").val();
if (oldpassw == '' || newpassw == '') {
alert("Please fill all the forms before submitting!");
} else {
// Returns successful data submission message when the entered information is stored in database.
$.post("http://r4ge.ro/php/security.php", {
xoldpass: oldpassw,
xnewpass: newpassw
}, function(data2) {
alert(data2);
$('#passform')[0].reset(); // To reset form fields
});
}
}
function sendmail()
{
var curpass = $("#curpass").val();
var newmail = $("#newmail").val();
if (curpass == '' || newmail == '')
{
alert("Please fill all the forms before submitting!");
}
else
{
// Returns successful data submission message when the entered information is stored in database.
$.post("http://r4ge.ro/php/security.php", {
curpass: curpass,
newmail: newmail
}, function(data3) {
alert(data3);
$('#mailform')[0].reset(); // To reset form fields
});
}
}
I'm guessing here but... I imagine you are doing something like
...<button onclick="sendreg">...
And you have your <script> in the bottom on the code. Just put them on top or use $("#mybtn").click(sendreg)
Try using $("#mybtn").click(sendreg) instead of inline onclick.
The script wasn't called in the html. sorry for wasting time. A simple
<script src="js/registerform.js"></script> Fixed it.
There is no syntax error there, and I don't see any such error when trying the page.
The error that you get is that you can't make a cross domain call. Do the request to the same domain:
$.post("http://www.r4ge.ro/php/register.php", {
or:
$.post("/php/register.php", {

How can I use the results of various ajax requests in another function?

I have been programming a registration form with ajax validation. The way I have it set up is in my js file, I have listeners that fire when the content of the field is changed. They send the data to the server, and the server makes sure it's valid and sends back its response in the form of a JSON object. I then read the values of the JSON object to output potential error messages.
I won't copy and paste the entire files, just one example:
$(document).ready(function() {
// USERNAME VALIDATION LISTENER
$("#regUsername").change(checkName);
}
and then the checkName function looks like this, it sends my ajax request:
function checkName() {
$.ajax({
type: "POST",
url: "./ajax_register.php",
data: {
request: "nameAvail",
username: $("#regUsername").val()
},
success: function(data) { // execute on success
var json = jQuery.parseJSON(data);
if (json.success) { // if usernames do match
$("#usernameAvailiability").removeClass().addClass('match');
$("#usernameAvailiability").text(json.msg);
} else { // if the user has failed to match names
$("#usernameAvailiability").removeClass().addClass('nomatch');
$("#usernameAvailiability").text(json.msg);
}
}
});
}
And depending on the response, it updates a span that tells the user if the input they wrote is valid or not.
The server validates with this part of the php file:
if(!isset($_POST['request'])) { // do nothing if no request was provided
print("no request provided");
} else { //ELSE request has been provided
if ($_POST['request'] == "nameAvail") { // if the request is to check if the username is valid
$response = array("success" => false, "msg" => " ", "request" => "nameAvail");
// CHECK USER NAME AVAILIABILITY CODE
if (!isset($_POST['username']) || empty($_POST['username'])) { // if no username is entered
$response['success'] = false;
$response['msg'] = "No username provided";
} else { // if a username has been entered
$username = $dbConn->real_escape_string($_POST['username']);
if (!ctype_alnum($username)) { // Make sure it's alpha/numeric
$response['success'] = false;
$response['msg'] = "username may only contain alpha numeric characters";
} elseif (strlen($username) < 4) { // make sure it's greater than 3 characters
$response['success'] = false;
$response['msg'] = "username must be at least 4 characters long.";
} elseif (strlen($username) > 20) { // make sure it's less than 26 characters
$response['success'] = false;
$response['msg'] = "username can be up to 20 characters long.";
} else { // make sure it's not already in use
$query = $dbConn->query("SELECT `id`, `username` FROM `users` WHERE `username` = '"
. $username . "' LIMIT 1");
if ($query->num_rows) { // if the query returned a row, the username is taken
$response['success'] = false;
$response['msg'] = "That username is already taken.";
} else { // No one has that username!
$response['success'] = true;
$response['msg'] = "That username is availiable!";
}
}
}
print(json_encode($response));
}
What I'd like to do now is create a function in my javascript for the register button. But I need to make sure all the forms are validated first.
I'm not sure what my options are. What I'd LIKE to do is somehow be able to recycle the code I've already written in my PHP file. I don't want to write out an entirely new if($_POST['request'] == "register") clause and then copy and paste all the validation code to make sure the input is valid before I insert the registrant's data into the database. It seems really repetitive!
I know I could check to see if all the spans on the page were set to 'match', but that could easily be tampered with and blank forms could be submitted.
so far, my register button function looks like this:
function register() {
if ( NEED SOME KIND OF CLAUSE HERE TO CHECK IF ALL THE FIELDS ARE VALID) {
$.ajax({
type: "POST",
url: "./ajax_register.php",
data: {
request: "register",
username: $("#regUsername").val(),
password: $("#regPassword").val(),
email: $("#email").val(),
dob: $("#dob").val(),
sQuest: $("#securityQuestion").val(),
sAns: $("#securityAnswer").val(),
ref: $("#referred").val()
}, success: function(data) {
var json = jQuery.parseJSON(data);
console.log(json);
$("#regValid").removeClass();
$("#regValid").text("");
}
}); //AJAX req done
} else {
$("#regValid").removeClass().addClass('nomatch');
$("#regValid").text("One or more fields are not entered correctly");
}
return false;// so that it wont submit form / refresh page
}
I would really appreciate some help, I've spent the last few hours scouring StackOverflow for an answer, but I can't seem to get anything to work. Will I have to duplicate code in my PHP file or is there a more elegant way to handle this?

AJAX stored requests and form submitting

I am working on a jQuery validation "plugin" (not yet a plugin) that use my Zend_Form validators to verify the fields before submitting, client-side, so I only have to specify my constraints one time instead of two (Zend Validators + jQuery Validate Plugin, for example).
I store the validation AJAX requests for each field, then wait for them to finish, and then read the results and show or not an error message.
The problem : when I enter validated strings and hit submit, it shows no errors (good so far), but I have to re-click the submit button the form to really submit it.
Making a return true or false inside the .whenAll function is ignored and does not work, that's why I used a flag to tell the function if yes or no it can really submit the form.
$(function() {
var form = $('form'); // target form
var requests = [], validations = []; // used to store async requests and their results
var nbInputs = $('input[type="text"], input[type="password"]').length; // number of inputs we want to check in the form
var cancelSubmit = true; // skip validation flag
form.submit(function( ) {
// if we call the submit inside the function, skip validation and do submit the form
if(cancelSubmit === false) {
console.log('[-] cancelSubmit is false. Validation skipped.');
this.submit();
return true;
}
console.log('[-] Entering validation');
// resetting requests and validations
requests.length = 0;
validations.length = 0;
// for each input (text/password), storing the validation request
$('input[type="text"], input[type="password"]').each(function(i) {
var validatorField = $(this).attr('data-validator');
var valueField = $(this).val();
postData = {
validator: validatorField,
value: valueField
};
// storing requests into an array
requests.push($.post('/validate', postData));
});
(function($) {
$.whenAll = function() {
return $.when.apply($, arguments);
};
})(jQuery);
// when all the requests are done and returned a response
$.whenAll(requests).then(function() {
// show the validation status for each input
$.each(requests, function(i, element) {
element.done(function(data) {
// response is formatted like this
// { valid: 1 } or { valid: 0, message:"This is the error message" }
json = $.parseJSON(data);
formGroup = $('input:eq('+i+')').parent();
// if it isn't valid, show error and store result
if(json.valid == 0) {
if($('span.help-block', formGroup).length == 0) {
$(formGroup).addClass('has-error').append('<span class="help-block">'+json.message+'</span>');
$('label', formGroup).addClass('control-label');
}
validations.push(0);
}
// else, remove error (if there was) and store the result
else if(json.valid == 1) {
if($(formGroup).hasClass('has-error'))
{
$(formGroup).removeClass('has-error');
$('.help-block', formGroup).remove();
}
validations.push(1);
}
// if we got all the validations required
if(validations.length == nbInputs)
{
console.log('[-] All validations have been done.');
// and if no error ("0") in the results, we resubmit the form with skip-flag
if($.inArray(0, validations) == -1){
console.log('[-] No errors. Submitting form.');
cancelSubmit = false;
form.off('submit');
form.submit();
}
else
console.log('[-] There is still errors.');
}
});
});
});
// there are errors, so we won't submit the form
if(cancelSubmit === true)
return false;
});
});
Do you see a logic flaw in my code ? Maybe re-submitting the form with a flag isn't the right way to do it ?
You're returning from a sub scope rather than from the form submit handler. Instead, always prevent the submit, and then force it to submit with form[0].submit() when you want it to submit.
form.submit(function(e) {
e.preventDefault();
...
// now i want to submit...
form[0].submit();
form[0].submit() will bypass your jquery bound submit handler.

Categories

Resources