Validation issue in select2 multiple select - javascript

I'm trying to validated select2 and other input fields they are validating as shown in code snippet, but i do not want to show text on validation error instead i want to show red border around select2 and textbox, i have used that too in error placement and highlight section but it is not showing any red border around fields.
$("#singleselect").select2({ placeholder: "Please select",width: '100%'});
$.validator.messages.required = '';
$("form#msform").validate({
ignore:'input[type=hidden]',
rules:
{
"singleselect[]": { required: true },
name: { required: true }
},
errorPlacement: function (error, element) {
var elem = $(element);
if (elem.hasClass("select2-hidden-accessible")) {
element = $("#select2-" + elem.attr("id") + "-container").parent();
error.insertAfter(element);
}
else {
error.insertAfter(element);
}
},
highlight: function (element, errorClass, validClass) {
var elem = $(element);
if (elem.hasClass("select2-hidden-accessible")) {
$("#select2-" + elem.attr("id") + "-container").parent().addClass(errorClass);
}
else if(elem.is(':checkbox'))
{
elem.addClass("parent-error");
}
else {
elem.addClass(errorClass);
}
},
unhighlight: function (element, errorClass, validClass) {
var elem = $(element);
if (elem.hasClass("select2-hidden-accessible")) {
$("#select2-" + elem.attr("id") + "-container").parent().removeClass(errorClass);
}
else if(elem.is(':checkbox'))
{
elem.removeClass("parent-error");
}
else {
elem.removeClass(errorClass);
}
},
success: function (label, element) {
//jQuery(element).parent().removeClass('has-error');
},
submitHandler: function(form) {
form.submit();
}
});
span.error{
outline: 1px solid red;
border: 1px solid red;
}
.parent-error {
outline:1px solid red;
background:red;
}
#msform label.error {
display: none !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.13.1/jquery.validate.min.js"></script>
<form action="#" id="msform" method="post" accept-charset="utf-8" novalidate="novalidate">
<select class="sl" id="singleselect" name="singleselect[]" multiple>
<option value="val1">Val-1</option>
<option value="val2">Val-2</option>
</select>
<input type="text" name="name" value="" id="name" maxlength="80" size="30" class="form-control error" autocomplete="off" placeholder="Name" aria-invalid="true">
<input type="submit" name="register" value="Register" class="btn btn-primary">
</form>

Your problem has to do with your targeting logic.
if (elem.hasClass("select2-hidden-accessible"))
You do not have anything in the DOM with that class. The hidden select element only has a class of sl.
Then you are trying to target an element with an ID of select2-" + elem.attr("id") + "-container", however, no such thing exists. I set up a jsFiddle, inspected the DOM, and the ID of the container is s2id_singleselect.
https://jsfiddle.net/8ganq0mt/1/
I also removed a lot of unnecessary code. There is no need to blank out the actual message or hide with CSS. If you don't want error messages, then don't use the errorPlacement callback to place the messages; just return false and messages are gone.
errorPlacement: function() {
return false;
},

Related

How to change the input field background color right after I type something?

