I've got the following HTML form: http://jsfiddle.net/nfgfP/
<form id="form" onsubmit="return(login())">
<input name="username" placeholder="Username" required />
<input name="pass" type="password" placeholder="Password" required/>
<br/>Remember me: <input type="checkbox" name="remember" value="true" /><br/>
<input type="submit" name="submit" value="Log In"/>
Currently when I hit enter when they're both blank, a popup box appears saying "Please fill out this field". How would I change that default message to "This field cannot be left blank"?
The type password field's error message is simply *****. To recreate this give the username a value and hit submit.
Here is some code to display a custom error message:
<input type="text" id="username" required placeholder="Enter Name"
oninvalid="ths.setCustomValidity('Enter User Name Here')"
oninput="setCustomValidity('')"/>
This part is important because it hides the error message when the user inputs new data:
oninput="setCustomValidity('')"
Note: the this keyword is not required for inline event handlers, but you may want to use it anyway for consistency.
Use setCustomValidity:
document.addEventListener("DOMContentLoaded", function() {
var elements = document.getElementsByTagName("INPUT");
for (var i = 0; i < elements.length; i++) {
elements[i].oninvalid = function(e) {
e.target.setCustomValidity("");
if (!e.target.validity.valid) {
e.target.setCustomValidity("This field cannot be left blank");
}
};
elements[i].oninput = function(e) {
e.target.setCustomValidity("");
};
}
})
I changed to vanilla JavaScript from Mootools as suggested by #itpastorn in the comments, but you should be able to work out the Mootools equivalent if necessary.
If setCustomValidity is set to anything other than the empty string it will cause the field to be considered invalid; therefore you must clear it before testing validity, you can't just set it and forget.
As pointed out in #thomasvdb's comment below, you need to clear the custom validity in some event outside of invalid otherwise there may be an extra pass through the oninvalid handler to clear it.
It's very simple to control custom messages with the help of HTML5 event oninvalid
Here is code:
<input id="UserID" type="text" required="required"
oninvalid="this.setCustomValidity('Witinnovation')"
onvalid="this.setCustomValidity('')">
This is most important:
onvalid="this.setCustomValidity('')"
Note: This no longer works in Chrome, not tested in other browsers. See edits below. This answer is being left here for historical reference.
If you feel that the validation string really should not be set by code, you can set you input element's title attribute to read "This field cannot be left blank". (Works in Chrome 10)
title="This field should not be left blank."
See http://jsfiddle.net/kaleb/nfgfP/8/
And in Firefox, you can add this attribute:
x-moz-errormessage="This field should not be left blank."
Edit
This seems to have changed since I originally wrote this answer. Now adding a title does not change the validity message, it just adds an addendum to the message. The fiddle above still applies.
Edit 2
Chrome now does nothing with the title attribute as of Chrome 51. I am not sure in which version this changed.
It's very simple to control custom messages with the help of the HTML5 oninvalid event
Here is the code:
User ID
<input id="UserID" type="text" required
oninvalid="this.setCustomValidity('User ID is a must')">
By setting and unsetting the setCustomValidity in the right time, the validation message will work flawlessly.
<input name="Username" required
oninvalid="this.setCustomValidity('Username cannot be empty.')"
onchange="this.setCustomValidity('')" type="text" />
I used onchange instead of oninput which is more general and occurs when the value is changed in any condition even through JavaScript.
I have made a small library to ease changing and translating the error messages. You can even change the texts by error type which is currently not available using title in Chrome or x-moz-errormessage in Firefox. Go check it out on GitHub, and give feedback.
It's used like:
<input type="email" required data-errormessage-value-missing="Please input something">
There's a demo available at jsFiddle.
Try this one, its better and tested:
function InvalidMsg(textbox) {
if (textbox.value === '') {
textbox.setCustomValidity('Required email address');
} else if (textbox.validity.typeMismatch){
textbox.setCustomValidity('please enter a valid email address');
} else {
textbox.setCustomValidity('');
}
return true;
}
<form id="myform">
<input id="email"
oninvalid="InvalidMsg(this);"
oninput="InvalidMsg(this);"
name="email"
type="email"
required="required" />
<input type="submit" />
</form>
Demo:
http://jsfiddle.net/patelriki13/Sqq8e/
The easiest and cleanest way I've found is to use a data attribute to store your custom error. Test the node for validity and handle the error by using some custom html.
le javascript
if(node.validity.patternMismatch)
{
message = node.dataset.patternError;
}
and some super HTML5
<input type="text" id="city" name="city" data-pattern-error="Please use only letters for your city." pattern="[A-z ']*" required>
The solution for preventing Google Chrome error messages on input each symbol:
<p>Click the 'Submit' button with empty input field and you will see the custom error message. Then put "-" sign in the same input field.</p>
<form method="post" action="#">
<label for="text_number_1">Here you will see browser's error validation message on input:</label><br>
<input id="test_number_1" type="number" min="0" required="true"
oninput="this.setCustomValidity('')"
oninvalid="this.setCustomValidity('This is my custom message.')"/>
<input type="submit"/>
</form>
<form method="post" action="#">
<p></p>
<label for="text_number_1">Here you will see no error messages on input:</label><br>
<input id="test_number_2" type="number" min="0" required="true"
oninput="(function(e){e.setCustomValidity(''); return !e.validity.valid && e.setCustomValidity(' ')})(this)"
oninvalid="this.setCustomValidity('This is my custom message.')"/>
<input type="submit"/>
</form>
I have a simpler vanilla js only solution:
For checkboxes:
document.getElementById("id").oninvalid = function () {
this.setCustomValidity(this.checked ? '' : 'My message');
};
For inputs:
document.getElementById("id").oninvalid = function () {
this.setCustomValidity(this.value ? '' : 'My message');
};
Okay, oninvalid works well but it shows error even if user entered valid data. So I have used below to tackle it, hope it will work for you as well,
oninvalid="this.setCustomValidity('Your custom message.')" onkeyup="setCustomValidity('')"
If your error message is a single one, then try below.
<input oninvalid="this.setCustomValidity('my error message')"
oninput="this.setCustomValidity('')"> <!-- 👈 don't forget it. -->
To handle multiple errors, try below
<input oninput="this.setCustomValidity('')">
<script>
inputElem.addEventListener("invalid", ()=>{
if (inputElem.validity.patternMismatch) {
return inputElem.setCustomValidity('my error message')
}
return inputElem.setCustomValidity('') // default message
})
</script>
Example
You can test valueMissing and valueMissing.
<form>
<input pattern="[^\\/:\x22*?<>|]+"
placeholder="input file name"
oninput="this.setCustomValidity('')"
required
>
<input type="submit">
</form>
<script>
const form = document.querySelector("form")
const inputElem = document.querySelector(`input`)
inputElem.addEventListener("invalid", ()=>{
if (inputElem.validity.patternMismatch) {
return inputElem.setCustomValidity('Illegal Filename Characters \\/:\x22?<>|')
}
return inputElem.setCustomValidity('') // return default message according inputElem.validity.{badInput, customError, tooLong, valueMissing ...}
})
form.onsubmit = () => {
return false
}
</script>
ValidityState
const username= document.querySelector('#username');
const submit=document.querySelector('#submit');
submit.addEventListener('click',()=>{
if(username.validity.typeMismatch){
username.setCustomValidity('Please enter User Name');
}else{
username.setCustomValidity('');
}
if(pass.validity.typeMismatch){
pass.setCustomValidity('Please enter Password');
}else{
pass.setCustomValidity('');
}
})
Adapting Salar's answer to JSX and React, I noticed that React Select doesn't behave just like an <input/> field regarding validation. Apparently, several workarounds are needed to show only the custom message and to keep it from showing at inconvenient times.
I've raised an issue here, if it helps anything. Here is a CodeSandbox with a working example, and the most important code there is reproduced here:
Hello.js
import React, { Component } from "react";
import SelectValid from "./SelectValid";
export default class Hello extends Component {
render() {
return (
<form>
<SelectValid placeholder="this one is optional" />
<SelectValid placeholder="this one is required" required />
<input
required
defaultValue="foo"
onChange={e => e.target.setCustomValidity("")}
onInvalid={e => e.target.setCustomValidity("foo")}
/>
<button>button</button>
</form>
);
}
}
SelectValid.js
import React, { Component } from "react";
import Select from "react-select";
import "react-select/dist/react-select.css";
export default class SelectValid extends Component {
render() {
this.required = !this.props.required
? false
: this.state && this.state.value ? false : true;
let inputProps = undefined;
let onInputChange = undefined;
if (this.props.required) {
inputProps = {
onInvalid: e => e.target.setCustomValidity(this.required ? "foo" : "")
};
onInputChange = value => {
this.selectComponent.input.input.setCustomValidity(
value
? ""
: this.required
? "foo"
: this.selectComponent.props.value ? "" : "foo"
);
return value;
};
}
return (
<Select
onChange={value => {
this.required = !this.props.required ? false : value ? false : true;
let state = this && this.state ? this.state : { value: null };
state.value = value;
this.setState(state);
if (this.props.onChange) {
this.props.onChange();
}
}}
value={this && this.state ? this.state.value : null}
options={[{ label: "yes", value: 1 }, { label: "no", value: 0 }]}
placeholder={this.props.placeholder}
required={this.required}
clearable
searchable
inputProps={inputProps}
ref={input => (this.selectComponent = input)}
onInputChange={onInputChange}
/>
);
}
}
For a totaly custom check logic:
$(document).ready(function() {
$('#form').on('submit', function(e) {
if ($('#customCheck').val() != 'apple') {
$('#customCheck')[0].setCustomValidity('Custom error here! "apple" is the magic word');
$('#customCheck')[0].reportValidity();
e.preventDefault();
}
});
$('#customCheck').on('input', function() {
$('#customCheck')[0].setCustomValidity('');
});
});
input {
display: block;
margin-top: 15px;
}
input[type="text"] {
min-width: 250px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form">
<input type="text" placeholder="dafault check with 'required' TAG" required/>
<input type="text" placeholder="custom check for word 'apple'" id="customCheck" />
<input type="submit">
</form>
Can be easily handled by just putting 'title' with the field:
<input type="text" id="username" required title="This field can not be empty" />
Related
I am trying to change the default error message "setCustomValidity" throws on email being invalid.
I cannot access the source code. My assumption is that the source somehow invokes setCustomValidity; just because of the look of the error message. This is the source element:
<input type="email" value="" name="customer[email]" id="email" class="large" size="30">
I can only inject any change using external JavaScript/css file.
I could think of two solutions.
Solution 1: I am trying to inject inline HTML element using JS which would result in something like this.
<input type="email" value="" name="customer[email]" class="large" size="30" oninvalid="this.setCustomValidity('Please Enter valid email')" oninput="setCustomValidity('')">
I am new to JS and I am having a hard time figuring how to implement HTML in an external JS file.
Solution 2: Invoke the oninvalid and setCustomValidity DOM methods in error_message.js like so:
function emailValidity(){
var myInput = document.getElementByName("customer[email]");
myInput.oninvalid = function() {
(errorMessage)
};
function errorMessage(){
myInput.setCustomValidity("hey! the email isn't right");
}
}
But this file even after being included somehow fails to override the default message!
Any help is appreciated. Thank you in advance.
Additionally you must call the reportValidity method on the same element or nothing will happen.
HTMLObjectElement.setCustomValidity
function validate(input) {
var validityState_object = input.validity;
console.log(validityState_object)
if (validityState_object.typeMismatch) {
input.setCustomValidity('Thats not an email!');
input.reportValidity();
} else {
input.setCustomValidity('');
input.reportValidity();
}
}
document.querySelector('#email').addEventListener('blur', e =>
validate(e.target)
)
<input type="email" value="" id="email">
Just set the input and invalid event listeners in much the same way.
const input = document.querySelector('input');
input.oninput = () => input.setCustomValidity('');
input.oninvalid = () => input.setCustomValidity('Please Enter valid email');
<form>
<input type="email" value="" name="customer[email]" class="large" size="30">
</form>
Your code wasn't working because it wasn't in a form. A form needs a submit button to check the inputs and display an error message if necessary, so I added that.
Also, you have getElementByName when it should be getElementsByName, with a later on [0] indexing to select the element.
In addition to that, you were trying to set the validity every time the user tried to submit, when it only needed to be set once.
Try this:
var myInput = document.getElementsByName("customer[email]")[0];
myInput.oninvalid = function() {
myInput.setCustomValidity("Hey! the email isn't right")
};
<form>
<input type="email" name="customer[email]" id="email" class="large" size="30">
<input type="submit" onsubmit="emailValidity()">
</form>
This is how I solved it:
customAnswer.js
document.addEventListener("DOMContentLoaded", function(event) {
// Source text: "Fill out this field."
var validateElements1 = document.querySelectorAll('input#username, input#password');
if (validateElements1.length > 0) {
for (var x = 0; x < validateElements1.length; x++) {
validateElements1[x].setAttribute("oninvalid","this.setCustomValidity('Complete este campo.')");
validateElements1[x].setAttribute("oninput","this.setCustomValidity('')");
}
}
});
I have an input with React, but maxlength does not work. Does anyone know how to solve this?
This is handleChangeInput
handleChangeInput(input) {
this.setState({
...this.state,
form: {
...this.state.form,
[input.target.name]: input.target.value
}
})
}
And this is my input:
<div className="input-field col s12 m6 l6">
<input onChange={this.handleChangeInput} value={this.state.form.message} type="text" className="phone validate" name="phone" maxlength="11"/>
<label for="telefone">Telefone</label>
</div>
Property and attribute names are generally camelCase in React, maxLength works.
<input
onChange={this.handleChangeInput}
value={this.state.form.message}
type="text"
className="phone validate"
name="phone"
maxLength="11"
/>
However, you can still override this option if you give the input a value longer than maxLength. The only way around this is to check the length of the value in the callback, and truncate it.
Example
class App extends React.Component {
state = { form: { message: "" } };
handleChangeInput = event => {
const { value, maxLength } = event.target;
const message = value.slice(0, maxLength);
this.setState({
form: {
message
}
});
};
render() {
return (
<input
onChange={this.handleChangeInput}
value={this.state.form.message}
type="text"
className="phone validate"
name="phone"
maxLength="11"
/>
);
}
}
for maxLength to work, type has to be 'text' (most people are probably putting number)
You need to pass maxLength value as a number.
<input
onChange={this.handleChangeInput}
value={this.state.form.message}
type="text"
className="phone validate"
name="phone"
maxLength={11}
/>
inputProps = {{maxLength:6}}
variant="outlined"
Simply do like this in your handleOnChange Function:
handlePasswordChange = (e) => {
if(e.target.value <= 11){
this.setState({
[e.target.name]: e.target.value
});
}
};
For the people who's input type is number, this code will work
handlePhone(object) {
if (object.target.value.length > object.target.maxLength) {
object.target.value = object.target.value.slice(0, object.target.maxLength)
this.setState({ phone: object.target.value });
}
}
<input
placeholder="Phone Number"
onChange={this.handlePhone}
type = "number" maxLength = "10"
/>
<input
id="ZIPCode"
className="form-control"
type="text"
maxLength={10} // this is the important line
></input>
React uses camelCased html attributes, so maxlength would then be maxLength
For anybody using a reactstrap input, like other properties it uses (e.g. colSpan) it needs both camelCase naming and a number passing to it (e.g. maxLength={250}), rather than a string. I have found passing a string will work but React will complain about it.
I'm trying to get rid of the browser's default validation logic using formsy-react, and according to the documentation the "formNoValidation" attribute should do the trick. But I can't get it to work.
What am I doing wrong?
var React = require('React');
var Formsy = require('formsy-react');
var Input = require('./forms/Input.js');
module.exports = React.createClass({
render: function () {
return (
<Formsy.Form>
<Input ref="phonenumber" id="phonenumber" value={this.state.phonenumber.value} name="phonenumber" required validations="isNumeric" validationError="Please provide a valid phone number" />
</Formsy.Form>
);
}
});
Input.js
var Formsy = require('formsy-react');
var React = require('React');
module.exports = React.createClass({
mixins: [Formsy.Mixin],
changeValue: function (event) {
this.setValue(event.currentTarget.value);
},
render: function () {
var className = this.showRequired() ? 'required' : this.showError() ? 'error' : null;
var isReadOnly = this.props.readOnly;
var errorMessage = this.getErrorMessage();
return (
<div className={className}>
<input type="text" onChange={this.changeValue} value={this.getValue()} readOnly={isReadOnly} required={this.isRequired()} formNoValidate />
<span>{errorMessage}</span>
</div>
);
}
});
The formNoValidate attribute is only intended for elements that submit the form. So, placing it on a "text" type of input will work if it is the only input in the form (no submit button).
Imagine having a form for writing an article, It could have two submit buttons, one for "Save draft" that doesn't need to run native validation, and one for "Publish" that does.
Adding noValidate on the form tag should disable native validation on the form completely, however this isn't possible until issue issue 89 is resolved (scheduled for the next release).
write "novalidate" in form tag.
Example
<form method="post" novalidate>...</form>
Example
To disable HTML validation, use noValidate, it`s camel case sensitve:
<form onSubmit={this.handleSubmit} noValidate>
// code
</form>
Apparently, this is a way around the problem:
<Formsy.Form>
<Input ref="phonenumber" id="phonenumber" name="phonenumber" validations="isNumeric" validationError="Oppgi et gyldig telefonnummer"/>
<input type="submit" formNoValidate value="Submit"/>
</Formsy.Form>
I have a custom jQuery validate rule called fiftyCents() where there are two rules:
if the item is free, one can "buy" it for $0.00 or they can pay greater than $0.50.
if the item is NOT free, then they must pay at least the cost specified (stored in a hidden cachedValue input field).
So those are my two validation error messages. The problem I'm having in adding these to fiftyCents() is that I can only figure out how to evaluate it as true/false and if false, display a single message, e.g., "Amount must be $0.00 OR greater than $0.50.".
The solution to the JSfiddle (code below too) appears to be to make a message object that could be part of the fiftyCents() function. However, I don't know how to return that along with evaluating true/false. Thoughts?
JS:
$('button').click(function(){
$('form').validate().form();
});
$.validator.addMethod("fiftyCents", function(value) {
var cachedValue=$('.purchaseModalAmtPaidCached').val();
var value = $('.purchaseModalAmtPaid').val();
var message="Amount must be $0.00 OR greater than $0.50.";
if(cachedValue>0) message='Amount must be at least'+cachedValue+'.';
return cachedValue<=value && (value==0 || (0.51<=value && value<=10000));
}, message);
$.validator.classRuleSettings.purchaseModalAmtPaid = { fiftyCents: true };
HTML:
<form>
<input class="purchaseModalPassword required" minlength="8" type="password"name="password" value="dddddddv" title="Please enter a valid password" />
<input type="text" title="Amount must be $0.00 OR greater than $0.50"
class="required purchaseModalAmtPaid" name="amt_paid" value="" />
<input type="hidden" class='purchaseModalAmtPaidCached required' name="AmtPaidCached" value="0.00" />
<button type='button'>Buy</button>
</form>
Ok I answered my own question. What I ended up doing is splitting up the two rules into their own custom methods. I used an if/else before either custom method is invoked to determine which of the two should be followed.
Here's the JSFiddle and code below:
JS:
$('button').click(function(){
$('form').validate().form();
});
var params=$('.purchaseModalAmtPaidCached').val();
if(params>0){
$.validator.addMethod("AmountOrGreater", function(value, element, params) {
console.log('amountOrGreater'+params[0]);
return params[0]<=value && (value==0 || (0.51<=value && value<=10000));
}, $.validator.format("Amount must be at least {0}."));
$.validator.classRuleSettings.purchaseModalAmtPaid = { AmountOrGreater: params };
}
else{
$.validator.addMethod("fiftyCents", function(value, element, params) {
console.log('fiftyCents'+params[0]);
return params[0]<=value && (value==0 || (0.51<=value && value<=10000));
}, "Amount must be $0.00 OR greater than $0.50.");
$.validator.classRuleSettings.purchaseModalAmtPaid = { fiftyCents: params };
} //else
HTML:
<form>
<input class="purchaseModalPassword required" minlength="8" type="password" name="password" value="dddddddv" title="Please enter a valid password" />
<input type="text"
class="required purchaseModalAmtPaid" name="amt_paid" value="" />
<input type="hidden" class='purchaseModalAmtPaidCached required' name="AmtPaidCached" value="0.00" />
<button type='button'>Buy</button>
</form>
Note: A key to the HTML cooperating with jQuery validate is that if you give your inputs a title='' attribute then that title will always be used, thus overriding the message in your custom rule. This is relevant in my case b/c there were two custom rules/messages and I'm not able to determine in advance of the HTML being rendered which one the user would see.
I'm new to js. trying to create mini validation function which will check fields if they're empty or not.
What i wanna do is, to call func like that checkIfEmpty("fullname, email,..."), then inside function, check each field seperated by comma, collect empty fields to one array, and check at the end if this array is empty or not. Tried something like following func, but don't know all alternatives of php functions in js. Please help me to realize my idea..
function checkIfEmpty(fields)
{
var emptyFields=new Array();
fields=fields.split(',');
foreach(fields as field)
{
if (!field.val()) {
field.attr('class', 'invalid');
emptyFields[] = field;
}
}
if(emptyFields.length()==0){return true;}
else {return false;}
}
Seems like you want something like this:
$("input:text").each(function(i, field) {
if (!field.val()) {
field.addClass('invalid');
}
});
return ($("input.invald").length > 0); // return true if invalid fields
You could also set a class on each input that not suppose to be empty, then on form submission check each input that has this class.
$('#form_id').submit(function() {
$('.required').each(function() {
// if a input field that's required is empty
// we add the class '.invalid'
if(!$(this).val()) {
$(this).addClass('invalid');
}
});
// prevent the submission if number
// there is required fields still empty
return ($('input.invalid').length == 0);
});
This is an example form with one required field called email:
<form method="POST">
<input type="text" name="email" class="required" />
<input type="text" name="firstname" />
<input type="text" name="lastname" />
<input type="submit" value="SEND" />
</form>