Hidden input not submitted after updating value in on submit event - javascript

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.

Related

Laravel - Image File Uploader submits save button instead of uploading image

I am using Laravel-5.8 for my project. I want to upload image, and click on submit button to save the image and other text fields into the database.
Controller
public function create()
{
$countries = ConfigCountries::all();
return view('organization.companies.create')->with('countries', $countries);
}
public function store(Request $request)
{
try {
$orgStartDate = Carbon::parse($request->org_start_date);
$arr = [
'organisation_code' => $request->organisation_code,
'organisation_name' => $request->organisation_name,
'website' => $request->website,
'org_decription' => $request->org_description,
'total_employees' => $request->total_employees,
'registration_number' => $request->registration_number,
'org_start_date' => $request->$orgStartDate,
'phone_number' => $request->phone_number,
'secondary_phone' => $request->secondary_phone,
'email' => $request->email,
'secondary_email' => $request->secondary_email,
'address1' => $request->address1,
'address2' => $request->address2,
'country_id' => $request->country_id,
'created_by' => Auth::user()->id,
'created_at' => date("Y-m-d H:i:s"),
'is_active' => 1,
];
if ($request->org_image != "") {
$org_image = time() . '_' . $request->org_image->getClientOriginalName();
$request->org_image->move('storage_files/companies/profile/', $org_image);
$arr['org_image'] = 'storage_files/companies/profile/' . $org_image;
}
$company = OrgCompany::create($arr);
$company->save();
Session::flash('success', 'Company is created successfully');
return redirect()->route('organization.companies.index');
} catch (Exception $exception) {
return back()->withInput()
->withErrors(['unexpected_error' => 'Unexpected error occurred while trying to process your request.']);
}
}
view
<div class="card-body">
<form action="{{ route("organization.companies.store") }}" method="post class="form-horizontal" enctype="multipart/form-data">
{{csrf_field()}}
<div class="text-center">
<input type="image" class="profile-user-img img-fluid img-circle"
src="{{asset('theme/adminlte3/dist/img/company_logo.png')}}"
id="wizardPicturePreview" title="" width="150">
<input type="file" name="picture" id="wizard-picture" class="" hidden>
<h4 class="profile-username text-center">Click On Image to Add Logo</h4>
</div>
<span style="color:blue;"><h4 class="box-title"><b>Contact Information</b></h4></span>
<hr class="m-t-0 m-b-40">
<div class="row">
<div class="col-md-6">
<div class="form-group row">
<label class="control-label text-right col-md-3"> Phone No.</label>
<div class="col-md-9 controls">
<input type="text" name="phone_number" placeholder="Enter Company Phone no. here" class="form-control" value="{{old('phone_number')}}">
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group row">
<label class="control-label text-right col-md-3"> Alternative Phone No.</label>
<div class="col-md-9 controls">
<input type="text" name="secondary_phone" placeholder="Enter Alternative Phone no. here" class="form-control" value="{{old('secondary_phone')}}">
</div>
</div>
</div>
<!--/span-->
</div>
<hr>
<div class="form-actions">
<div class="row">
<div class="col-md-6">
<div class="row">
<div class="col-md-offset-3 col-md-9">
<button type="submit" class="btn btn-primary">Add Company</button>
<button type="button" onclick="window.location.href='{{route('organization.companies.index')}}'" class="btn btn-default">Cancel</button>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<script>
$(document).ready(function(){
$("#wizard-picture").change(function(){
readURL(this);
});
});
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#wizardPicturePreview').attr('src', e.target.result).fadeIn('slow');
}
reader.readAsDataURL(input.files[0]);
} }
$("input[type='image']").click(function() {
$("input[id='wizard-picture']").click();
});
$(".form-control").keypress(function(e) {
if (e.which == 13) {
e.preventDefault();
return false;
}
});
</script>
The issue is that without clicking on the save submit button, when I clicked on image file uploader, it redirects to the index page without uploading the image to the screen.
How do I resolve this?
Thanks
An input type of image is a way to define an image as a submit button, so clicking on the image actually is submitting the form. You can either change the image to a regular <img> tag or change you click handler to prevent the default action like so
$("input[type='image']").click(function(e) {
e.preventDefault();
$("input[id='wizard-picture']").click();
});
Also just a heads up, you have a typo in the line that opens your form. There's no closing quotes after method="POST which is probably why the page is just redirecting on submit
Maybe because the closing quote of method is missing in <form> starting tag

Used bootstrap for validating the form ,even there is some validation the form is getting submitted.How should I avoid it