I wrote the code below and I'm trying to change the input field background color the moment I type something. I have 4 input fields. If I click submit in the first time and any field is empty, the color of this field will change to red, but I need to change the color to green the moment I fill this empty field.
const submitButton = document.getElementById("submit")
const inputField = document.querySelectorAll(".input")
let requiredField = document.querySelectorAll(".requiredField")
inputField.forEach(function (item){
submitButton.addEventListener("click", function (){
if(item.value == '') {
item.classList.add("red");
item.nextElementSibling.classList.add("red");
}
else{
item.classList.add("green")
item.nextElementSibling.classList.remove("green");
}
})
})
Try this:
inputField.forEach(field => {
field.addEventListener("input", () => {
field.classList.add("green");
});
});
If you want only one field to be green at a time:
inputField.forEach(field => {
field.addEventListener("input", () => {
inputField.forEach(input => {
input.classList.remove("green");
});
field.classList.add("green");
});
});
I'm not sure all your code does what you are expecting, but I have an approach that is approaching your requirement by listening to the keyup event and evaluating if the input has content or not; you should be able to reconfigure this to your use case.
I also moved your loop of the four loops inside the submit button click handler-- otherwise you are adding three identical handlers to the button.
const submitButton = document.getElementById("submit")
const inputField = document.querySelectorAll(".input")
submitButton.addEventListener("click", function(e) {
inputField.forEach(function(item) {
e.preventDefault();
if (item.value == '') {
item.classList.add("red");
item.nextElementSibling.classList.add("red");
} else {
item.classList.add("green")
item.nextElementSibling.classList.remove("green");
}
})
})
inputField.forEach(function (item) {
item.addEventListener('keyup', function(e) {
const theInput = e.target;
if (theInput.value) {
theInput.classList.remove('red');
theInput.classList.add('green');
}
});
});
.red {
border: red 2px solid;
}
.green {
border: green 2px solid;
}
<label for="myfield">My Field:</label>
<input class="input" id="myfield" name="myfield" />
<br/>
<label for="myotherfield">My Other Field:</label>
<input class="input" id="myotherfield" name="myotherfield" />
<button id="submit">Submit</button>
Note another option would be to omit the JavaScript altogether and just go for native validation-- you have less control about when and how the validation styles are applied, but also less JS to write:
const submitButton = document.getElementById("submit")
submitButton.addEventListener("click", function(e) {
e.preventDefault();
});
.input:invalid {
border: red 2px solid;
}
.input:valid {
border: green 2px solid;
}
<label for="myfield">My Field:</label>
<input class="input" id="myfield" name="myfield" required/>
<br/>
<label for="myotherfield">My Other Field:</label>
<input class="input" id="myotherfield" name="myotherfield" required />
<button id="submit">Submit</button>
If you go with the first approach, make sure you are providing adequate feedback for screen readers and assistive technologies to understand the form's state-- if there are no validation or validation-state attributes on the input and you are only indicating validity with a green/red border, screen readers won't be aware of it. Furthermore, those with red/green color blindness might not be able to perceive the difference.
You don't actually need any JavaScript for this. Add the required attribute on the inputs and then style them accordingly with css.
<input type="text" required>
<input type="text" required>
<input type="text" required>
<input type="text" required>
input:valid {
background-color: green;
}
input:invalid:required {
background-color: red;
}
try this for a quick fix:
const submitButton = document.getElementById("submit")
const inputField = document.querySelectorAll(".input")
inputField.forEach(field => {
field.addEventListener("input", () => {
inputField.forEach(input => {
input.classList.remove("green");
input.classList.remove("red");
});
if (field.value !== "") {
field.classList.add("green");
} else {
field.classList.add("red");
}
});
});

jQuery validate URL without http:// [duplicate]

This question already has answers here:
How to make url validation without http ( or add it after validation passed )?
(3 answers)
Closed 4 years ago.
I'm trying to validate a url without http:// using jQuery validate but it's not working. I am following the mtosic's answer from here
<form id="form" method="post" action="#">
<input type="text" name="url" id="url" />
<button type="submit">Submit</button>
</form>
$.validator.addMethod('validUrl', function(value, element) {
var url = $.validator.methods.url.bind(this);
return url(value, element) || url('http://' + value, element);
}, 'Please enter a valid URL');
$("#form").validate({
rules: {
"url": {
url: "validUrl"
}
},
submitHandler: function (form) {
alert('valid form submitted');
return false;
}
});
When I type in an address like "www.google.com" I still get the invalid error.
Here's the fiddle
What is the issue? Thank you for the help
The problem is because you've defined the rule named validUrl, yet you're still setting the url rule on the element in the $.validate settings. Also note that you want to pass a boolean value to the property, not a string. Try this:
$(document).ready(function() {
$.validator.addMethod('validUrl', function(value, element) {
var url = $.validator.methods.url.bind(this);
return url(value, element) || url('http://' + value, element);
}, 'Please enter a valid URL');
$("#form").validate({
rules: {
"url": {
validUrl: true // <-- change this
}
},
submitHandler: function(form) {
alert('valid form submitted'); // for demo
return false; // for demo
}
});
});
body {
padding: 20px;
}
label {
display: block;
}
input.error {
border: 1px solid red;
}
label.error {
font-weight: normal;
color: red;
}
button {
display: block;
margin-top: 20px;
}
<script type="text/javascript" src="//code.jquery.com/jquery-2.0.2.js"></script>
<script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.0/jquery.validate.min.js"></script>
<link rel="stylesheet" type="text/css" href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.0/additional-methods.js"></script>
<form id="form" method="post" action="#">
<input type="text" name="url" id="url" />
<button type="submit">Submit</button>
</form>

