Conditional Required Fields validation is not working - javascript

I've got a new enigma for you to solve, because I can't manage to get this working.
Imagine yourself working for an online marketing company with a proprietary platform to host and manage campaigns. And then imagine only being able to validate required fields that 'just are there'. And at last; imagine a client that needs form fields to be required after a certain radio button is checked. Right? Right! Well.... no... not right.
Here is the thing. That same radio button triggers a jQuery script that eases in the 5 div's with form fields that are hidden display: block. I have the jQuery.validation.js plugin at the ready.
I insert this piece of code to the form fields that are required if it meets the condition that the depending field is checked:
class="textInput1 validate[condRequired[radiobuttonX]]"
textInput1 is a CSS class that styles an input field.
As a submitbutton I use an image which uses this code to submit: input type="image"
onclick="document.forms['formName'].submit();"
I have got:
$(document).ready(function() {
in place and in my head I have the link to the validation script:
<script src="../path/to/jquery.validationEngine.js"></script>
I use the: Inline Form Validation Engine 2.6.2, jQuery plugin
How do I make form field Y required when radiobuttonX is ticked? I definitely need syntax as well, because I'm a dumbs ;-)

If you can switch fromjQuery Validation Engine to jQuery-Validate, this would be the solution:
$("#form").validate({
rules: {
fieldY: {
required: {
depends: function() {
return $("#radioButtonX").is(":checked");
}
}
}
}
});

Related

Custom validation with bootstrap V5

So right now im basically using the default Bootstrap V5 form validator and I was wondering if there is a way to make a custom parameter that needs to be checked in order for the input to be valid. Right now I want the user to input their licenseplate, which must include letters and numbers. I more or less got the must include part, but bootstrap still says that the input is valid, even if its technically not, because it only checks if there is any input in the field. Would there be a way for me to change what bootstrap views as valid?
The default bootstrap validation function looks like this:
// Example starter JavaScript for disabling form submissions if there are invalid fields
(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)
})
})()
After just spending the better part of the afternoon researching the same topic, there is very little information on custom JS validation with the OOB Bootstrap validation. I've concluded there are two viable options:
Using the pattern attribute on the element
Calling your own JS validation as part of the checkValidity() expression
Pattern Attribute
When creating an input, you can set a pattern attribute on the element.
From the MDN pattern article:
<p>
<label>Enter your phone number in the format (123) - 456 - 7890
(<input name="tel1" type="tel" pattern="[0-9]{3}" placeholder="###" aria-label="3-digit area code" size="2"/>) -
<input name="tel2" type="tel" pattern="[0-9]{3}" placeholder="###" aria-label="3-digit prefix" size="2"/> -
<input name="tel3" type="tel" pattern="[0-9]{4}" placeholder="####" aria-label="4-digit number" size="3"/>
</label>
</p>
Here we have 3 sections for a north American phone number with an implicit label encompassing all three components of the phone number, expecting 3-digits, 3-digits and 4-digits respectively, as defined by the pattern attribute set on each.
JS Validation
When invoking the checkValidity() method, inject custom JS validation to invalidate the form's submission.
const myValidation = someValidation()
if (!myValidation || !form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
When invoking someValidation(), be sure to add/remove the validation classes as-needed:
// valid input
const foo = document.getElementById("foo")
foo.classList.remove("is-invalid")
foo.classList.add("is-valid")
// invalid input
const bar = document.getElementById("bar")
bar.classList.add("is-invalid")
bar.classList.remove("is-valid")
However, I haven't quite figured out how to completely prevent the validation framework from showing the input as valid (checkmark on the right side of the input) even though the classes are set appropriately. I suspect it has something to do with the pattern attribute being empty, which simply means the field cannot be empty, and also needing to invoke the element's reportValidity() method: HTML Spec: reportValidity()
Conclusion
Looks like the pattern attribute and RegEx is the path forward when using this validation framework.
Hopefully someone else can improve this answer with a better path forward using the pure JS method.

Warn on non-ASCII Characters in Django Form

I'm trying to add some client-side Ajax validation of my Django form. I want to warn users, as they are typing in a field, if any of the characters they just inputted are not ascii.
I originally put the basic python to check for ascii characters in my form's clean method. I don't want to do that, though, as I don't want to produce an error but rather just give a warning message and let the user continue with the rest of the form.
try:
field_value.decode('ascii')
except UnicodeEncodeError:
#raise forms.ValidationError("Non-ASCII characters may cause issues in registering your data. Consider removing these characters. You may still submit at your own risk.")
# Just want to show a warning so the user can still submit the form if they wish
I want to show a small warning under the field as the user is typing. I've tried using django-dajax, but am not sure. How can I do this?
EDIT:
To clarify, I want to show the warning before the user submits the form. So, as they are filling out the form...
Use
> <input type="text" pattern="^[\x20-\x7F]+$" id ....>
in html
Use JavaScript to validate that form field.
Example (using jQuery):
<form>
<input name="whatever" id="fieldId">
...
</form>
<script type="text/javascript">
/* Define a function to check the form field value */
function containsAllAscii(str) {
return /^[\000-\177]*$/.test(str); // returns true if all are ASCII characters. false otherwise.
}
/* Now a little jQuery */
$('#fieldId').on('change', function() {
str = $(this).val();
is_valid = containsAllAscii(str);
if (!is_valid) {
window.alert("There are Non-ASCII characters in the input field");
}
});
</script>
The above code will check the given field's value whenever it changes (i.e. loses focus). You can use .on('keyup', ... instead of .on('change', ... which will check the field's value as the user is typing.
Finally, the error message that is shown is just a browser alert. Which is crappy. You can display a beautiful error message, you just need to learn a little more of jQuery. But I hope I've given you a good starting point.
Credits:
The code for containsAllAscii function is taken from this answer by Juan Mendes.
In your django form, create a custom field and take advantage of the media class.
from django import forms
class MyWidget(forms.TextInput):
class Media:
css = {
'all': ('pretty.css',)
}
js = ('animations.js', 'actions.js')
and set the js to the javascript file you will use for validation. something along the lines of the the other answer
https://docs.djangoproject.com/en/1.9/topics/forms/media/

Dynamically remove submitHandler from jQuery Validate to allow normal PayPal 'donate' button action

I have to add a PayPal donate button to the middle of an AngularJS donation form, so nesting the PayPal generated form tags within the donation form tags.
The donation form is processed by an old version (1.12) of jQuery Validate, so no access to the .rules() functions.
I found a way past the validation requirements with this answer (commented out code below), but the problem is the submitHandler takes an argument of 'form' which is always the parent form element (the full donation form).
Ideally, I'd like to disable jQuery validate all together once PayPal is selected.
Here is the function I call when the user chooses 'credit card' vs 'PayPal' and it is correctly going into the else when PayPal is selected.
$scope.payByCreditCard= function(cc_true) {
if(cc_true){
$scope.creditCardDetails = true;
$scope.submit_text = "Submit Donation";
$scope.method_type = "donate";
} else {
$scope.creditCardDetails = false;
$scope.submit_text = "Continue Donation on Paypal";
$scope.method_type = "startDonation";
// var settings = $('#donationForm').validate().settings;
// delete settings.rules;
// $("*").removeClass("required");
}
};
And the jQuery Validate calls with submit handler:
$('#donationForm').validate({
rules: {
otherDonationAmount: {
money: true,
required : true
}
},
errorPlacement : function(error, element) {
if (element.attr('id') == 'donationAmount') {
error.insertAfter(element.parent());
} else {
error.insertAfter(element);
}
},
submitHandler: function(form) {
$('#donation-errors').remove();
window.scrollTo(0, 0);
$("#donationForm").hide();
$("#donationForm").before('<div class="well donation-loading" style="text-align:center;">' +
This may take a few seconds. Do not leave the page or click the back button.' + '</div>');
}
});
What's happening is I disable the validation, but then when I click the PayPal donate button, the submitHandler function is triggered and it tries to process the whole donation form, rather than following what's in the PayPal generated code:
<form action="https://www.paypal.com/xxx/xxx" method="post" target="_top">
<input type="hidden" name="" value="">
<input type="hidden" name="" value="">
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>
So, I'm looking for a way to disable jQuery validate as both a validator and submitHandler if a condition is met (The user selects PayPal).
Quote OP:
"...nesting the paypal generated form tags within the donation form tags."
This is totally invalid HTML and it's a really bad idea. I would abandon any design that places a <form></form> container within a <form></form> container.
Quote OP:
"The donation form is processed by an old version (1.12) of jQuery Validate, so no access to the .rules() functions."
That's just not true. The .rules() methods are available going all the way back through many versions/years including 1.12 which is only one version behind the newest (1.13).
Quote OP:
"... when I click the paypal donate button, the submitHandler function is triggered and it tries to process the whole donation form, rather than following what's in the paypal generated code"
Of course it does. Your HTML is completely invalid so all kinds of unexpected things are going to happen.
Quote OP:
"Ideally, I'd like to disable jQuery validate all together once paypal is selected. ... So, I'm looking for a way to disable jQuery validate as both a validator and submitHandler if a condition is met (The user selects PayPal)."
Once initialized on your form, you cannot toggle or disable the jQuery Validate plugin, the .validate() method, or any of its options including the submitHandler. This is an absolute restriction without any workaround.
The only thing (s) the developer allows you to do "dynamically" are....
add/remove certain rules using the .rules('add') and .rules('remove') methods. (YES, these methods are available in all versions of the plugin going back several years including v1.12)
You can also toggle certain boolean rules by using the depends property.
If you toggle visibility of a field, the ability for validation on that field is also toggled.
Why can't you just have two completely independent and separate forms, each with their own actions, rules, etc. and then use jQuery to dynamically display the one you need? The jQuery Validate plugin will automatically ignore any hidden forms & fields by default.

jQuery validation plugin - how to style 1 validation message differently to others

I have a form that is being validated with the jQuery validation plugin successfully.
Messages are displayed in the correct position and in the correct situations.
So far, so good.
I have 1 field that is being validated correctly, but I need to position that 1 validation message differently to the others. With 2 inputs next to each other, I want the validation to appear under them both (ie under the block that wraps them both) rather than to the right per individual inputs.
The validation on these 2 inputs are dependent on each other, ie at least one must have input. The validation rule works, it's just the positioning I'm struggling with.
I'm using the following validation syntax:
$('#formId').validate({
rules: {
},
messages : {
}
}
In my HTML I have created a label specifically for the (radio) field I am trying to customise:
<label for="radioName" id="radioNameId-invalid" class="error"">Some error message</label>
I tried adding content to the 'showErrors' function of validate, which works, but seemingly then doesn't show any of the other validation messages in my page.
showErrors: function(errors) {
var collectionMethodError = errors['collectionMethod'];
if(collectionMethodError) {
$('#radioNameId-invalid').text(errorString);
$('#radioNameId-invalid').css("display","block");
}
}
I want to enable this error AND then allow validator to continue to do its default behaviour for other fields.
If I remove the showErrors function, the other validation messages are displayed but not my custom one.
How can I get both behaviours?
I ended up using the errorPlacement function instead of the showErrors function:
errorPlacement: function(error, element){
$(error).insertAfter(element);
// special case for display
if($(element).attr("name")=="radioName") {
$(error).insertAfter("#anElement"));
$("label[for=radioName].error").attr("id","invalid-radio-message");
}
}
So in short I'm adding an ID to a label that validation plugin adds, then styling to that ID in my css.
That seems to do what I was trying to do. Now to workout the re-hiding of the message!

How do I get KendoUI Validator to ignore hidden form elements?

I am attempting to use KendoUI Validator with an ASP.NET WebForms project.
I have a simple page, that has a number of inputs, and of course ASP.NET adds some hidden form elements as well.
I have the following questions:
Why does the KendoUI Validator not ignore hidden form fields, and how to I get it to?
Why does KendoUI apply the rules to every input field, and how to do get it to ignore some fields. I want a declarative way to do this, not by adding all sorts of exceptions in my validation rule, as per the example in the KendoUI Validator API page.
Shouldn't it be that if no rule is set as an attribute in the input element (eg; required) then no validation is applied?
Behavior I am getting:
With no validation specific attributes on the input element at all, the validation rules still get applied when I call .validate()
Hidden form elements are validated.
I am using the following kendo:
http://cdn.kendostatic.com/2013.2.716/js/jquery.min.js
http://cdn.kendostatic.com/2013.2.716/js/kendo.all.min.js
http://cdn.kendostatic.com/2013.2.716/styles/kendo.common.min.css
http://cdn.kendostatic.com/2013.2.716/styles/kendo.default.min.css
I have put together a fiddle that demonstrates this:
http://jsfiddle.net/codeowl/B5ML4/3/
And here is the code, for those that don't have access to fiddle:
I have the following markup:
<form action="/" id="testForm">
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="text" id="testInput" value="">
<a id="testValidate" href="javascript:;">Validate</a>
</form>
and the following script:
var validatable = $("#testForm").kendoValidator({
rules: {
testRule1: function (input) {
// Only "Tom" will be a valid value for the FirstName input
return input.is("[name=firstname]") && input.val() === "Tom";
},
testRule2: function (input) {
return $.trim(input.val()) !== "";
}
},
messages: {
testRule1: "Your name must be Test",
testRule2: "Your name must be Foo"
}
}).data("kendoValidator");
$("#testValidate").click(function () {
if (validatable.validate()) {
alert('passed');
}
});
and when I press the validate link it shows validation messages for the hidden fields.
For anyone interested, I did eventually get a response to this question. I had to post it on the KendoUI Premium Forums to get someone to respond.
Here is the response:
How do I get KendoUI Validator to ignore hidden form elements?
Indeed, the hidden input elements are passed through the validation
rules logic by default due to the fact that there are multiple widgets
which has a hidden input as part of there markup. However, as the
built-in rules relays on the presence of certain attributes, if there
are missing no validation will happen on the hidden inputs. Therefore,
your own custom rules should handle this scenario and skip the
appropriate elements. For example:
testRule2: function (input) {
if (!input.is(":hidden")) {
return $.trim(input.val()) !== "";
}
return true;
}
I'm writing this for new comers.
Simply make hidden inputs disabled
$('#hidden_input').prop('disabled', true) // won't check in kendo or standard jquery validation
$('#hidden_input').prop('disabled', false) // will check in kendo or standard jquery validation
validator._inputSelector=
":input:not(:button,[type=submit],[type=reset],[disabled],[readonly],[type=hidden],:hidden)
[data-validate!=false]
This will not validate hidden controls. Kendo 2018 version

Categories

Resources