validating that a canvas has been drawn in - javascript

I'm implementing an online waiver where a client has to sign into canvas before they can complete the form. I use Signature_Pad from szimek and jquery-validate and would like to have the canvas (which is part of the form) be included. I tried a custom formatter, like so:
let wrapper = document.getElementById("signature_pad");
var signaturePad = new SignaturePad(wrapper.querySelector("canvas"), {
backgroundColor: 'white'
});
jQuery.validator.addMethod("checkSignature", function(value, element) {
return signaturePad.isEmpty() == false;
}, "Signature must be provided");
$("form[name='form-waiver']").validate({
rules: {
WaiverName: {
required: true,
minlength: 2
},
signature_pad: {
checkSignature: true
}
},
messages: {
WaiverName: "The name has to be filled out"
},
successClass: "valid",
errorClass: "invalid",
submitHandler: function (form) {
...
}
};
However, the form validates even if the canvas is empty. Is there a method to include the canvas in the form validation?

Related

Submit form data without javascript

TL;DR
How to make a form to make a normal post instead of making a submission via JQuery?
I bought a theme recently and I'm making a form with several steps. I'm using the "Wizard" component of this theme and you can see how it works through this link:
https://keenthemes.com/metronic/preview/demo1/custom/pages/wizard/wizard-2.html
My problem is with the submission of this form. I would like to make a common submission. As it stands, the form must be submitted using JQuery.
I made some changes to my form to be able to make a common submission. For example:
I informed the POST method and an action for the form:
<form class="m-form m-form--label-align-right- m-form--state-" id="m_form" action="sale/new" method="post" enctype="multipart/form-data">
And I also created a "Submit" button:
<button type="submit" class="btn btn-primary" data-wizard-action="submit">Save</button>
For the Wizard work, the form must have an id (m_form) and the submit button must also have the attribute data-wizard-action="submit".
I am using the javascript of the theme itself, and it is precisely because I don't know much about JS that I believe I am facing problems. I tried to remove the e.preventDefault, but the form still does not POST to the action I determined. The javascript code for the theme I'm using is this:
//== Class definition
var WizardDemo = function () {
//== Base elements
var wizardEl = $('#m_wizard');
var formEl = $('#m_form');
var validator;
var wizard;
//== Private functions
var initWizard = function () {
//== Initialize form wizard
wizard = new mWizard('m_wizard', {
startStep: 1
});
//== Validation before going to next page
wizard.on('beforeNext', function(wizardObj) {
if (validator.form() !== true) {
wizardObj.stop(); // don't go to the next step
}
})
//== Change event
wizard.on('change', function(wizard) {
mUtil.scrollTop();
});
//== Change event
wizard.on('change', function(wizard) {
if (wizard.getStep() === 1) {
// alert(1);
}
});
}
var initValidation = function() {
validator = formEl.validate({
//== Validate only visible fields
ignore: ":hidden",
//== Validation rules
rules: {
//=== Client Information(step 1)
//== Client details
name: {
required: true
},
email: {
required: true,
email: true
},
phone: {
required: true,
phoneUS: true
},
//== Mailing address
address1: {
required: true
},
city: {
required: true
},
state: {
required: true
},
city: {
required: true
},
country: {
required: true
},
//=== Client Information(step 2)
//== Account Details
account_url: {
required: true,
url: true
},
account_username: {
required: true,
minlength: 4
},
account_password: {
required: true,
minlength: 6
},
//== Client Settings
account_group: {
required: true
},
'account_communication[]': {
required: true
},
//=== Client Information(step 3)
//== Billing Information
billing_card_name: {
required: true
},
billing_card_number: {
required: true,
creditcard: true
},
billing_card_exp_month: {
required: true
},
billing_card_exp_year: {
required: true
},
billing_card_cvv: {
required: true,
minlength: 2,
maxlength: 3
},
//== Billing Address
billing_address_1: {
required: true
},
billing_address_2: {
},
billing_city: {
required: true
},
billing_state: {
required: true
},
billing_zip: {
required: true,
number: true
},
billing_delivery: {
required: true
},
//=== Confirmation(step 4)
accept: {
required: true
}
},
//== Validation messages
messages: {
'account_communication[]': {
required: 'You must select at least one communication option'
},
accept: {
required: "You must accept the Terms and Conditions agreement!"
}
},
//== Display error
invalidHandler: function(event, validator) {
mUtil.scrollTop();
swal({
"title": "",
"text": "There are some errors in your submission. Please correct them.",
"type": "error",
"confirmButtonClass": "btn btn-secondary m-btn m-btn--wide"
});
},
//== Submit valid form
submitHandler: function (form) {
}
});
}
var initSubmit = function() {
var btn = formEl.find('[data-wizard-action="submit"]');
btn.on('click', function(e) {
e.preventDefault();
if (validator.form()) {
//== See: src\js\framework\base\app.js
mApp.progress(btn);
//mApp.block(formEl);
//== See: http://malsup.com/jquery/form/#ajaxSubmit
formEl.ajaxSubmit({
success: function() {
mApp.unprogress(btn);
//mApp.unblock(formEl);
swal({
"title": "",
"text": "The application has been successfully submitted!",
"type": "success",
"confirmButtonClass": "btn btn-secondary m-btn m-btn--wide"
});
}
});
}
});
}
return {
// public functions
init: function() {
wizardEl = $('#m_wizard');
formEl = $('#m_form');
initWizard();
initValidation();
initSubmit();
}
};
}();
jQuery(document).ready(function() {
WizardDemo.init();
});
I would like to know if there is any way to keep the Wizard and the validation working, but in a way that it is possible to make a common submission for the action that I defined for the form.
You just need a slight change in your initSubmit() function.
var initSubmit = function() {
var btn = formEl.find('[data-wizard-action="submit"]');
btn.on('click', function(e) {
e.preventDefault();
if (validator.form()) {
//== See: src\js\framework\base\app.js
mApp.progress(btn);
//mApp.block(formEl);
//== See: http://malsup.com/jquery/form/#ajaxSubmit
/*
formEl.ajaxSubmit({
success: function() {
mApp.unprogress(btn);
//mApp.unblock(formEl);
swal({
"title": "",
"text": "The application has been successfully submitted!",
"type": "success",
"confirmButtonClass": "btn btn-secondary m-btn m-btn--wide"
});
}
});
*/
// Use this one instead:
formEl.submit();
}
});
}
This simply means that:
Instead of doing an AJAX request if validation result is positive, just do a normal submission.
Here's the reference for the submit() method of jQuery:
https://api.jquery.com/submit/
By the way, this question can be found under the title (how to submit form using jQuery ?), see this question for example:
Submit a form using jQuery

jquery number validation not working consistently

I am using jquery validations in a form. I haven't had many issues, however I did run into a problem in a users form where the jquery number validation isn't firing. I tested it in IE, firefox and chrome and it is not working in any of them. The weird part is that so far it seems that it is specific to this one user's form as when I go to other user forms the alerts fire fine as it does in my testing across all browsers. I was wondering if any one else has come across this problem before when using jquery validation. Below is an example of some of the jquery validation code I am using.
var validator = $("#educationForm").validate({
debug: true,
errorElement: "span",
errorClass: "help-block errortext",
errorPlacement: function (error, element) {
element.before(error);
},
success: function (label) {
label.remove();
},
rules: {
school1GPA: {
number: true
},
school2GPA: {
number: true
},
school1Units: {
number: true
},
school2Units: {
number: true
},
},
onsubmit: false
});
$('.form-actions').on('click', '#btnSubmit', function (evt) {
evt.preventDefault();
if ($("#educationForm").valid()) {
$.ajax({
type: "POST",............
} else {
validator.focusInvalid();
}
});
The issue is that you are triggering evt.preventDefault() before you could even trigger jquery validation. That is basically killing any validation statement following evt.preventDefault(). All you need to is just call $("#educationForm").valid() or jquery.validate() and then call evt.preventDefault().
$('.form-actions').on('click', '#btnSubmit', function (evt) {
if ($("#educationForm").valid()) {
evt.preventDefault(); // prevents the form submission to allow ajax
$.ajax({
type: "POST",............
} else {
validator.focusInvalid();
}
});
You should not need your click handler at all. As per documentation, your ajax belongs inside of the submitHandler callback function.
You also should not set onsubmit to false unless you want validation blocked when the submit button is clicked.
debug set to true will block submission of the form.
Something more like this...
var validator = $("#educationForm").validate({
// debug: true, // <- this is blocking the submit entirely
submitHandler: function(form) {
// your ajax here
$.ajax(...);
return false;
},
errorElement: "span",
errorClass: "help-block errortext",
errorPlacement: function (error, element) {
element.before(error);
},
success: function (label) {
label.remove();
},
rules: {
school1GPA: {
number: true
},
school2GPA: {
number: true
},
school1Units: {
number: true
},
school2Units: {
number: true
},
},
// onsubmit: false // <- this is preventing validation on the submit.
});
DEMO: http://jsfiddle.net/2vv8vL79/

Multiple instances of jQuery Validation Plugin on a JSP page

SOLVED: $.extend() twice in a row simply overwrites the previous object because objects are passed by reference. My fix was to do this:
var updateUserObj = $.extend({}, validationPluginDefaults);
var newUserObj = $.extend({}, validationPluginDefaults);
Then the validators are executed like this:
var whateverValidator = $.extend(updateUserObj,{new rules})
Update: Further research shows that what I'm trying to do appears to be correct but the problem may be in the object I am extending - "validationPluginDefaults"). Here it is below:
var validationPluginDefaults = {
ignore: [],
errorElement: 'p', //default input error message container <p>
errorClass: 'text-error', // default input error message class
focusInvalid: true, //focus on the first invalid field
messages: {},
invalidHandler: function (event, validator) { //display error alert on form submit
},
highlight: function (el) { // hightlight error inputs
//jQuery(el).closest('.control-group').addClass('error'); // set error class to the control group
},
success: function (err, el) {
jQuery(el).next(".text-error").hide();
jQuery(el).next(".text-error").remove();
},
errorPlacement: function (error, element) {
error.insertAfter(element);
},
onfocusin: function () {},
onfocusout: function () {}
};
From my testing it appears that even though I have two separate forms on a JSP page and each has different validation that I can still only use one jQuery Validate Plugin instance per page; is this correct?
Here's my code:
// Define validation rules for form one
var formOneValidator = $.extend(validationPluginDefaults,{
rules: {
firstName: {
minlength: 2,
onlyAlphaAndHyphen: true,
required: true,
},
lastName: {
minlength: 2,
required: true,
},
email: {
required: true,
email: true
}
}
});
var formTwoValidator = $.extend(validationPluginDefaults,{
rules: {
newFirstName: {
minlength: 2,
onlyAlphaAndHyphen: true,
required: true,
},
newLastName: {
minlength: 2,
required: true,
},
newEmail: {
required: true,
email: true,
}
}
});
$("#formOne").validate(formOneValidator);
$("#formTwo").validate(formTwoValidator);
What happens here is that formOne validator takes on all the rules of formTwoValidator after this code executes.
Is the solution to have only one validator and swap out rules depending on which form I'm in? It just seems strange that I wouldn't be able to define separate validators for each form on the page. Am I fundamentally misunderstanding something here?
you could use knockout and give each page a different view model which handles the different validation. That is how i would do it but i'm sure there will be a better answer.

Automatically close qtip2 using JQuery .validate()

I'm working on a form which implements QTip2 to display a tooltip once someone tries to submit a form where data is missing. Everything works as intended, however I would like the tooltip to be removed once the error class is removed (effectively once someone types in the input field). I have the following code for my validation currently:
$('#form0').validate({
rules: {
Name: "required",
Email: {
required: true,
email: true
},
Subject: "required",
Message: "required"
},
errorPlacement: function (error, element) {
$('#Name').qtip({
content: 'Please enter your name',
position: {
target: 'mouse', // Track the mouse as the positioning target
adjust: { x: 5, y: 5 } // Offset it slightly from under the mouse
},
style: { classes: 'qtip-red' }
});
return true;
},
errorClass: "form-error"
});
As you can see, once someone tries to submit the form the class "form-error" is assigned to the input field, so I would like the tooltip to be removed as well once this class is removed. I tried the following, but it did not work, not sure why:
onHide: function() { $(this).qtip('destroy'); }
I found a solution to this problem by adding the following code inside errorPlacement {}:
events: { show: function (event, api) { if (!element.hasClass('form-error')) event.preventDefault(); } },
show: {
delay: 0,
target: element
},
hide: { target: element },

How to validate kendo DateTimePickerFor using mvc 4 razor?

i wants to validate kendo DateTimePickerFor on client side.My control on view as
#(Html.Kendo().DateTimePickerFor(m => m.StartDate)
.HtmlAttributes(new { style = "width:200px", #class = datePicker",required = "true" })
.Name("StartDate")
.Depth(CalendarView.Year)
.Value(DateTime.Now.ToString())
.Min(DateTime.Now.ToString())
.Max(DateTime.Now.AddMonths(4))
.Format("MM/dd/yyyy hh:mm tt")
)
i have masked it in ready function.but it allows me to type any input.
$(document).ready(function () {
$('.datePicker').mask('99/99/9999');
$('#_appointmentCreateForm input[type="text"], textarea').tooltipster({
trigger: 'custom',
onlyOne: false,
position: 'right',
appendTo: "#_appointmentCreateForm"
});
$('#_appointmentCreateForm').validate({
ignore: [],
rules: {
StartDate: {
required: true
}
},
messages: {
StartDate: {
required: "Please choose Date and Time."
}
},
errorPlacement: ValidatorErrorPlacement,
success: ValidatorSuccess
}
);
});
And when there is no value in datetimepicker i.e datetimepicker is empty then validation gets fail but not showing any message.
So, any ideas how I can validate the Kendo DateTimePicker to accept valid input format? Thanks in advance.
You can define
Html.Kendo().DateTimePickerFor(model => model.date_debut)
.ParseFormats(new string[] { "dd/MM/yyyy HH:mm" })
on the control. But this will be a server side validate as Html.Kendo() will generate the control from the model.
To validate it in client side, the best way is to test when the submit is fired.
$.submit(function(e) {
//test if form is ok
});
My problem has been solved!when i changed my ready function to
$(document).ready(function () {
$('.datePicker').mask('99/99/9999');
$('#_appointmentCreateForm input[type="text"], textarea').tooltipster({
trigger: 'custom',
onlyOne: false,
position: 'right',
appendTo: "#_appointmentCreateForm"
});
$('#_appointmentCreateForm').validate({
ignore: [],
rules: {
Speciality: {
selectspeciality: true
}
},
messages: {
Speciality: {
selectspeciality: "Please select Speciality."
}
},
errorPlacement: ValidatorErrorPlacement,
success: ValidatorSuccess
}
);
$.validator.addMethod("selectspeciality", function (value, element) {
var isValid = $(element).data("kendoDropDownList").selectedIndex == 0 ? false : true;
return this.optional(element) || isValid;
}, "Please select Speciality.");
});
Ho[e it will help someone like me.

Categories

Resources