jQuery input mask - jquery-ui

I want the onBlur event of the input box to trigger the CheckMask() validation function to see whether the data entered by the user is correct or not. The data format is abc 123. If the input isn't in the correct format, I want to display an error message.
Can someone help me modify this code? I'm not getting the correct result.
function CheckMask() {
var value = $('.Mask-tttnnn').val();
if (value.length <= 3) {
char = value.substring(value.length - 1);
if (!(isNaN(char))) {
var newval = value.substring(0, value.length - 1);
$(Mask - tttnnn).val(newval);
}
}
if (value.length > 3) {
char = value.substring(value.length - 1);
if (isNaN(char)) {
var newval = value.substring(0, value.length - 1);
$(Mask - tttnnn).val(newval);
}
}
}
HTML:
<input id="checkval" value="" type="text" class="Mask-tttnnn" onBlur="CheckMask()" />

Step 1: remove the onBlur from your HTML. Keep code and mark-up separate.
Step 2: construct a regular expression you would like to validate. See http://www.regular-expressions.info/javascript.html
[A-Z]{3}[0-9]{3}
Step 3: attach a function to the blur event of your input using jQuery
$('checkval').blur(function () {
// check $(this).val() against the regex
// alert if it fails or whatever you want to do
});

Related

Angular 11 Custom ISBN Validator Reactive Forms

I'm doing a custom validation for an ISBN number, I already have the function that checks the number and works perfect giving me the response by console, but I need to do the custom validator to get the error in the view with the form control and in this step this error is showing in console when I write an ISBN number, It's like it checks the errors but it doesn't know when its right and it should take the null response as a right ISBN number, at least thats what I saw in some examples.
core.js:6210 ERROR TypeError: Cannot read properties of null (reading 'CheckDigit')
at LibrosComponent_Template (libros.component.html:22)
at executeTemplate (core.js:9600)
at refreshView (core.js:9466)
at refreshComponent (core.js:10637)
at refreshChildComponents (core.js:9263)
at refreshView (core.js:9516)
at refreshEmbeddedViews (core.js:10591)
at refreshView (core.js:9490)
at refreshComponent (core.js:10637)
at refreshChildComponents (core.js:9263)
This is my typescript,
export class LibrosComponent implements OnInit {
//ISBN Validator
isbnValue: string = ""
firstFormGroup: FormGroup;
secondFormGroup: FormGroup;
constructor(
private _formBuilder: FormBuilder,
) {}
ngOnInit() {
this.firstFormGroup = this._formBuilder.group({
tituloControl: ['', Validators.required],
isbnControl: ['', Validators.required],
},
{ validator: this.isbnValidate });
}
isbnValidate(g: FormGroup) {
var isbnValue = g.get('isbnControl').value
var subject = isbnValue;
// Checks for ISBN-10 or ISBN-13 format
var regex = /^(?:ISBN(?:-1[03])?:? )?(?=[0-9X]{10}$|(?=(?:[0-9]+[- ]){3})[- 0-9X]{13}$|97[89][0-9]{10}$|(?=(?:[0-9]+[- ]){4})[- 0-9]{17}$)(?:97[89][- ]?)?[0-9]{1,5}[- ]?[0-9]+[- ]?[0-9]+[- ]?[0-9X]$/;
if (regex.test(subject)) {
// Remove non ISBN digits, then split into an array
var chars = subject.replace(/[- ]|^ISBN(?:-1[03])?:?/g, "").split("");
// Remove the final ISBN digit from `chars`, and assign it to `last`
var last = chars.pop();
var sum = 0;
var check, i;
if (chars.length == 9) {
// Compute the ISBN-10 check digit
chars.reverse();
for (i = 0; i < chars.length; i++) {
sum += (i + 2) * parseInt(chars[i], 10);
}
check = 11 - (sum % 11);
if (check == 10) {
check = "X";
} else if (check == 11) {
check = "0";
}
} else {
// Compute the ISBN-13 check digit
for (i = 0; i < chars.length; i++) {
sum += (i % 2 * 2 + 1) * parseInt(chars[i], 10);
}
check = 10 - (sum % 10);
if (check == 10) {
check = "0";
}
}
if (check != last) {
return null;
} else {
return g.get('isbnControl').setErrors( {CheckDigit: true} )
}
} else {
return g.get('isbnControl').setErrors( {Invalid: true} );
}
}
}
In my HTML I have some inputs that are included in the form:
<form class="form" [formGroup]="firstFormGroup">
<div class="container-1">
<mat-form-field class="width">
<mat-label>Título</mat-label>
<input matInput formControlName="tituloControl" required>
</mat-form-field>
<mat-form-field class="width">
<mat-label>ISBN</mat-label>
<input matInput formControlName="isbnControl" required>
<mat-error *ngIf="firstFormGroup.controls['isbnControl'].pristine || firstFormGroup.controls.isbnControl.errors['CheckDigit']">Invalid ISBN check digit</mat-error>
<mat-error *ngIf="firstFormGroup.controls['isbnControl'].pristine || firstFormGroup.controls.isbnControl.errors['Invalid']">Invalid ISBN</mat-error>
</mat-form-field>
</form>
I already found the solution to the error, replacing the .errors [''] with hasError (''), the .errors[] is to read the property of the object that contains the validation error. But first I have to evaluate with the hasError () method if that property exists to access it.