I am using the bootstrap 'needs-validation' for checking the validation form. Here when I click the submit button its validating the field and form is also getting submitted. What I want is when the validation fails the form should not get submitted. I found the form validation from (needs validation) from here https://www.w3schools.com/bootstrap4/bootstrap_forms.asp and I used it in my program.
My script is
<div class="row top-space-30">
<form class="needs-validation" novalidate action="" method="">
<div class="form-group row">
<label class="col-md-4 col-form-label text-md-right" for="studentname">Student Name:</label>
<div class="col-md-6">
<input id="role" name="studentname" type="text" placeholder="name" class="form-control input-md"
required>
<div class="valid-feedback">Valid.</div>
<div class="invalid-feedback">Please fill out this field.</div>
</div>
</div>
<div class="form-group row">
<label class="col-md-4 col-form-label text-md-right" for="department">Department:</label>
<div class="col-md-8">
<input class="form-control" type="text" id="department">
<input type="hidden" id="TestHidden" value="{{result}}" required>
</div>
</div>
<div class="col-md-6 offset-md-4 top-space-30">
<button type="submit" id="submit">Submit</button>
</div>
</form>
</div>
</div>
<script>
// Disable form submissions if there are invalid fields
(function () {
'use strict';
window.addEventListener('load', function () {
// Get the forms we want to add validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function (form) {
form.addEventListener('submit', function (event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}, false);
})();
$("#submit").click(function (e) {
var studentName = $("#role").val();
var departmentsList = $("#department").val().split(',');
$.ajax({
type: 'POST',
url: '/students/add',
data: {
'role': studentName,
'departmentslist': JSON.stringify(departmentsList)
},
success: function (result) {
alert("The department has been added");
document.location.href = "/department";
}
})
})
</script>
Try this one, I have one function for validationsformSubmit add your own validations in that function.
<div class="row top-space-30">
<form class="needs-validation" name="myForm" action="" method="" onsubmit=" return formSubmit()" >
<div class="form-group row">
<label class="col-md-4 col-form-label text-md-right" for="studentname">Student Name:</label>
<div class="col-md-6">
<input id="role" name="studentname" type="text" placeholder="name" class="form-control input-md"
required>
<div class="valid-feedback">Valid.</div>
<div class="invalid-feedback">Please fill out this field.</div>
</div>
</div>
<div class="form-group row">
<label class="col-md-4 col-form-label text-md-right" for="department">Department:</label>
<div class="col-md-8">
<input class="form-control" type="text" name = "departmentname" id="department">
<input type="hidden" id="TestHidden" value="{{result}}" required>
</div>
</div>
<div class="col-md-6 offset-md-4 top-space-30">
<button type="Submit" id="submit">Submit</button>
</div>
</form>
</div>
</div>
<script
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"></script>
<script>
//Disable form submissions if there are invalid fields
(function () {
'use strict';
window.addEventListener('load', function () {
// Get the forms we want to add validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function (form) {
form.addEventListener('submit', function (event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}, false);
})();
function formSubmit(){
var forms = document.forms["myForm"];
var studenName = forms.studentname.value;
var departmentName = forms.departmentname.value;
// perform validation for studentname and departname if they are validated then return true, else for wrong input return false
if(isNaN(studentname) && isNaN(departmentname)){
return true;
}
else{
return false;
}
}
$("#submit").click(function (e) {
var studentName = $("#role").val();
var departmentsList = $("#department").val().split(',');
$.ajax({
type: 'POST',
url: '/students/add',
data: {
'role': studentName,
'departmentslist': JSON.stringify(departmentsList)
},
success: function (result) {
alert("The department has been added");
document.location.href = "/department";
}
})
})
</script>

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.

AngularJS 1.6.8: Unable to submit form and display success message

I have a simple query submission form with name, email and query fields and a component with a controller function having the submit function to submit the form.
I am using ng-submit directive in the <form></form> tag to submit the user input and display a success message on submission.
below is the code for the respective files.
contact.html
<div ngController="contactController as vm">
<div class="heading text-center">
<h1>Contact Us</h1>
</div>
<div>
<form class="needs-validation" id="contactForm" novalidate method="post" name="vm.contactForm" ng-submit="saveform()">
<div class="form-group row">
<label for="validationTooltip01" class="col-sm-2 col-form-label">Name</label>
<div class="input-group">
<input type="text" class="form-control" id="validationTooltipName" placeholder="Name" ng-model="vm.name" required>
<div class="invalid-tooltip">
Please enter your full name.
</div>
</div>
</div>
<div class="form-group row">
<label for="validationTooltipEmail" class="col-sm-2 col-form-label">Email</label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text" id="validationTooltipUsernamePrepend">#</span>
</div>
<input type="email" class="form-control" id="validationTooltipEmail" placeholder="Email"
aria-describedby="validationTooltipUsernamePrepend" ng-model="vm.email" required>
<div class="invalid-tooltip">
Please choose a valid email.
</div>
</div>
</div>
<div class="form-group row">
<label for="validationTooltip03" class="col-sm-2 col-form-label">Query</label>
<div class="input-group">
<input type="text" class="form-control" id="validationTooltipQuery" ng-model="vm.query" placeholder="Query" required>
<div class="invalid-tooltip">
Please write your Query.
</div>
</div>
</div>
<div class="btn-group offset-md-5">
<button class="btn btn-primary" type="submit">Submit</button>
<button class="btn btn-default" type="button" id="homebtn" ng-click="navigate ('home')">Home</button>
</div>
</form>
<span data-ng-bind="Message" ng-hide="hideMessage" class="sucessMsg"></span>
</div>
</div>
contact.component.js
angular.module('myApp')
.component('contactComponent', {
restrict: 'E',
$scope:{},
templateUrl:'contact/contact.html',
controller: contactController,
controllerAs: 'vm',
factory:'userService',
$rootscope:{}
});
function contactController($scope, $state,userService,$rootScope) {
var vm = this;
$scope.navigate = function(home){
$state.go(home)
};
$scope.saveform = function(){
$scope.name= vm.name;
$scope.email= vm.email;
$scope.query= vm.email;
$scope.hideMessage = false;
$scope.Message = "Your query has been successfully submitted."
};
$scope.user = userService;
};
//localStorage code
function userService($rootScope) {
var service = {
model: {
name: '',
email: '',
query:''
},
SaveState: function () {
sessionStorage.userService = angular.toJson(service.model);
},
RestoreState: function () {
service.model = angular.fromJson(sessionStorage.userService);
}
}
$rootScope.$on("savestate", service.SaveState);
$rootScope.$on("restorestate", service.RestoreState);
return service;
$rootScope.$on("$routeChangeStart", function (event, next, current) {
if (sessionStorage.restorestate == "true") {
$rootScope.$broadcast('restorestate'); //let everything know we need to restore state
sessionStorage.restorestate = false;
}
});
//let everthing know that we need to save state now.
window.onbeforeunload = function (event) {
$rootScope.$broadcast('savestate');
};
};
UPDATE: On Submit, When I check the response in network tab in dev tools, I do not see the submitted values. All I see is the markup.
In your template, the name of the method is saveform:
ng-submit="saveform()"
But in your controller, it's save:
$scope.save = function() { ... }
Rename it to saveform:
$scope.saveform = function() { ... }

Trying to send custom inputs to braintree but only payment_method_nonce works

I am attempting to have the user inputs( first name, last name, contract number, amount) pass to payment.php and then be sent via $result = Braintree_Transaction::sale but payment_method_nonce is the only thing that passes to payment.php. When test payment.php with <?php print_r($_POST); ?> I only receive Array ( [payment_method_nonce] => 9ce4f24f-9746-076c-760b-d30d18a3cdf5 ) Thanks in advance Here is my code:
HTML
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default bootstrap-basic">
<div class="panel-heading">
<h3 class="panel-title">Enter Payment Details</h3>
</div>
<form class="panel-body" id="paymentportal" action="payment.php" method="post">
<div class="row">
<div class="form-group col-sm-6">
<label class="control-label">First Name</label>
<!-- Hosted Fields div container -->
<input type="text" placeholder="John" class="form-control" id="first-name">
</div>
<div class="form-group col-sm-6">
<label class="control-label">Last Name</label>
<!-- Hosted Fields div container -->
<input type="text" placeholder="Doe" class="form-control" id="last-name">
</div>
</div>
<div class="row">
<div class="form-group col-sm-6">
<label class="control-label">Contract Number</label>
<!-- Hosted Fields div container -->
<input type="text" placeholder="1462" class="form-control" id="order-number">
</div>
<div class="form-group col-sm-6">
<label class="control-label">Amount</label>
<!-- Hosted Fields div container -->
<input type="text" placeholder="$1234.56" class="form-control" id="amount">
</div>
</div>
<div class="row">
<div class="form-group col-sm-8">
<label class="control-label">Card Number</label>
<!-- Hosted Fields div container -->
<div class="form-control" id="card-number"></div>
<span class="helper-text"></span>
</div>
<div class="form-group col-sm-4">
<div class="row">
<label class="control-label col-xs-12">Expiration Date</label>
<div class="col-xs-6">
<!-- Hosted Fields div container -->
<div class="form-control" id="expiration-month"></div>
</div>
<div class="col-xs-6">
<!-- Hosted Fields div container -->
<div class="form-control" id="expiration-year"></div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-sm-6">
<label class="control-label">Security Code</label>
<!-- Hosted Fields div container -->
<div class="form-control" id="cvv"></div>
</div>
<div class="form-group col-sm-6">
<label class="control-label">Zipcode</label>
<!-- Hosted Fields div container -->
<div class="form-control" id="postal-code"></div>
</div>
</div>
<input type="hidden" name="payment_method_nonce" id="payment_method_nonce">
<button value="btnSubmit" id="btnSubmit" class="btn-box center-block">Pay with <span id="card-type">Card</span></button>
</form>
</div>
</div>
JS
var form = document.getElementById('paymentportal');
braintree.client.create({
authorization: 'sandbox_authorization'
}, function (err, clientInstance) {
if (err) {
console.error(err);
return;
}
braintree.hostedFields.create({
client: clientInstance,
styles: {
'input': {
'font-size': '14px',
'font-family': 'helvetica, tahoma, calibri, sans-serif',
'color': '#3a3a3a'
},
':focus': {
'color': 'black'
}
},
fields: {
number: {
selector: '#card-number',
placeholder: '4111 1111 1111 1111'
},
cvv: {
selector: '#cvv',
placeholder: '123'
},
expirationMonth: {
selector: '#expiration-month',
placeholder: 'MM'
},
expirationYear: {
selector: '#expiration-year',
placeholder: 'YY'
},
postalCode: {
selector: '#postal-code',
placeholder: '90210'
}
}
}, function (err, hostedFieldsInstance) {
if (err) {
console.error(err);
return;
}
hostedFieldsInstance.on('validityChange', function (event) {
var field = event.fields[event.emittedBy];
if (field.isValid) {
if (event.emittedBy === 'expirationMonth' || event.emittedBy === 'expirationYear') {
if (!event.fields.expirationMonth.isValid || !event.fields.expirationYear.isValid) {
return;
}
} else if (event.emittedBy === 'number') {
$('#card-number').next('span').text('');
}
// Remove any previously applied error or warning classes
$(field.container).parents('.form-group').removeClass('has-warning');
$(field.container).parents('.form-group').removeClass('has-success');
// Apply styling for a valid field
$(field.container).parents('.form-group').addClass('has-success');
} else if (field.isPotentiallyValid) {
// Remove styling from potentially valid fields
$(field.container).parents('.form-group').removeClass('has-warning');
$(field.container).parents('.form-group').removeClass('has-success');
if (event.emittedBy === 'number') {
$('#card-number').next('span').text('');
}
} else {
// Add styling to invalid fields
$(field.container).parents('.form-group').addClass('has-warning');
// Add helper text for an invalid card number
if (event.emittedBy === 'number') {
$('#card-number').next('span').text('Looks like this card number has an error.');
}
}
});
hostedFieldsInstance.on('cardTypeChange', function (event) {
// Handle a field's change, such as a change in validity or credit card type
if (event.cards.length === 1) {
$('#card-type').text(event.cards[0].niceType);
} else {
$('#card-type').text('Card');
}
});
$('.panel-body').submit(function (event) {
event.preventDefault();
hostedFieldsInstance.tokenize(function (err, payload) {
if (err) {
console.error(err);
return;
}
document.querySelector('input[name="payment_method_nonce"]').value = payload.nonce;
// This is where you would submit payload.nonce to your server
form.submit();
});
});
});
});
PHP
<?php
$result = Braintree_Transaction::sale([
'amount' => $_POST['amount'],
'orderId' => $_POST['order-number'],
'paymentMethodNonce' => $_POST['payment_method_nonce'],
'customer' => [
'firstName' => $_POST['first-name'],
'lastName' => $_POST['last-name'],
],
'options' => [
'submitForSettlement' => true
]
]);
if ($result->success === true){
}else
{
print_r($result->errors);
die();
}
?>
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact
support.
Remember when you collect form data on your server, you need to reference those inputs by their name attribute. Once you add the respective name values to each of these inputs, it should work as expected.
For example, your first name input;
<input type="text" placeholder="John" class="form-control" id="first-name" name="first-name">

Categories