I am currently using Django 1.9 and Braintree payments JS v3. What I want to be able to do is when the user submits the form successfully, have a Javascript alert() pop up. But the pop-up message will be contingent on what the back end Python returns...
So like this:
Submit the form
Run the backend stuff
Pop up the alert with a message dependent on what is returned by the Python backend
When the alert is closed, refresh or redirect
var client_token = "{{ request.session.braintree_client_token }}"
var form = document.querySelector('#checkout-form');
var submit = document.querySelector('input[type="submit"]');
braintree.client.create({
authorization: client_token
}, function (clientErr, clientInstance) {
if (clientErr) { // for error loading client authorization
if(alert('There was a form verification issue, reloading page on close.')){}
else window.location.reload();
return;
}
braintree.hostedFields.create({
client: clientInstance,
styles: {
'input': {
'font-size': '14px'
},
'input.invalid': {
'color': 'red'
},
'input.valid': {
'color': 'green'
}
},
fields: {
number: {
selector: '#card-number',
placeholder: 'Credit Card Number'
},
cvv: {
selector: '#cvv',
placeholder: '123'
},
expirationDate: {
selector: '#expiration-date',
placeholder: '10/2019'
},
postalCode: {
selector: '#postal-code',
placeholder: '10014'
}
}
}, function (hostedFieldsErr, hostedFieldsInstance) {
if (hostedFieldsErr) { // for errors creating form
if(alert('There was a form creation issue, reloading page on close.')){}
else window.location.reload();
return;
}
submit.removeAttribute('disabled');
form.addEventListener('submit', function (event) {
event.preventDefault();
document.querySelector('input[id="pay-button"]').value = "Please wait...";
hostedFieldsInstance.tokenize(function (tokenizeErr, payload) {
if (tokenizeErr) {
if (tokenizeErr.code === 'HOSTED_FIELDS_FIELDS_EMPTY') {
alert('Please fill in card info');
document.querySelector('input[id="pay-button"]').value = "Complete Booking";
}
return;
}
// Put `payload.nonce` into the `payment_method_nonce`
document.querySelector('input[name="payment_method_nonce"]').value = payload.nonce;
form.submit();
$('input[type="submit"]').prop('disabled',true);
});
}, false);
});
});
I'm thinking that this functionality would need to be right after form.submit() is run on the bottom...
Edit:
I added the vars up top in my code
Related
could someone help me with one problem? I want to add a process bar when you waiting for a response from the server (Django 3.x).
Step to reproduce:
On the page 'A' we have the form.
Enter data to form.
Submit POST request by clicking to button on the page 'A'.
Waiting for getting the result on the page 'A'.
Get the result on the page 'A'.
So, I want to add process bar after 4th and before 5th points on the page 'A'. When you will get the result on the page 'A' it should disappear.
Python 3.7
Django 3.x
You can use nprogress, it's a library used for progress bars. Use this inside the interceptor where you can config it for displaying only when request is in progress until finished.
There are lots of ways to do this. I think using jquery would be easier. Basically you just need to prevent submitting the page and do an Ajax request to server. something like
<script type='text/javascript'>
$(document).ready(function () {
$("form").submit(function (e) {
// prevent page loading
e.preventDefault(e);
$('#loadinAnimation').show();
// preapre formdata
$.ajax({
type: "yourRequestType",
url: "yourUrlEndpoint",
data: formdata,
success: function (data) {
$('#loadinAnimation').hide();
// do rest of the work with data
}
});
});
});
</script>
and show appropriate loading animation in your html part
<div id='loadinAnimation' style='display:none'>
<div>loading gif</div>
</div>
You can also do it using UiKit Library in Javascript on your Django Template Page.
Below code is when a file is Uploaded
In your template file (template.html)
<body>
..
<form>
<progress id="js-progressbar" class="uk-progress" value="0" max="100" hidden></progress>
...
<div class="uk-alert-danger uk-margin-top uk-hidden" id="upload_error" uk-alert></div>
...
</form>
</head>
<script type="text/javascript">
$(document).ready(function(){
var bar = document.getElementById('js-progressbar');
UIkit.upload('.js-upload-list', {
url: '',
name : "customer-docs",
params :{
"csrfmiddlewaretoken":"{{csrf_token}}"
},
method : "POST",
concurrent:1,
allow:'*.(csv|xlsx)',
beforeSend: function (environment) {
console.log('beforeSend', arguments);
// The environment object can still be modified here.
// var {data, method, headers, xhr, responseType} = environment;
},
beforeAll: function (args,files) {
console.log('beforeAll', arguments);
},
load: function () {
console.log('load', arguments);
},
error: function (files) {
console.log("---------------")
},
complete: function () {
console.log('complete', arguments);
},
loadStart: function (e) {
console.log('loadStart', arguments);
bar.removeAttribute('hidden');
bar.max = e.total;
bar.value = e.loaded;
},
progress: function (e) {
console.log('progress', arguments);
bar.max = e.total;
bar.value = e.loaded;
},
loadEnd: function (e) {
console.log('loadEnd', arguments);
bar.max = e.total;
bar.value = e.loaded;
},
completeAll: function (data) {
console.log('completeAll', arguments);
console.log('completeAll', data);
let redirect_loc = ""
setTimeout(function () {
bar.setAttribute('hidden', 'hidden');
}, 1000);
// This is the response from your POST method of views.py
data.responseText = JSON.parse(data.responseText)
if(data.responseText.status == 201){
// swal is another library to show sweet alert pop ups
swal({
icon: data.responseText.status_icon,
closeOnClickOutside: true,
text: data.responseText.message,
buttons: {
Done: true
},
}).then((value) => {
switch (value) {
case "Done":
window.location.href = ""
break;
}
});
}
else if(data.responseText.status == 500){
swal({
icon: data.responseText.status_icon,
closeOnClickOutside: true,
text: data.responseText.message,
buttons: {
Ok: true
},
}).then((value) => {
switch (value) {
case "Ok":
window.location.href = ""
break;
}
});
}
}
});
// This block of code is to restrict user to upload only specific FILE formats (below example is for CSV & XLSX files)
(function() {
var _old_alert = window.alert;
window.alert = function(e) {
console.log(e)
if(e.includes("csv|xlsx") || e.includes("Invalid file type")) {
$("#upload_error").html("Invalid file format. Valid formats are CSV, XLSX").removeClass('uk-hidden')
}else if(e.includes("Internal Server Error")) {
$("#upload_error").html("Internal Server Error Kindly upload Documents again").removeClass('uk-hidden')
}
else {
_old_alert.apply(window,arguments);
$("#upload_error").addClass('uk-hidden').html("")
}
};
})();
});
</script>
On your views.py you can do your computation and once done, you can return a response like below
resp_json = {
"status" : 201,
"status_icon" : "success",
"url" : "/",
"message": message
}
return HttpResponse(json.dumps(resp_json))
For more info on SWAL (Sweet Alerts), visit https://sweetalert.js.org/guides/
The first alert verifies whether the entered password corresponds to the user's password
If it does, then opens another alert where the user change the password if he has entered the same password in both fields
And finally, the third alert will open if it has successfully changed the password
The problem occurs if I click Cancel in the second alert or after confirming the third alert
After that, I'm not able to click on anything inside the app until I unload and restart the same application
So I guess the problem occurs because the alert is not closed properly
Here is my code:
$scope.changePass = function () {
$scope.newitem = {}
var myPopup = $ionicPopup.alert({
template: '<input type="password" placeholder="password" ng-model="newitem.password">',
title: 'Insert your password',
scope: $scope,
buttons: [
{ text: 'Cancel' },
{
text: '<b>Confirm</b>',
type: 'button-positive',
onTap: function(e) {
if (!$scope.newitem.password) {
console.log("preventing default");
e.preventDefault();
} else {
if($scope.newitem.password == $scope.user.password) {
$scope.new = {}
var newPass = $ionicPopup.alert({
template: '<input type="password" placeholder="password" ng-model="new.newpass"><br><input type="password" placeholder="Repeat password" ng-model="new.repeatpass">',
title: 'Insert your new password',
scope: $scope,
buttons: [
{ text: 'Cancel' },
{
text: '<b>Confirm</b>',
type: 'button-positive',
onTap: function(e) {
if (!$scope.new.newpass) {
console.log("preventing default");
e.preventDefault();
} else {
if (!$scope.new.repeatpass) {
$scope.new.newpass = "";
console.log("preventing default");
e.preventDefault();
} else {
if ($scope.new.newpass == $scope.new.repeatpass) {
$scope.user.password = $scope.new.newpass;
var uri = "http://someLink" + $window.localStorage.id;
$http({
method: 'PUT',
url: uri,
headers: {"Content-Type": "application/json;charset=UTF-8"},
data: $scope.user
}).success(function() {
var succesResponse = $ionicPopup.alert({
title: 'Ok',
template: "Password has changed"
});
succesResponse;
e.preventDefault();
});
}
else {
$scope.new.newpass = "";
$scope.new.repeatpass = "";
e.preventDefault();
}
}
}
}
}
]
});
}
else {
$scope.newitem.password = "";
e.preventDefault();
}
}
}
}
]
});
}
I found the answer to my question
Namely, the solution is to close the first alert before I open the second alert
But before I open second alert, it is necessary to have a timeout to close the first alert properly
myPopup.close();
$timeout(function() {
$scope.new = {}
var newPass = $ionicPopup.alert({...});
}, 500);
I am trying to build a dynamic popup that allows the user to edit data in a datatable without redirecting the page. I am using NodeJS with jQuery 'modal' library for the popup and 'formvalidation' library to validate and submit the data. (Note: This is not the same library as jquery validate).
Here's a demo of exactly what I am attempting to accomplish.
http://formvalidation.io/examples/loading-saving-data-modal/
I got most of the code working, I was able to display the modal window, passing in data and the validation works properly, too. The problem is that the success.form.fv event is not being triggered, the dialog just closes.
script.
$(document).ready(function () {
$('#editFilepathForm')
.formValidation({
framework: 'bootstrap',
icon: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
fields: {
id: {
validators: {
notEmpty: {
message: 'ID is required'
}
}
},
edited_filepath: {
validators: {
notEmpty: {
message: 'Edited Filepath is required'
},
regexp: {
regexp: /^[a-zA-Z\s]+$/,
message: 'The full name can only consist of alphabetical characters'
}
}
},
edited_filename: {
validators: {
notEmpty: {
message: 'Edited Filename is required'
},
regexp: {
regexp: /^[a-zA-Z\s]+$/,
message: 'The full name can only consist of alphabetical characters'
}
}
}
}
})
//THIS EVENT IS NOT TRIGGERING AT ALL. ALERT MESSAGE DOES NOT APPEAR. THE BOX JUST CLOSES AFTER SUCCESSFUL VALIDATION.
.on('success.form.fv', function (e) {
alert('success');
// Save the form data via an Ajax request
e.preventDefault();
var $form = $(e.target),
id = $form.find('[name="id"]').val();
// Hide the dialog
$form.parents('.bootbox').modal('hide');
// You can inform the user that the data is updated successfully
// by highlighting the row or showing a message box
bootbox.alert('The user profile is updated');
//});
});
$('.editButton').on('click', function () {
var id = $(this).attr('data-id');
var requested_filepath = $(this).attr('data-requested-filepath');
var requested_filename = $(this).attr('data-requested-filename');
/*Set original requested values to display in modal form window*/
$('#editFilepathForm')
.find('[name="id"]').html(id).end()
.find('[name="requested_filepath"]').html(requested_filepath).end()
.find('[name="requested_filename"]').html(requested_filename).end()
.find('[name="edited_filepath"]').val(requested_filepath).end()
.find('[name="edited_filename"]').val(requested_filename).end()
// Show the dialog
bootbox
.dialog({
title: 'Edit Requested Filepath',
message: $('#editFilepathForm'),
show: false // We will show it manually later
})
.on('shown.bs.modal', function () {
$('#editFilepathForm')
.show() // Show the login form
.formValidation('resetForm'); // Reset form
})
.on('hide.bs.modal', function (e) {
// Bootbox will remove the modal (including the body which contains the login form)
// after hiding the modal
// Therefor, we need to backup the form
$('#editFilepathForm').hide().appendTo('body');
})
.modal('show');
//});
});
});
I was able to resolve the issue by adding the 'excluded' property as explained in the documentation.
http://formvalidation.io/examples/modal/
I'm stuck at this point now. I never used braintree API before. The problem is when I hit the submit button it is showing alert box with my payment_method_nonce.
It means I'm successfully getting the payment_method_nonce from the client, But the problem is I don't know how can I submit a the form with this payment_method_nonce.
This client sdk is written in jquery.
And I tried several ways to submit the form but I don't know exactly how can I get a 'payment_method_nonce' when submitting a form.
I tired adding a hidden type field. And even that hidden type field doesn't comes up.
Please help. Here is the jquery code.
I just want to know how can I submit a form in jquery with that 'payment_method_nonce'.
braintree.client.create({
authorization: '{{$clientToken}}'
}, 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;
}
// This is where you would submit payload.nonce to your server
alert('Submit your nonce to your server here!' + payload.nonce);
});
});
});
});
Full disclosure: I work at Braintree. If you have any further questions, feel free to contact
support.
Without your form, or HTML code included, it's tough to know if you've defined your form as a variable. Essentially, though, you'll want to inject that nonce value (payload.nonce) into your form, following which you'll submit that form to your server.
For example, I have defined my form (above my braintree.client.create)
var form = document.querySelector('#checkout-form');
Then, in your submit event, you'll want to inject the payload value into your form after a successful tokenization (which you've seemed to achieve based on the alert value)
document.querySelector('input[name="payment_method_nonce"]').value = payload.nonce;
Subsequently submitting your form;
form.submit()
This will submit your form with an input named payment_method_nonce, which you can then request on your server.
Let me know if I can further clarify. Happy to help.
I'm trying to do a sencha touch app where the user first needs to register. After that, a pop up alert will say that you have registered and when the user presses the 'ok' button, the register form (register.js) will go to login form (login.js).
This is my register.js:
Ext.define('demo.view.Register',{
extend:'Ext.form.Panel',
xtype:'register',
requires:[
'Ext.form.FieldSet',
'Ext.field.Email',
'demo.view.Login'
],
config:{
title:'Register',
iconCls:'user',
url:'doRegister.php',
items:[
{
xtype:'fieldset',
title:'Registration!!!',
items:[
{
xtype:'textfield',
name:'username',
label:'Name'
},
{
xtype:'passwordfield',
name:'password',
label:'Password'
},
{
xtype:'emailfield',
name:'email',
label:'Email'
},
{
xtype:'textfield',
name:'first_name',
label:'First Name'
},
{
xtype:'textfield',
name:'last_name',
label:'Last Name'
}
]
},
{
xtype:'button',
text:'Share',
ui:'confirm',
handler: function() {
// This looks up the items stack above, getting a reference to the first form it see
var form = this.up('register');
// Sends an AJAX request with the form data to the url specified above (contact.php).
// The success callback is called if we get a non-error response from the server
form.submit({
success: function() {
Ext.Msg.alert('Status', 'Resgistered Successful!', function(btn, text){
if (btn == 'ok'){
var redirect = 'login.js';
window.location = redirect;
}
});
}
});
}
}
]
}
});
This is my login.js:
Ext.define('demo.view.Login',{
extend:'Ext.form.Panel',
xtype:'login',
requires:[
'Ext.form.FieldSet',
'Ext.field.Email'
],
config:{
title:'Login',
iconCls:'user',
url:'doLogin.php',
items:[
{
xtype:'fieldset',
title:'Please Login',
items:[
{
xtype:'textfield',
name:'username',
label:'username'
},
{
xtype:'passwordfield',
name:'password',
label:'password'
}
]
},
{
xtype:'button',
text:'Login',
ui:'confirm',
handler: function() {
// This looks up the items stack above, getting a reference to the first form it see
var form = this.up('share');
// Sends an AJAX request with the form data to the url specified above (contact.php).
// The success callback is called if we get a non-error response from the server
form.submit({
method:'POST',
waitTitle:'Connecting',
waitMsg:'Sending data...',
success: function() {
Ext.Msg.alert('Status', 'Login Successful!', function(btn, text){
if (btn == 'ok'){
var redirect = 'Share.js';
window.location = redirect;
}
});
}
});
}
}
]
}
});
You could put both of the forms inside one Container with a card layout (layout: 'card') and when you want to switch to the login form you can call setActiveItem(1) on the parent container.. It would be best to use a controller for this logic so you could have references to all of the containers/forms from that controller.
on alert ok button press you can create your login page to the viewport and then navigate to the login page.
here is the code :
Ext.Msg.alert('Demo', "Register successfully", function(){
Ext.Viewport.add(Ext.create('demo.view.Login'));
Ext.Viewport.animateActiveItem(this.getLogin(),{
type: 'slide',
direction: 'right'
});
});