How can i use data outside of the submit function

Trying to use data outside of the submit function to use my own validation
onBlur = {
() = > {
setNameError(nameValidation(data.name));
}
}
You should not handle validation with onBlur function first of all. You can listen to events on form using these approaches so that you capture both form input and button click.
I have not covered styling of form . You can look into more info link to do that one but yeah, just add or remove a class as shown in code below which either shows validation text or not show based on input changes.
// create form with id/class
// There are many ways to pick a DOM node; here we get the form itself and the email
// input box, as well as the span element into which we will place the error message.
const form = document.getElementsByTagName('form')[0];
const email = document.getElementById('mail');
const emailError = document.querySelector('#mail + span.error');
// add an event listener to listen to both form and button click which are defined by id "email" and "submit" as button events.
email.addEventListener('input', function(event) {
// Each time the user types something, we check if the
// form fields are valid.
if (email.validity.valid) {
// In case there is an error message visible, if the field
// is valid, we remove the error message.
emailError.textContent = ''; // Reset the content of the message
emailError.className = 'error'; // Reset the visual state of the message
} else {
// If there is still an error, show the correct error
showError();
}
});
form.addEventListener('submit', function(event) {
// if the email field is valid, we let the form submit
if (!email.validity.valid) {
// If it isn't, we display an appropriate error message
showError();
// Then we prevent the form from being sent by canceling the event
event.preventDefault();
}
});
// finally kick off the error that validates input or button click both and displays error if needed.
function showError() {
if (email.validity.valueMissing) {
// If the field is empty,
// display the following error message.
emailError.textContent = 'You need to enter an e-mail address.';
} else if (email.validity.typeMismatch) {
// If the field doesn't contain an email address,
// display the following error message.
emailError.textContent = 'Entered value needs to be an e-mail address.';
} else if (email.validity.tooShort) {
// If the data is too short,
// display the following error message.
emailError.textContent = `Email should be at least ${ email.minLength } characters; you entered ${ email.value.length }.`;
}
// Set the styling appropriately
emailError.className = 'error active';
}
More info
// On react way
handleOnChange(ev): React.MouseEvent {
this.validateUserInput(ev):
}
const validateUserInput = (ev) => {
if (ev.target.textContent.indexOf(Regular expression logic goes here)) {
this.state.setState({
formValidationText: "Character must be 3 at least"
})
}
}
const renderValidationText = () => { <
h1 > {
this.state.formValidationText
} < /h1>
}
render() {
return <>
<input placeholder="Enter your name" onChange = {
(ev) => this.handleOnChange.bind(this)
}/>
{this.renderValidatorText}
/>
}

my checkbox pass value even unchecked - Grails

I have lots of checkbox element on my Grails form, one is this:
<g:checkBox id="consolidate" name="consolidate" value="${true}" checked="${false}" />
Then on the receiving controller, I verify the value of the checkbox using this code:
println params?.consolidate
And it displays:
on
Regardless whether I've tick my checkbox or not. In other language, if the checkbox is not ticked, its value on the controller will be null or undefined. What should be its value when unchecked, and what is the right code to access its value on the grails controller?
Temporary Solution:
The following code (on JavaScript) is what I had used temporarily to accommodate my requirement. Though what I want is an explanation or maybe correction about this behavior.
var serialized_string = "";
$("#form input").each(function(i, j) {
var o = $(j);
if(o.val() !== undefined && o.val() !== "undefined" && o.val() !== "") {
if(serialized_string === "") {
serialized_string += o.attr("name") + "=";
}
else {
if(o.attr("name") === "consolidate") {
var val = "false";
if(o.prop("checked")) {
val = "true";
}
data += val;
}
else {
data += "&" + o.attr("name") + "=";
}
}
}
});
If checked, you see the on you're seeing; otherwise you see null, which is your false.

Use jQuery to check and see if div element is empty