How to use Jquery validation on the radio button with respected fields?

My issue is regarding jquery validation. I have a form and validation is working on input field but I am confused how to use the validation on the radio button because I have three radio buttons and the user can choose only one. All the radio button have their respected fields. I have to set the validation on it.
Example: I choose the first radio then the user should enter the book1 and book2 fields as well. If you choose the second radio then the user should enter the fruit1 and fruit2 fields value.
if user choose only radio button and without filling the fields details and clicked on submit then validation should display.
I tried some code. It's working for first radio button but what if any user chooses a second radio button?
This is the output I am getting.
Radio button Book is checked with Jquery validation if fields are empty
Notice here I choose fruit and clicked on submit button but validation is not displaying
The reason was I am not getting because I added only book radio button validation. Now how to use for fruit and subject?
book1: {required: true},
book2: {required: true}
$(document).ready(function() {
$("input[name='books_fruit_sub']").click(function() {
var test = $(this).val();
$(".show_fields").hide();
$("#show" + test).show();
});
$('#form').validate({ // initialize the plugin
rules: {
mobile: {
required: true,
number: true,
minlength: 10,
maxlength: 10
},
book1: {
required: true
},
book2: {
required: true
}
},
submitHandler: function(form) { // for demo
form.submit();
}
});
});
ul {
text-decoration: none;
margin: 0;
padding: 0;
}
ul li {
display: inline-block;
}
.error {
color: red;
}
<form action="" id="form">
<input type="text" name="mobile" placeholder="Mobile">
<ul>
<li>
<input type="radio" name="books_fruit_sub" id="books" value="books" checked>
<label for="books">Books</label>
</li>
<li>
<input type="radio" name="books_fruit_sub" id="fruit" value="fruit">
<label for="fruit">Fruit </label>
</li>
<li>
<input type="radio" name="books_fruit_sub" id="subject" value="subject">
<label for="subject">Subject </label>
</li>
</ul>
<div>
<div class="show_fields" id="showbooks">
<input type="text" name="book1" placeholder="Book 1">
<input type="text" name="book2" placeholder="Book 2">
</div>
<div class="show_fields" id="showfruit" style="display: none;">
<input type="text" name="fruit1" placeholder="Fruit 1">
<input type="text" name="fruit2" placeholder="Fruit 2">
</div>
<div class="show_fields" id="showsubject" style="display: none;">
<input type="text" name="subject1" placeholder="Subject 1">
<input type="text" name="subject2" placeholder="Subject 2">
</div>
</div>
<input type="submit" name="send" value="Submit">
</form>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.0/jquery.validate.min.js"></script>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.0/additional-methods.js"></script>
Just use a function that return true or false depending on if the related radio buttton is selected or not.
book1: {
required: function() {
return $('#books').is(':checked');
}
},
book2: {
required: function() {
return $('#books').is(':checked');
}
},
fruit1: {
required: function() {
return $('#fruit').is(':checked');
}
},
fruit2: {
required: function() {
return $('#fruit').is(':checked');
}
},
..
To be consequent use the plural form "fruits" and "subjects" as you did for "books" for your radio-buttons.
Here is your modified and working code in plunker.
You don't need jQuery for that. Using ES20xx, data-attributes and css it's fairly easy to create your own form validation. Let's, just for fun, work out an example based on your code.
We need a function to determine the chosen value of a radio button, that's checkRadio in the snippet;
We need a function to show or hide fields belonging to a radio button choice, that's switchFieldsBasedOnRadioChoice in the snippet. That function is activated by clickHandling. We use the chosen value from checkRadio to identify div#show[chosen value]] to be able to show the right div containing the input elements belonging to the chosen value;
We need an Object containing some methods to check fields denoted in html by data-check and activated by the value of [data-check], it's called fieldChecks;
We need a handler function for the (submit) button which will check all fields denoted by [data-check] for field value validity and warn if the field value is not valid, that's checkValues, activated by clickHandling;
We also create a focusin-handler that removes warnings from a previous input values check if the user clicks on or focuses one of the form fields;
We use data-attributes and css to style and display the warning values. Every text-input is wrapped in a div. We use the css class .invalid for (input fields container)-div that to style the warnings on the containing input fields (if applicable).
Notes
the handlers (click, focusin) in this snippet use event delegation.
client side validation is never sufficient. You should always check the fields values server side too before handling them at the server.
see also
// check value of a radio button
const checkRadio = name => {
const isChecked =
Array.from(document.querySelectorAll(`[name='${name}']`))
.filter(rb => rb.checked);
return isChecked.length ? isChecked[0].value : null;
};
// validity checks for field values ([data-check])
const fieldChecks = {
mobile: value => {
const valueClean = value.replace(/[^\d]/g, "");
return {
cando: valueClean.length === 10,
instruction: "Invalid: need 10 digits, you can use spaces and '-'"
};
},
booksOrFruits: value => ({
cando: value.trim().length >= 5,
instruction: "Invalid: all fields ≥ 5 characters"
}),
};
// add event listeners
document.addEventListener("click", clickHandling);
document.addEventListener("focusin", removeWarnings);
// click handling delegate
function clickHandling(evt) {
const origin = evt.target;
if (origin.type === "radio") {
return switchFieldsBasedOnRadioChoice(origin);
} else if (origin.id === "validate") {
return checkValues();
}
}
// focusin handling delegate: remove warnings on focus
function removeWarnings() {
console.clear();
Array.from(document.querySelectorAll(".notvalid"))
.forEach( el => el.classList.remove("notvalid") );
}
// check all field values and warn for invalid values in required fields
function checkValues() {
console.clear();
const checks = Array.from(document.querySelectorAll("[data-check]"));
let cando = true;
checks.forEach( input => {
// check for existence of input.dataset.check
if (!fieldChecks[input.dataset.check]) {
throw new Error(
`You forgot to add '${input.dataset.check}' to fieldChecks!`
);
}
const parent = input.parentNode;
// don't check input values from parent class "show_fields hidden"
if (parent.classList.contains("show_fields")
&& parent.classList.contains("hidden")) {
return false;
}
// perform the check denoted by [data-check] from the input field
const fieldChck = fieldChecks[input.dataset.check](input.value);
// if invalid value, use css/data-attributes to style a warning
if (!fieldChck.cando) {
parent.classList.add("notvalid");
if (fieldChck && fieldChck.instruction) {
parent.dataset.instruction = fieldChck.instruction;
}
cando = false;
} else {
parent.classList.add("valid")
}
} );
// all fields checked out ok
if (cando) { console.log("you're ok"); }
}
// show input fields belonging to a chosen radio input field
function switchFieldsBasedOnRadioChoice(origin) {
Array.from(document.querySelectorAll(".show_fields"))
.forEach(v => v.classList.add("hidden"))
const chosenValue = checkRadio(origin.name);
document.querySelector(`#show${chosenValue}`)
.classList.remove("hidden");
}
body {
margin: 2em;
font: normal 12px/15px verdana, arial, sans-serif;
}
input[type=text] {
margin: 0.3em 0.3em 0 0;
padding: 2px 4px;
}
button {
margin-top: 0.3em;
}
/* fields originating from radio choice */
.show_fields {
display: table-row;
visibility: "visible";
opacity: 1;
transition: opacity ease-in 0.5s 0s;
}
.hidden {
opacity: 0;
transition: opacity ease-out 0.1s 0s;
visibility: collapse;
}
/* styling related to validation */
.notvalid input {
border: 1px solid red;
}
.notvalid[data-instruction]:after {
content: attr(data-instruction);
margin-left: 0.2em;
}
.notvalid ::placeholder {
color: red;
}
.valid:after {
font-weight: bold;
content: "\2714";
color: green;
}
.valid input {
color: green;
}
<ul>
<li>
<input type="radio" name="books_fruit_sub" id="books" value="books" checked>
<label for="books">Books</label>
</li>
<li>
<input type="radio" name="books_fruit_sub" id="fruit" value="fruit">
<label for="fruit">Fruit </label>
</li>
</ul>
<div data-required>
<input type="text" name="mobile" placeholder="mobile" data-check="mobile">
</div>
<div>
<input type="text" name="notrequired" placeholder="not required">
</div>
<div class="show_fields" id="showbooks">
<input type="text" name="book1" placeholder="Book 1" data-check="booksOrFruits">
<input type="text" name="book2" placeholder="Book 2" data-check="booksOrFruits">
</div>
<div class="show_fields hidden" id="showfruit">
<input type="text" name="fruit1" placeholder="Fruit 1" data-check="booksOrFruits">
<input type="text" name="fruit2" placeholder="Fruit 2" data-check="booksOrFruits">
</div>
<button id="validate">Check</button>
Remove the rule for book1 and book2 from validator initialization and in your click handler just add this
$(".show_fields").find("input").removeAttr("required");
$("#show" + test).find("input").attr("required" , "required");
Also in html add required attribute to both inputs book1 and book2

