jQuery dialog partial form submit validation - javascript

I have the following partial view (I have removed some of the formatting just to keep it simple on this forum). My form tag is on the parent page, and the items on the dialog are a part of that form.
This is a strongly typed partial view. I have defined the password and confirmPassword fields as [Required] in my Model.
#Html.LabelFor(m => m.password)
Reset Password
<div id="dialogResetPassword" title="Reset Password">
<p>Reset password for user: #Model.userId</p>
#Html.LabelFor(m => m.password)
#Html.PasswordFor(m => m.password)
#Html.ValidationMessageFor(m => m.password)
<div class="rowEnd"></div>
#Html.LabelFor(m => m.confirmPassword)
#Html.PasswordFor(m => m.confirmPassword)
#Html.ValidationMessageFor(m => m.confirmPassword)
<div class="rowEnd"></div>
</div>
I have the following javascript for the initialization of the dialog:
function initializeResetPasswordDialog() {
$(resetPasswordDialogId).dialog(
{
autoOpen: false,
autoResize: true,
buttons: {
Ok: function () {
if (!($('#userForm').valid())) {
return false;
}
//more code goes here ...
closeResetPasswordDialog();
},
Cancel: function () {
closeResetPasswordDialog();
}
}
});
}
My dialog initializes, opens and closes fine, but when I try to check the validity of the items in the dialog, I always get "valid".
I do not want to submit the entire form, but just submit the password and the confirm password fields on the Ok button, and also fire up my validations. Any suggestions on how to do this?

Ok, so I solved it by adding the following function to the open parameter for the jQuery dialog:
open: function () {
$(this).parent().appendTo("#userForm");
}
I noticed that when initializing a jQuery dialog, even though it was within my form, when the HTML page rendered in the browser, the dialog div was moved outside the form. For the validations to work, the inputs must be within a form.
I hope this post helps other people too!

Related

Bootstrap V5 Form Validation & Sweetalert2 : Showing success message after successful submission

