var onSuccess works in HTML file but not in .js file - javascript

I am implementing Google's Invisible Recaptcha and I am trying to have everything run from my mail.js file (and I would really prefer to keep it there). For some reason Recaptcha is not finding "onSuccess" in mail.js but if I move it to the HTML inside <script></script> it works.
I am getting this error in JavaScript console: ReCAPTCHA couldn't find user-provided function: onSuccess when it is in mail.js
$(".input-field").each(function () {
var $this = $(this);
if ($this.val().length) {
$this.parent().addClass("input--filled")
}
$this.on("focus", function () {
$this.parent().addClass("input--filled");
});
$this.on("blur", function () {
if (!$this.val().length) {
$this.parent().removeClass("input--filled")
}
})
});
$(function () {
// Get the form.
var form = $('#ajax-contact'),
// Get the messages div.
formMessages = $('#form-messages');
// Set up an event listener for the contact form.
$(form).submit(function (e) {
// Stop the browser from submitting the form.
grecaptcha.execute();
e.preventDefault();
});
});
var onSuccess = function(response) {
$("#btn-submit").addClass("btn-loading");
// Serialize the form data.
var formData = $(form).serialize();
// Submit the form using AJAX.
$.ajax({
type: 'POST',
url: $(form).attr('action'),
data: formData
})
.done(function (response) {
// Make sure that the formMessages div has the 'success' class.
$(formMessages).removeClass('error').addClass('success').fadeIn().delay(5000).fadeOut();
// Set the message text.
$(formMessages).text(response);
// Clear the form.
$(form).trigger("reset");
grecaptcha.reset();
$("#btn-submit").removeClass("btn-loading");
})
.fail(function (data) {
// Make sure that the formMessages div has the 'error' class.
$(formMessages).removeClass('success').addClass('error').fadeIn().delay(5000).fadeOut();
// Set the message text.
if (data.responseText !== '') {
$(formMessages).text(data.responseText);
} else {
$(formMessages).text('Oops! An error occured and your message could not be sent.');
}
$("#btn-submit").removeClass("btn-loading");
});
};
here is the HTML:
<form id="ajax-contact" class="" method="post" action="mailer.php">
<fieldset>
<div class="row">
<div class="input col-xs-12 col-sm-12 padding-bottom-xs-50 padding-bottom-40">
<label class="input-label" for="name">
<span class="input-label-content font-second" data-content="name">name *</span>
</label>
<input class="input-field" type="text" name="name" id="name" required />
</div>
<div class="input col-xs-12 col-sm-6 padding-bottom-xs-50 padding-bottom-50">
<label class="input-label" for="email">
<span class="input-label-content font-second" data-content="email">email *</span>
</label>
<input class="input-field" type="email" name="email" id="email" required />
</div>
<div class="input col-xs-12 col-sm-6 padding-bottom-xs-60 padding-bottom-50">
<label class="input-label" for="company">
<span class="input-label-content font-second" data-content="company">company</span>
</label>
<input class="input-field" type="text" name="company" id="company" />
</div>
<div class="message col-xs-12 col-sm-12 padding-bottom-xs-40 padding-bottom-30">
<label class="textarea-label font-second" for="message">message *</label>
<textarea class="input-field textarea" name="message" id="message" required></textarea>
</div>
</div>
<div class="g-recaptcha" data-sitekey="6Lf-6XQUAAAAAGhsZxXTlA3MtMGr_xDhOXPG-Ds0" data-badge="inline" data-size="invisible" data-callback="onSuccess"></div>
<div id="form-messages" class="form-message"></div>
<div class="col-xs-12 margin-top-30 text-center">
<button id="btn-submit" type="submit" class="btn btn-animated btn-contact ripple-alone" data-text="send it"><span class="btn-icon"><span class="loader-parent"><span class="loader3"></span></span>
</span>
</button>
</div>
</fieldset>

Related

Form validation with Ajax call triggers when not validation