Below is the code I'm using to place a blur event on a text box in my ASP MVC 3 view. The code works fine if #MailingState is empty, however it cannot tell if #channelName is empty.
For example, if #channelName is empty but #MailingState is not, then when I place a value in #MailingZip the getDrmTerritory Ajax call is fired off every time.
Here is the jQuery
$('#MailingZip').blur(function () {
if ($('#AlignmentM').is(':checked')) {
if ($('#MailingState').val() != "" && $('#channelName').html() != "") {
getDrmTerritory($('#MailingZip').val(), $('#MailingState').val(), $('#channelName').html());
}
}
});
and here is the HTML for the #channelName segment it is checking
<div id="channelName" class="M-display-field">
#*this will be updated via ajax from Market Segment *#
#Html.DisplayFor(model => model.Channel, new { style = "margin-left: 300px;" } )
</div>
The section mentioned in the comments is updated via another jQuery method that looks like this
function ChangeChannel() {
//this function called if Market Segment changes, to update the channel
var pendistcode = document.getElementById('Pendist');
if (pendistcode == null) alert('Error: Cannot find Market Segment control');
//alert('!pendistcode value is ' + pendistcode.value);
$.ajax({
type: 'POST',
url: '/AgentTransmission/GetChannel/',
data: { pendist: pendistcode.value },
success: function (data) {
// alert("success: " + data);
$('#channelName').html(data);
$('#Channel').val(data);
},
error: function (data) {
alert("failure to obtain Channel name");
}
});
CheckTerritory('channel');
} //end ChangeChannel
That jQuery method (ChangeChannel) appends text to the channelName div which, when rendered with a value in it, looks like this
Here is the HTML you get when you inspect the Life Sales from that picture
You can check if #channelName is empty or not like this:
if ( $('#channelName').is(':empty') )
and combine with your code like this:
if ($('#MailingState').val() != "" && !$('#channelName').is(':empty'))
I put in an alert statment to find out channelName's length and it came back with 35, so there must obviously be some white space that gets rendered each time. I had to change the statement to the following to trim out the whitespace and add the variable to the condition.
var channel = $.trim($('#channelName').html());
if ($('#MailingState').val() != "" && channel != "")

Has any one used client_side_validations gem with Chosen.js dropdown?

I am using chosen.js (http://harvesthq.github.com/chosen/). I was wondering if anyone has been able to use chosen select boxes and client_side_validations together.
The issue is that when we use chosen it hides the original select element and renders its own dropdown instead, and when we focus out the validation isn't called and also when the validation message is shown it is shown with the original select element so positioning of the error isnt also correct.
What could be a good way to handle this, My be we can change some code inside ActionView::Base.field_error_proc which currently looks something like
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
unless html_tag =~ /^<label/
%{<div class="field_with_errors">#{html_tag}<label for="#{instance.send(:tag_id)}" class="message">#{instance.error_message.first}</label></div>}.html_safe
else
%{<div class="field_with_errors">#{html_tag}</div>}.html_safe
end
end
Any ideas ?
Edit 1:
I have the following solution that is working for me now.
applied a class "chzn-dropdown" to all my selects that were being displayed by chosen
used the following callback provided by client_side_validations Gem
clientSideValidations.callbacks.element.fail = function(element, message, callback) {
if (element.data('valid') !== false) {
if(element.hasClass('dropdown')){
chzn_element = $('#'+element.attr('id')+'_chzn');
console.log(chzn_element);
chzn_element.append("<label class='message-chzn'>"+message+"</label>");
}
else{
callback();
}
}
}
About the issue with the validation not running at all when the chosen selection changes you can try this:
selectbox.change(function() { setTimeout(function() { selectbox.focusout() }) });
I'm still looking for a solution about the validation message positioning because I'd really love to avoid tampering with the client side validations javascript.
EDIT:
It seems this is a good solution after all, to keep closer to the client side validations api I came up with the following (for whom it may concern):
var settings = {
type: 'ActionView::Helpers::FormBuilder',
input_tag: '<div class="field_with_errors"><span id="input_tag" /><label class="message validationError" /></div>'
};
clientSideValidations.callbacks.element.fail = function (element, message, addError) {
if ($(element).data('chosen') != null) {
var chosen = $('#' + element.attr('id') + '_chzn');
clientSideValidations.formBuilders[settings.type].add(chosen, settings, message);
// Point the label back to the select box
$('label[for="' + chosen.attr('id') + '"]').attr('for', element.attr('id'));
// Mark it as invalid
chosen.data('valid', false);
} else {
addError(element, message);
}
};
clientSideValidations.callbacks.element.pass = function (element, removeError) {
if (element.data('chosen') != null) {
var chosen = $('#' + element.attr('id') + '_chzn');
clientSideValidations.formBuilders[settings.type].remove(chosen, settings);
// Un-mark it from invalid
chosen.data('valid', null);
} else {
removeError(element);
}
};
Note that I use a data attribute (data-chosen) for initialising select-boxes with chosen. Also for a label click to open chosen to work, I explicitly open the list box on label click:
// element is the select box
// Delegate click event from related labels to element (this is already done on "good" browsers)
$('label[for="' + element.attr('id') + '"]').click(function() { element.click() });
// Delegate click event on original element and any related labels to open the list
$(element).click(function() { setTimeout(function() { element.trigger('liszt:open'); }, 0); });
clientSideValidations.callbacks.element.fail = function(element, message, callback){
if(element.data("valid") !== false) {
callback();
if(element.is("select") && $("#" + element.attr("id") + "_chzn").length > 0){
element.parent().prepend($("#" + element.attr("id") + "_chzn"));
}
}
}
Try this:
Tell the gem that you want to validate select tags:
ClientSideValidations.selectors.inputs += ', select';
Force validation when Chosen's dropbox changes:
$('#form_field').chosen().change(function(e) {
var settings = window.ClientSideValidations.forms[this.form.id];
$(this).isValid(settings.validators);
});
Since Chosen hides the field, you will need to enable validation for that field explicitly in the view:
<%= form_for ..., :validate => true do |f| %>
...
<%= f.validate :form_field %>
...
<% end %>

Resources