I have simple form based on Bootstrap 5 with a validation option I'm trying to display alert message if the form field is successfuly submited using Sweatalert2.
Here is my Code :
HTML
<form action="" method="POST" class="needs-validation" novalidate>
<label for="validationCustomUsername" class="form-label">Username</label>
<div class="input-group has-validation mb-3">
<span class="input-group-text" id="inputGroupPrepend">#</span>
<input type="text" class="form-control" id="validationCustomUsername" placeholder="Username *" aria-describedby="inputGroupPrepend" required />
<div class="invalid-feedback">
Please choose a username.
</div>
</div>
<button class="btn btn-primary" type="submit">Submit form</button>
</form>
JS
(function () {
'use strict'
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.querySelectorAll('.needs-validation')
// Loop over them and prevent submission
Array.prototype.slice.call(forms)
.forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
Live Example
I was having the same issue and came across this post which quite helpful.
Below code might help:
......
form.classList.add('was-validated');
if (form.reportValidity()) {
event.preventDefault()
Swal.fire({
position: 'center',
icon: 'success',
title: 'Your application has been submitted successfully!',
showConfirmButton: false,
timer: 2500
}).then((result) => {
// Reload the Page
location.reload();
});
}
It will reload the page after form submission.
This is may be too late, but I hope it can help others. I have the same issue. Then, I tried to combine bootstrap validation inside the SweetAlert Confirmation Box before submitting the form.
I create the code like below:
$('#submitForm').on('click', function (e) {
e.preventDefault();// prevent form submit
/*this part is taken from bootstrap validation*/
var forms = document.getElementsByClassName('needs-validation');
var validation = Array.prototype.filter.call(forms, function (form) {
if (form.checkValidity() === false) {
form.classList.add('was-validated');
}
else {
Swal.fire({
title: 'Are you sure?',
text: "It cannot be undone",
type: 'warning',
icon: 'question',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, send it!'
}).then((result) => {
if (result.value) {
/*submit the form*/
$("#formsubmitsekali").submit();
}
});
}
}, false);
});
submitForm is the ID name for the button ID for submit the form.
formsubmitsekali is the form ID.
By doing so, if the required field is not filled, it will show the bootstrap validation without showing Sweetalert confirmation box. But if all of required fields are filled, the Sweetalert will show up.
The same behavior also happens if you have email input type, but it is filled by non-email, it will run the bootstrap validation first. It is also work if you use HTML5 pattern inside the input type and the user fills with the wrong pattern.

Braintree JSv3 payment_method_nonce Value Bad With HostedFields

I have looked at a few posts on here with the same issue but under different circumstances that don't supply me with an answer to my particular issue...
I was using Braintree JSv2 with my Django project and all was working fine. Since I have migrated over to v3 of Braintree, the only issue I seem to have right now is that the value inputted to "payment_method_nonce" is not there...
Here is the code that is supposed to be dumping the payment_method_nonce value:
document.querySelector('input[name="payment_method_nonce"]').value = payload.nonce;
And here is the code that is supposed to be grabbing it on the python side:
client_payment_nonce = request.POST['payment_method_nonce']
When submitting this in my dev environment, I get an error (MultiValueDictKeyError) for "payment_method_nonce".
I am using Django 1.9 and Python 2.7. I am also using the example given by Braintree for a simple integration using HostedFields...
Small test
So I manually added an input field in my form with name "payment_method_nonce" just to see if not having a field was causing some issue. I know it is injected by Braintree but just testing a thought. It seems that although the value of payment_method_nonce is supposed to be my nonce, I didn't type anything into the input box and it was still coming back as null.
Full Snippets of Form and HostedFields
<form action="/booking/" method="post" id="checkout_form">
{% csrf_token %}
<div class="payment">
<span>Payment</span>
<!--input elements for user card data-->
<div class="hosted-fields" id="card-number"></div>
<div class="hosted-fields" id="postal-code"></div>
<div class="hosted-fields" id="expiration-date"></div>
<div class="hosted-fields" id="cvv"></div>
<div class="btns">
<input type="hidden" name="payment_method_nonce">
<input type="submit" value="Complete Booking" id="pay-button">
</div>
</div>
</form>
Note: I had just changed the payment_method_nonce field to type="hidden" instead of type="text" but still have the same effect...
<!-- load the required client component -->
<script src="https://js.braintreegateway.com/web/3.15.0/js/client.min.js"></script>
<!-- load the hosted fields component -->
<script src="https://js.braintreegateway.com/web/3.15.0/js/hosted-fields.min.js"></script>
<!-- Braintree setup -->
<script>
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) {
// Handle error in client creation
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) {
// handle error in Hosted Fields creation
return;
}
submit.removeAttribute('disabled');
form.addEventListener('submit', function (event) {
event.preventDefault();
hostedFieldsInstance.tokenize(function (tokenizeErr, payload) {
if (tokenizeErr) {
// handle error in Hosted Fields tokenization
return;
}
// Put `payload.nonce` into the `payment_method_nonce`
document.querySelector('input[name="payment_method_nonce"]').value = payload.nonce;
document.querySelector('input[id="pay-button"]').value = "Please wait...";
form.submit();
});
}, false);
});
});
</script>
Note: the line document.querySelector('input[id="pay-button"]').value = "Please wait..."; doesn't fire (I know this because the button does not change values). Maybe these querySelector lines just aren't working?
Something New Noticed
I just went back to my page and hit the submit button without even entering any information. In v2 of Braintree, I would not be able to click the submit button until all fields were filled in... Maybe the values in my form aren't even being sent to braintree to receive a nonce and that's why there is an empty string being returned..?
Moral of the story
Review your code... Multiple times. As pointed out by C Joseph, I have my form ID as something different than what my var form is referencing...
<form action="/booking/" method="post" id="checkout_form">
var form = document.querySelector('#checkout-form');

Multiple Submit from Drop downs in a single Form