Text field group validation using jquery validator

Currently working with jquery group field validation. I am using the great jquery validation plugin I have searched through SO actually I got some idea for group validation with my current code I can able to validate the three field and when i typed in any of the field the errClass getting disappear but the validation count was not detecting.
I was not able to figure out what was the problem
Here is the jquery code
$(document).ready(function () {
$(".error_msge").hide();
$(".basicForm").validate({
ignore: false,
onkeyup: false,
showErrors: function (errorMap, errorList) {
var errors = this.numberOfInvalids();
if (errors) {
var message = errors == 1 ? 'You missed 1 field. It has been highlighted' : 'You have missed ' + errors + ' fields. Please fill the highlited field before submit.';
$("#error_message").html(message);
$(".error_msge").show();
} else {
$(".error_msge").hide();
}
this.defaultShowErrors();
},
errorPlacement: function () {
return false;
},
highlight: function (element) {
if ($(element).is(':radio')) {
} else {
$(element).addClass('errRed');
}
$(element).prevAll('label').find('span.required-star').addClass('text-error-red').removeClass('text-error-black');
},
unhighlight: function (element) {
if ($(element).is(':radio')) {
} else {
$(element).removeClass('errRed');
}
$(element).prevAll('label').find('span.required-star').addClass('text-error-black').removeClass('text-error-red');
},
rules: {
txt_Po: {
require_from_group: [1, ".txt_Add"]
},
txt_Bdg: {
require_from_group: [1, ".txt_Add"]
},
txt_St: {
require_from_group: [1, ".txt_Add"]
}
}
});
});
Here is my HTML code
<span id="error_message" class="error_msge">
</span>
<form autocomplete="off" class="basicForm" id="basicForm" method="POST">
<!--first field-->
<label>P.O.Box</label>
<br/>
<input type="text" class="ipt_Field txt_Add" id="txt_Po" name="txt_Po" />
<!--second field-->
<label>Building</label>
<br/>
<input type="text" class="ipt_Field txt_Add" id="txt_Bdg" name="txt_Bdg" />
<!--third field-->
<label>Street</label>
<br/>
<input type="text" class="ipt_Field txt_Add" id="txt_St" name="txt_St" />
<button class="btn-next" id="btn-Next" >Next</button>
</form>
Here is the CSS code
.errRed {
color: black !important;
border: 1px solid #EA373D !important;
padding: 6px !important;
}
.error_msge {
border:1px solid red;
width: 450px;
margin: 0px auto;
text-align: center;
background-color: #FFBABA!important;
padding: 5px;
}
Thanks in advance

