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/
Related
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.
I have an HTML input field where certain characters shouldn't be allowed. The functional part is solved, but I would like to display a tooltip/message next to the input field while it contains illegal characters.
I have a boolean which keeps track of this, but I've been unable to make a satisfactory tooltip/message.
I've tried tweaking uib-tooltip, but It requires the user to hover over the input area. I've tried making a span/div/label that's hidden/displayed based on the boolean, but my CSS skills aren't strong enough.
The app uses Angularjs and Bootstrap 3.
The input field is not part of a form.
where you catch that boolean just say to display the div next to input like
myDiv.visible = true;
Without knowing your exact Javascript, I can't really answer it directly.
I would do something like
function invalid() {
if (invalid = true) {
document.getElementById("alert").style.visibility = 'visible'
}
}
make sure the error message is set to hidden,
then have the checker function run on focus..
<input type="text" onfocus="invalid()">
https://jsfiddle.net/we67geke/1/
This comment by user Lex solved the problem.
You can manually set the visibility of the uib-tooltip using the
tooltip-is-open attribute. Simply use the same boolean you are using
to keep track of the invalid characters.
As you mentioned
The app uses Angularjs and Bootstrap 3.
I suggest that you should use Boostrap tooltip. Use $('#element').tooltip('show') and $('#element').tooltip('hide') with your flag to handle status of Tooltip.
I don't know how your codes work, my idea seems like:
HTML:
<input type=text (keypress)="eventHandler()"> // angular >= 2
<input type=text ng-keypress="eventHandler()"> // angular 1
Angular code:
eventHandler() {
if (isIllegal) {
$('#element').tooltip('show');
} else {
$('#element').tooltip('hide');
}
}
Something like that.
Bootstrap Tooltip: https://getbootstrap.com/docs/3.3/javascript/#tooltips
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!
I have two major problem regarding HTML5 form validation.
1- I use this code to change the validation message of inputs
$$('INPUT').each(function(input)
{
input.oninvalid = function(event)
{
event.target.setCustomValidity('');
if (!event.target.validity.valid) event.target.setCustomValidity('Please Fill');
};
}
There's a big problem with this method. As the form is submitted if the input is invalid, an error message is attached to it. So it wouldn't validate on new input. Even after correction and submitting again it won't let the form get submitted because the message is still attached. so event.target.setCustomValidity('') will remove the message and form needs another submit. two submit after correction.
I couldn't find a way to correct this behavior.
2-How can I hide or disable these tooltips totally but still use form validation. Sometimes I want to use css invalid and valid pseudo classes, but these tips are still displayed.
I find formnovalidate on submit button and then I can check validity.valid of each inputs manually before submitting. any better idea?
In terms of question 1:
I had an input
<input name="VoucherCode" id="VoucherCode" type="text" pattern="(1[0-9]{9})|(2[0-9]{9})" value="">
And improved the default message
$("#VoucherCode").on("invalid", function (event) {
event.target.setCustomValidity('The format of Voucher Code is not correct.')
});
But this had the same problem you encountered: if the user gets the first attempt wrong, a correct response still show the invalid pattern message.
I fixed this based on #Pointy's suggestion:
$("#VoucherCode").on("invalid", function (event) {
event.target.setCustomValidity('The format of Voucher Code is not correct.')
}).bind('blur', function (event) {
event.target.setCustomValidity('');
});
(a bit late) but the solution could be around there!
What happen:
Since you customize the error message event.target.setCustomValidity("...") the property in the element.validity.customError is true ; the reportValidity with always return false and the submit wouldn't be valid
What I did?
When the User change the input (event.on Change) - I set up back the default error message event.target.setCustomValidity(''); this will tells the Browser to keep working without a custom error
In my example below I'm using a dijit.form.DateTextBox:
<input type="text" name="startDate" dojoType="dijit.form.DateTextBox" constraints="{datePattern:'MM/dd/yyyy'}" value='<c:out value="${sessionScope.adminMessageForm.startDate}"/>' />
So for example, if the user starts to enter "asdf" into the date the field turns yellow and a popup error message appears saying The value entered is not valid.. Even if I remove the constraints="{datePattern:'MM/dd/yyyy'}" it still validates.
Without going into details as to why, I would like to be able keep the dojoType and still prevent validation in particular circumstances.
Try overriding the validate method in your markup.
This will work (just tested):
<input type="text" name="startDate" dojoType="dijit.form.DateTextBox"
constraints="{datePattern:'MM/dd/yyyy'}"
value='<c:out value="${sessionScope.adminMessageForm.startDate}"/>'
validate='return true;'
/>
My only suggestion is to programmatically remove the dojoType on the server-side or client-side. It is not possible to keep the dojoType and not have it validate. Unless you create your own type that has you logic in it.
I had a similar problem, where the ValidationTextBox met all my needs but it was necessary to disable the validation routines until after the user had first pressed Submit.
My solution was to clone this into a ValidationConditionalTextBox with a couple new methods:
enableValidator:function() {
this.validatorOn = true;
},
disableValidator: function() {
this.validatorOn = false;
},
Then -- in the validator:function() I added a single check:
if (this.validatorOn)
{ ... }
Fairly straightforward, my default value for validatorOn is false (this appears right at the top of the javascript). When my form submits, simply call enableValidator(). You can view the full JavaScript here:
http://lilawnsprinklers.com/js/dijit/form/ValidationTextBox.js