I have a MVC5 setup with two Dropdowns that via Javascript automatically submits when a value is selected.
They are currently inside the same form, so i would like to have them submit to different Actions on my Backend
View:
<div class="panel-body">
#using (Html.BeginForm("", "BrugerSession"))
{
#Html.AntiForgeryToken()
<div class="row">
<div class="col-md-6">
#Html.LabelFor(model => model.Emails)
#Html.DropDownListFor(x => x.ValgtEmail, Model.Emails, "Vælg Email")
</div>
<div class="col-md-6">
#Html.LabelFor(model => model.Printere)
#Html.DropDownListFor(x => x.ValgtPrinter, Model.Printere)
</div>
</div>
}
</div>
JavaScript
$(document).ready(function () {
$("#ValgtEmail").change(function () {
$(this).closest('form').trigger('submit');
});
});
$(document).ready(function () {
$("#ValgtPrinter").change(function () {
$(this).closest('form').trigger('submit');
});
});
The trick here is, that i am using How do you handle multiple submit buttons in ASP.NET MVC Framework? to support multiple submit-targets in the Backend.
Why main Question is: Can the Javascript Trigger method submit the data in the propper way, so it will works with the Solution from the above link?
I tried looking into the http://api.jquery.com/trigger/ Documentation and there is support for additional parameters. But i do know how to format my Javascript to achieve what I need.
Update:
I never managed to get this working. Instead i surrounded each Select with its own form.
I hope my answer will help you. You can use JQuery AJAX.
First drop down
$("#dropdown1").change(function(){
$.ajax({
url: '/ControllerName/Action1',
data: { parm1:parm1 },
success: function () {
// Success function
},
error: function () {
// Error message
}
});
});
Second drop down
$("#dropdown2").change(function(){
$.ajax({
url: '/ControllerName/Action2',
data: { parm1:parm1 },
success: function () {
// Success function
},
error: function () {
// Error message
}
});
});

how to configure custom upload area in dropzone.js with mvc4 form

I just started looking into dropzone.js Is it possible to somehow modify the previewTemplate area to add additional info about the files uploaded and then submit the form to an mvc method?
For simplicity I want to add two fields DocumentTypeID and ExpirationDate for each file that a user wants to upload
#model MyProject.Model.Document
#using (Html.BeginForm("Create", "Document", FormMethod.Post, new { enctype = "multipart/form-data", #class = "dropzone", #id = "my-awesome-dropzone" }))
{
<div class="row-fluid">
<fieldset class="span6">
<div class="editor-label">
#Html.LabelFor(model => model.DocumentTypeID, "DocumentType")
</div>
<div class="editor-field">
#Html.DropDownList("DocumentTypeID", String.Empty)
#Html.ValidationMessageFor(model => model.DocumentTypeID)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.ExpirationDate)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ExpirationDate)
#Html.ValidationMessageFor(model => model.ExpirationDate)
</div>
</fieldset>
<div class="span6"> <div class="dropzone-previews"></div> </div>
</div>
}
Here is the controller method which for now should accept one file at a time
[HttpPost]
public ActionResult Create(Document document, HttpPostedFileBase file)
{
if (ModelState.IsValid && file != null)
{
db.Documents.Add(document);
document.FilePath = ProcessDocumentUpload(Request.Files[0], document.DocumentID);
db.SaveChanges();
return "";//? // not sure what to return yet
}
}
Now the Js function for dropzone
<script type="text/javascript">
$(function () {
// "myAwesomeDropzone" is the camelized version of the HTML element's ID
Dropzone.options.myAwesomeDropzone = {
autoDiscover: false,
paramName: "file", // The name that will be used to transfer the file
maxFilesize: 5, // MB
maxFiles: 1, //for now upload one at a time
//I started looking at the template and added two elements as an experiment.
previewTemplate: "<div class=\"dz-preview dz-file-preview\">\n <div class=\"dz-details\">\n <div class=\"dz-filename\"><span data-dz-name></span></div>\n <div class=\"dz-size\" data-dz-size></div>\n <img data-dz-thumbnail />\n </div>\n <input type=\"text\" data-dz-doc-expiration-date class=\"dz-doc-input\" />\n <select class=\"dz-doc-input\" data-dz-doc-document-type-id ></select>\n <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress></span></div>\n <div class=\"dz-success-mark\"><span>✔</span></div>\n <div class=\"dz-error-mark\"><span>✘</span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n</div>",
//dictDefaultMessage: "Drop files here to upload or click",
// The configuration that allows the whole form to be submitted on button click
autoProcessQueue: false,
uploadMultiple: false,
parallelUploads: 1,
addRemoveLinks: true,
previewsContainer: ".dropzone-previews", //show a preview in another place
// The setting up of the dropzone
init: function () {
var myDropzone = this;
// First change the button to actually tell Dropzone to process the queue.
$("input[type=submit]").on("click", function (e) {
// Make sure that the form isn't actually being sent.
e.preventDefault();
e.stopPropagation();
myDropzone.processQueue();
});
// Listen to the sendingmultiple event. In this case, it's the sendingmultiple event instead
// of the sending event because uploadMultiple is set to true.
this.on("sendingmultiple", function () {
// Gets triggered when the form is actually being sent.
// Hide the success button or the complete form.
});
this.on("successmultiple", function (files, response) {
// Gets triggered when the files have successfully been sent.
// Redirect user or notify of success.
});
this.on("errormultiple", function (files, response) {
// Gets triggered when there was an error sending the files.
// Maybe show form again, and notify user of error
});
},
accept: function (file, done) {
//maybe do something here for showing a dialog or adding the fields to the preview?
}
};
});
</script>
Thanks for looking!
have you tried to handle the event 'sending'?
$dropzone.on('sending', function (file, xhr, formData) {
formData.append('id', $id);
});
MVC controller
public JsonResult UploadImage(string id)
{
for (int i = 0; i < Request.Files.Count; i++)
{
HttpPostedFileBase file = Request.Files[i];
...
}
return Json(true, JsonRequestBehavior.DenyGet);
}
I've been using also MVC 4 and it has worked well.