jQuery Validate: change behaviour of error placement

I have a form with ratable options as radio buttons. What I am trying to achieve is the following:
If an option has not been rated, I want the parent div "option-group" to have a red border. Once the option has been rated, I want the red border to disappear. So far, I have not found a solution.
If the error message is visible and all required fields have been filled out, then I want the error message to disappear immediately.
Here comes the fiddle:
http://jsfiddle.net/a05jrdau/9/
Here comes my code:
HTML
<form id="my-form" action="" method="post">
<div id="msg-error"></div>
<input type="text" id="myInput" name="myInput"/>
<div class="option-con">
<div class="option-label">
Option 1
</div>
<div class="option-row">
<input type="radio" name="radioOption1" value="1"/> 1
<input type="radio" name="radioOption1" value="2"/> 2
<input type="radio" name="radioOption1" value="3"/> 3
</div>
</div>
<div class="option-con">
<div class="option-label">
Option 2
</div>
<div class="option-row">
<input type="radio" name="radioOption2" value="1"/> 1
<input type="radio" name="radioOption2" value="2"/> 2
<input type="radio" name="radioOption2" value="3"/> 3
</div>
</div>
<br>
<br>
<input type="submit" value="Test" />
</form>
CSS:
.option-con {
width: 100%;
float: left;
}
.option-label, .option-row {
float: left;
}
.option-row {
margin-left: 10px;
}
.error {
border: 1px solid red;
}
JS:
jQuery(function ($) {
$('#my-form').validate({
debug: true,
rules: {
myInput: {
required: true
},
radioOption1: {
required: true
},
radioOption2: {
required: true
}
},
invalidHandler: function (event, validator) {
if (validator.errorList.length > 0) {
$('#msg-error').empty().html('Please fill in required fields.').show();
} else {
$('#msg-error').hide();
}
},
errorClass: "error"
}
)});
You simply need to conditionally target the parent when the input element is a radio. Use the highlight and unhighlight callback functions to over-ride the default behavior.
highlight: function (element, errorClass, validClass) {
var target;
if ($(element).is(':radio')) {
target = $(element).parent('div');
} else {
target = $(element);
};
target.addClass(errorClass).removeClass(validClass);
},
unhighlight: function (element, errorClass, validClass) {
var target;
if ($(element).is(':radio')) {
target = $(element).parent('div');
} else {
target = $(element);
};
target.addClass(validClass).removeClass(errorClass);
},
Working DEMO: http://jsfiddle.net/a05jrdau/10/
Also note that, to suppress the error messages, you should put a return false inside of the errorPlacement callback function rather than leaving it empty.
errorPlacement: function (error, element) {
return false;
},
You also do not need errorClass: "error" as "error" is the default setting.
EDIT:
Your error message is not clearing on a valid form because you're trying to do that within the invalidHandler, which only fires when the form is invalid AND you click the button. invalidHandler can never clear the error message because it is never called when the form is valid or by any other triggering event.
You would use the showErrors callback instead...
showErrors: function (errorMap, errorList) {
var msgerror = "All fields are required.";
if (this.numberOfInvalids() > 0) {
$('#msg-error').empty().html(msgerror).show();
} else {
$('#msg-error').hide();
};
this.defaultShowErrors();
},
DEMO 2: http://jsfiddle.net/a05jrdau/14/

Categories