I have a simple form with Ajax call, but ajax call gets executed even if form is not validated.
In below code line console.log("This line should execute only if Form is validated"); gets executed when form is not validate.
Bootstrap 5 validation Codepen code
(function () {
"use strict";
const forms = document.querySelectorAll(".requires-validation");
Array.from(forms).forEach(function (form) {
form.addEventListener(
"submit",
function (event) {
if (!form.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
else
{
console.log("This line should execute only if Form is validated");
// Call Ajax Function
// AjaxCallSaveData();
}
form.classList.add("was-validated");
},
false
);
});
})();
//$(document).ready(function () {
function AjaxCallSaveData()
{
$("form").submit(function (event) {
var formData = {
name: $("#name").val(),
email: $("#email").val(),
message: $("#message").val(),
superheroAlias: $("#superheroAlias").val()
};
$.ajax({
type: "POST",
url: "SubmitFORM.php",
data: formData,
dataType: "json",
encode: true
}).done(function (data) {
console.log(data);
});
event.preventDefault();
});
}
//});
Not sure if i am doing it right?
HTML
<div class="form-body">
<div class="row">
<div class="form-holder">
<div class="form-content">
<div class="form-items">
<h3>Register you interest</h3>
<p>Fill in the data below, we will get back to you!</p>
<form class="requires-validation" action="SubmitFORM.php" method="POST" novalidate>
<div class="col-md-12 mb-3">
<input class="form-control" type="text" name="name" id="name" placeholder="Full Name" required>
<div class="valid-feedback">Username field is valid!</div>
<div class="invalid-feedback">Username field cannot be blank!</div>
</div>
<div class="col-md-12 mb-3">
<input class="form-control" type="email" name="email" id="email" placeholder="E-mail Address" required>
<div class="valid-feedback">Email field is valid!</div>
<div class="invalid-feedback">Email field cannot be blank!</div>
</div>
<div class="col-md-12 mb-3">
<textarea name="message" id="message" placeholder="Your Message"></textarea>
</div>
<div class="form-button mt-3">
<button id="submit" type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
event.preventDefault() will only stop the form from submitting. It cannot stop next lines of the JavaScript function from executing.
You should use return in place of event.preventDefault().

Hidden input not submitted after updating value in on submit event

Using Laravel framework.
I don't get it. I have a hidden input with id = prime near the top.
<form name="paymentForm" action="/parking_302/upload_payment" method="POST" role="form" class="form-horizontal">
{{ csrf_field() }}
<input type="hidden" id="parking_lot_id" name="parking_lot_id" value="{{ $parking_lot_id }}">
<input type="hidden" id="booking_id" name="booking_id" value="{{ $booking_id }}">
<input type="hidden" id="Price" name="Price" value="{{ $Price }}">
<input type="hidden" id="prime" name="prime"> {{-- To be obtained --}}
<legend>電子發票 & TapPay 付款</legend>
<div class="form-group">
<label for="CustomerEmail" class="col-lg-3 col-md-3 col-xs-4">電子信箱</label>
<div class="col-lg-9 col-md-9 col-xs-8">
<input type="email" class="form-control" id="CustomerEmail" name="CustomerEmail" value="{{ old('CustomerEmail') }}">
</div>
</div>
<div class="form-group">
<label for="CustomerPhone" class="col-md-3 col-xs-4">手機號碼</label>
<div class="col-md-9 col-xs-8">
<input type="number" class="form-control" id="CustomerPhone" name="CustomerPhone" value="{{ old('CustomerPhone') }}">
</div>
</div>
<hr>
<div class="form-group">
<div class="col-md-offset-3 col-xs-offset-4 col-md-9 col-xs-8">
<select class="form-control" id="giveTongBian" name="giveTongBian">
<option value="no" #if(old('giveTongBian') === "no") selected #endif>不需統編</option>
<option value="yes" #if(old('giveTongBian') === "yes") selected #endif>輸入統編</option>
</select>
</div>
</div>
<div class="form-group" id="customerIdentGroup">
<label for="CustomerIdentifier" class="col-md-3 col-xs-4">統一編號</label>
<div class="col-md-9 col-xs-8">
<input type="text" class="form-control" id="CustomerIdentifier" name="CustomerIdentifier" value="{{ old('CustomerIdentifier') }}">
</div>
</div>
<div class="form-group" id="customerNameGroup">
<label for="CustomerName" class="col-md-3 col-xs-4">買受人</label>
<div class="col-md-9 col-xs-8">
<input type="text" class="form-control" id="CustomerName" name="CustomerName" value="{{ old('CustomerName') }}">
</div>
</div>
<div class="form-group" id="customerAddrGroup">
<label for="CustomerAddr" class="col-md-3 col-xs-4">地址</label>
<div class="col-md-9 col-xs-8">
<input type="text" class="form-control" id="CustomerAddr" name="CustomerAddr" value="{{ old('CustomerAddr') }}">
</div>
</div>
<div class="tappay-form col-xs-offset-1 col-xs-10">
<h4 style="color: darkkhaki;">信用卡</h4>
<div class="form-group card-number-group">
<label for="card-number" class="control-label"><span id="cardtype"></span>卡號</label>
<div class="form-control card-number"></div>
</div>
<div class="form-group expiration-date-group">
<label for="expiration-date" class="control-label">卡片到期日</label>
<div class="form-control expiration-date" id="tappay-expiration-date"></div>
</div>
<div class="form-group cvc-group">
<label for="cvc" class="control-label">卡片後三碼</label>
<div class="form-control cvc"></div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-default">Pay</button>
</div>
</div>
</form>
I then have a on submit event which does a few things. At the bottom is me updating the hidden input with id = prime.
$('form').on('submit', function (event) {
//Code for first part of form begin
var boolFlag = true; //Default is submit
var errorMsg = ""; //Initial message
//Begin validation
var numOfNonEmptyFields = 0;
if(document.forms["paymentForm"]["CustomerEmail"].value != "") {
numOfNonEmptyFields++;
}
if(document.forms["paymentForm"]["CustomerPhone"].value != "") {
numOfNonEmptyFields++;
}
if(numOfNonEmptyFields == 0) {
errorMsg += "請輸入至少一個電子信箱或手機號碼.\n";
boolFlag = false;
}
//End validation
//Final steps: overall error message + success or fail case
if(boolFlag == false) {
alert("錯誤:\n" + errorMsg);
return false;
}
//Code for first part of form end
// fix keyboard issue in iOS device
forceBlurIos()
const tappayStatus = TPDirect.card.getTappayFieldsStatus()
console.log(tappayStatus)
// Check TPDirect.card.getTappayFieldsStatus().canGetPrime before TPDirect.card.getPrime
if (tappayStatus.canGetPrime === false) {
bootbox.alert({
title: "錯誤訊息",
message: "取得不了Prime.",
buttons: {
ok: {
label: "OK",
className: "btn btn-primary"
}
}
});
return false
}
// Get prime
TPDirect.card.getPrime(function (result) {
if (result.status !== 0) {
bootbox.alert({
title: "錯誤訊息",
message: result.msg,
buttons: {
ok: {
label: "OK",
className: "btn btn-primary"
}
}
});
return false
}
$("#prime").val(result.card.prime);
})
})
I've tested the hidden input with alert($("#prime").val()) directly after and it seems updated, however after submission, my Controller receives the value as null while other hidden input values are correct. So I suspect it's something got to do with the on submit event.
Added id attribute to the form element:
<form id="paymentForm" name="paymentForm" action="/parking_302/upload_payment" method="POST" role="form" class="form-horizontal">
Removed type from the button and added id:
<button id="submit-btn" class="btn btn-default">Pay</button>
Introduced a new click listener:
$(document).on("click","#submit-btn", function(event){
event.preventDefault();
validateAndSendForm();
});
Introduced a new function for the final form submit:
function submitForm(){
//do other stuff here with the finalized form and data
//.....
$( "#paymentForm" ).submit();
}
And put all of your old things into a new function as well:
function validateForm(){
//Code for first part of form begin
var boolFlag = true; //Default is submit
var errorMsg = ""; //Initial message
...
...
...
}
// Get prime
TPDirect.card.getPrime(function (result) {
if (result.status !== 0) {
bootbox.alert({
title: "錯誤訊息",
message: result.msg,
buttons: {
ok: {
label: "OK",
className: "btn btn-primary"
}
}
});
return false;
}
$("#prime").val(result.card.prime);
//use when you are ready to submit
submitForm();
})
}
So, basically you will have a "submitForm" function that you can use whenever you are ready to submit the form.
Seems like TPDirect.card.getPrime is something that gets data asynchronously so the $('form').on('submit' function won't wait for it to finish.

Dropzone js validate on submit

I have a form where I am using dropzone.js for file upload. Now I am validating all the input fields. But i'm not able to validate the file before submission. If the file is uploaded, then the submission should work. Otherwise it should throw an error like - "please upload the file". How can i achieve this?
HTML code:
<form action="/action">
<div class="form-row">
<div class="form-group col-md-6">
<input type="text" class="form-control" id="first_name" name="first_name" placeholder="First Name" required>
</div>
<div class="form-group col-md-6">
<input type="text" class="form-control" id="last_name" name="last_name" placeholder="Last Name" required>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<textarea class="form-control" id="message" name="message" placeholder="Message"></textarea>
</div>
</div>
<div class="form-row">
<div id="resume" class="dropzone form-control"></div>
</div>
<input type="submit" class="btn btn-primary mt-10" id="item-submit" value="submit">
</form>
Javascript :
<script type="text/javascript">
$(document).ready(function () {
$("div#resume").dropzone({ url: "/change-this-later" });
var dropzone3;
Dropzone.autoDiscover = false;
dropzone3 = new Dropzone('#resume', {
maxFiles: 1,
});
$('#item-submit').click(function(e) {
e.preventDefault();
e.stopPropagation();
if ($('form#resume').valid()) {};
});
});
</script>
You can add a callback event which is called if the upload is successful
//indicates file upload is complete and is successful
var uploaded = false;
$("div#resume").dropzone({
url: "/change-this-later",
success: function (file, response) {
uploaded = true;
}
});
//Check the value of 'uploaded' when validating rest of fields
So I come around this. Since I submit all my images and fields in the same button, I just acceded to the files array in side the dropzone and validate that it's lenght wasn't 0. $animalImage is my dropzone.
var validateImages = function (animal) {
if ($animalImage.files.length == 0) {
swal({
title: 'Advertencia',
type: 'info',
html: "Debe de guardar al menos una imágen",
showCloseButton: true,
focusConfirm: false
});
return false;
}
return animal;
};
Hope it helps, side note a submit trough ajax so I just used dropzone for the user experience.

Show a preview/Edit option before submitting the form using AngularJS

I have my html form as shown below:
<div class="container">
<div class="form-group" ng-controller="studentController">
<form role="form" class="well form-horizontal" id="registerForm" name="forms.registerForm">
<div class="form-group">
<label class="col-md-4 control-label">First Name </label>
<input ng-model="formdata.firstname" required type="text" name="firstname">
</div>
<div class="form-group">
<label class="col-md-4 control-label">Middle Name </label>
<input ng-model="formdata.middlename" required type="text" name="middlename" maxlength="1">
</div>
<div class="form-group">
<label class="col-md-4 control-label">Last Name </label>
<input ng-model="formdata.lastname" required type="text" name="lastname">
</div>
<div class="form-group">
<label for="email" class="col-md-4 control-label">E-mail address</label>
<input ng-model="formdata.email" required type="email">
</div>
<div class="form-group">
<label class="col-md-4 control-label">Student ID</label>
<input ng-model="formdata.studentid" required type="number">
</div>
<div required class="form-group">
<label class="col-md-6 control-label">
level
</label> <br>
<div class="radio">
<label class="col-md-6 control-label">
<input type="radio" ng-model="formdata.type" value="300" checked>
300 </label>
</div>
<div class="radio">
<label class="col-md-6 control-label">
<input type="radio" ng-model="formdata.type" value="400">
400 </label>
</div>
<div class="radio">
<label class="col-md-6 control-label">
<input type="radio" ng-model="formdata.type" value="500">
500 </label>
</div>
</div>
<div class="form-group" align="center">
<input type="file" ngf-select ng-model="formdataa.file" name="file" ngf-pattern="'application/pdf'" accept="'.pdf'" ngf-max-size="5MB" required ngf-model-invalid="errorFile">
</div>
<div class="container" align="center">
<button class="btn btn-register" ng-click="tempData()" ng-disabled="forms.registerForm.$invalid" >Submit</button>
</div>
Below is the angular javascript code to store the details of the form and the file in the server.
$scope.tempData = function(ev){
console.log($scope.formdata);
var confirm = $mdDialog.confirm()
.title('Are you sure you want to delete this user?')
.ok('YES')
.cancel('CANCEL');
$mdDialog.show({
locals:{formdata: $scope.formdata, dataToPassFile: $scope.formdataa}, //here where we pass our data
controller: _DialogController,
controllerAs: 'vd',
templateUrl: 'scripts/app/studentdialog/studentdialog.html',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose: true
})
.then(
function(answer) {},
function() {
}
);
};
function _DialogController($scope, $mdDialog, formdata,dataToPassFile) {
$scope.closeDialog = function() {
$mdDialog.hide();
};
$scope.firstname = formdata.firstname;
$scope.lastname = formdata.lastname;
$scope.middlename = formdata.middlename;
$scope.studentid = formdata.studentid;
$scope.email = formdata.email;
$scope.type = formdata.type;
$scope.file = dataToPassFile.file;
console.log('FIle Passed' +dataToPassFile.file);
$scope.tfile = function () {
console.log("TFIle Called");
if ($scope.forms.registerForm.file.$valid && $scope.formdataa.file) {
$scope.upload($scope.formdataa.file);
}
};
$scope.upload = function (file) {
file.upload = Upload.upload({
url: $rootScope.baseURL + 'php/uploadT.php',
method: 'POST',
data: {
'file': file,
'userId': $scope.formdata.firstname,
'type': $scope.formdata.type
},
});
$scope.register = function () {
console.log("clicked");
$scope.loading = true;
AppServices.register($scope.formdata)
.then(function (result) {
if (Object.keys(result).length > 0) {
// update current users list
if (result.type == '300' || result.type == '400') {
$scope.users.300.push(result);
} else {
console.log(result);
$scope.users[result.type] = result;
}
$scope.forms.registerForm.$setPristine();
$scope.forms.registerForm.$setUntouched();
$scope.msg = {};
$scope.msg.successRegister = 'Registered Successfully';
} else {
$scope.msg = {};
$scope.msg.errorRegister = 'Email already exists!';
}
})
.finally(function (data) {
$scope.loading = false;
});
};
When the user clicks on Submit button, I want to create a confirmation page where it will give the user all the details again so the user can confirm and then actually submit the form. Kindly let me know how can I use localStorage for storing and retrieving the data at the same time for confirm page.
Thank you in advance!
UPDATE: I created a MDDialog and calling it when the button is clicked,I can see all the data as well in MDDialog now. When user clicks on OK, I want the data on the page(not the data on the MDDialog) to be submited in the backend(php), how can I do that?
Why not show this info on a modal, and call the confirmation function in the same controller where you are, after the modal is closed. This way you won't need any caching policy.

jQuery AJAX TypeError: Cannot read property 'count' of undefined

I am trying to make an AJAX request when submitting a form, but I cannot even see the request in the Network panel because it fails before hitting the URL. This is the code:
// contact form
$(function() {
$(document).on("submit", "#contact-form", function(e) {
// prevents normal submit
e.preventDefault();
var form = $(this);
var url = form.attr("action");
$.post(url, function(data) {
alert(data);
})
.fail(function (jqXHR, textStatus, errorThrown) {
alert(errorThrown); // TypeError: Cannot read property 'count' of undefined
});
});
})
And this is the HTML:
This is the HTML:
<form name="contact" method="post" action="/app_dev.php/contacts/submit" id="contact-form">
<div class="row">
<div class="col-xl-6 form-group">
<input type="text" id="contact_firstname" name="contact[firstname]" maxlength="255" class="form-control form-control-lg" placeholder="Entre ton nom*" />
</div>
<div class="col-xl-6 form-group">
<input type="text" id="contact_lastname" name="contact[lastname]" required="required" maxlength="255" class="form-control form-control-lg" placeholder="Entre ton nom de famille*" />
</div>
<div class="col-xl-6 form-group">
<input type="email" id="contact_email" name="contact[email]" required="required" maxlength="255" class="form-control form-control-lg" placeholder="Entre ton adresse e-mail*" />
</div>
<div class="col-xl-6 form-group">
<input type="text" id="contact_subject" name="contact[subject]" required="required" maxlength="255" class="form-control form-control-lg" placeholder="Entre le sujet*" />
</div>
<div class="col-12 mb-5">
<textarea id="contact_message" name="contact[message]" required="required" class="form-control" rows="3" placeholder="Écris ton message*"></textarea>
</div>
<input type="hidden" name="_csrf_token" value="Su1QsqB8LZdqqVRxrxBPeXQNpp29QlYEt7yvg13hzCI">
<div class="col-xl-3">
<button type="submit" class="btn btn-xl btn-block">Envoyer</button>
</div>
</div>
</form>
I always receive an alert with this message: TypeError: Cannot read property 'count' of undefined.
If I try to put the same code outside of the submit (in the document ready event) it works fine:
// contact form
$(function() {
//$(document).on("submit", "#contact-form", function(e) {
//// prevents normal submit
//e.preventDefault();
//});
var form = $("contact-form");
var url = form.attr("action");
$.post(url, function(data) {
alert(data);
})
.fail(function (jqXHR, textStatus, errorThrown) {
alert(errorThrown); // WORKS FINE
});
})
These are my JavaScript files:
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
<script type="text/javascript" src="/js/app.js"></script>
I seems that it was a very odd bug caused by the Symfony Web Profiler Toolbar! Luckily a fix has been released 13 hours ago:
https://github.com/symfony/symfony/releases/tag/v2.8.36
This is the issue:
https://github.com/symfony/symfony/pull/26368

Categories