Alert Javascript as return response of action

how can i do, for example, i create a user in users.cshtml view, that it validates to ActionResult Create(RegisterModel um) and if its all ok, i want to return at users.cshtml but always with one javascript alert or similar, with the value of a variable from the action. Can i do this one?
I have it this in my view..
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Crear Usuario</legend>
<div class="editor-label">
Username:
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.UserName)
#Html.ValidationMessageFor(model => model.UserName)
</div>
<div class="editor-label">
Password:
</div>
<div class="editor-field">
#Html.PasswordFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<div class="editor-label">
Repite Password:
</div>
<div class="editor-field">
#Html.PasswordFor(model => model.ConfirmPassword)
#Html.ValidationMessageFor(model => model.ConfirmPassword)
</div>
</div>
<p>
<input type="submit" value="Crear" />
</p>
</fieldset>
And this in my controller action..
public ActionResult Create(RegisterModel um)
{
if (um.Password == um.ConfirmPassword)
{
// Attempt to register the user
MembershipCreateStatus createStatus;
Membership.CreateUser(um.UserName, um.Password, um.Email, um.PasswordAnswer, um.PasswordQuestion, true, null, out createStatus);
if (createStatus == MembershipCreateStatus.Success)
{
var alert = MembershipCreateStatus.Success.ToString();
}
else
{
ModelState.AddModelError("", ErrorCodeToString(createStatus));
var alert = ErrorCodeToString(createStatus);
}
}
//HERE IS WHERE I WANT TO RETURN TO /ADMIN/USERS BUT WITH AN ALERT WITH CONTAINING THE VALUE OF alert IN A JAVASCRIPT OR SIMILAR ALERT WINDOW
return RedirectToAction("Users", "Admin"); ???????
Can i do it something like this?
You could store the message inside TempData just before redirecting to the Users action:
TempData["message"] = "some message that you want to display";
return RedirectToAction("Users", "Admin");
and then inside the Users.cshtml view (which is returned by the Users action to which you redirected) test for the presence of this message and display an alert:
#if (TempData["message"] != null) {
<script type="text/javascript">
alert(#Html.Raw(Json.Encode(TempData["message"])));
</script>
}
i was trying to show error in same view, instead of trying darin's answer i tried other like this using ViewBag and this to show error in another page by returning Partial View
finally i tried using TempData, to maintain the message during post, here i am showing error using bootstrap
action method:
[HttpPost]
public ActionResult RegDetail(User_table usob, FormCollection col)
{
// some other code here
if (!sqlReader.HasRows)
{
TempData["message"] = "Contains some message";
return RedirectToAction("Registration");
}
return RedirectToAction("Index");
}
my registration view:
#if (TempData["message"] != null)
{
<link href="~/css/boostrap.css" rel="stylesheet" />
<script src="~/js/boostrap.min.js"></script>
<div class="alert alert-danger">
<a class="close" data-dismiss="alert">×</a>
<strong style="width:12px">Error!</strong> Thats wrong code no, try entering correct!
</div>
}
if you need to explore more using Tempdata you can check this where Mr.James explains using bootstrap messages, hope helps someone

Categories

Resources