I have mask for my date in MM/YY format. There must be month >= then current, and year >= then current year.
I have regexp pattern here:
<input id="expiration" type="tel" placeholder="MM/YY" class="masked" pattern="(1[0-2]|0[1-9])\/(1[8-9]|2\d)" data-valid-example="12/18" onchange="onChangeInput(event)"/>
Seems like it's ok for this format, but I still can write a year less than 18.
Need a little help from you, stack overflow.
The pattern seems fine, however as noted using an input type tel is likely not a good idea as it's semantically inconsistent.
You might try using script instead of relying on browser validation as support is patchy. Something like the following may suit.
function validateInput(evt) {
var re = new RegExp(this.pattern);
var s = this.value;
// Show whether value is valid or not when input is full
document.querySelector('#s0').textContent = s.length < 5 || re.test(s)? '' : 'Invalid';
}
window.onload = function(){
document.querySelector('#i0').addEventListener('input',validateInput, false);
};
<input id="i0" type="text" placeholder="MM/YY" pattern="(1[0-2]|0[1-9])\/(1[8-9]|2\d)" maxlength="5"><br>
<span id="s0"></span>
Related
I am trying to validate a user input date range. We can accept ISO8601 formatted dates and Date Math Expressions since I am passing it into elasticsearch.
Due to the way the code is, they enter it via an input box so I have to validate the text manually and force them into correct input (unable to transform to proper format).
Sample valid user inputs:
[2021 to 2022]
[2020-12-25T14:48Z to now]
[now-5y to now+1w]
[2020-12-25+1M to now-1m]
Sample invalid user inputs:
[2020-12-25tt4:48Z to now]
[NOW-5y to now+1w]
[now-5y too now+1w]
[2020-12-25+1M To now-1h/d]
So far I [think] I have found a way to confirm the valid ISO8601 and range delimiter but I am having trouble with the regex for the + - / options. This is a snippet of my code so far:
const ALLOWED_NOW_CONSTANTS = /\bnow([+-/][1-9][yMwdhHms])?/; // ISSUE WITH DATE MATHS HERE
const ISO_8601 = /^\d{4}(-\d\d(-\d\d(T\d\d:\d\d(:\d\d)?(\.\d+)?(([+-]\d\d:\d\d)|Z)?)?)?)?$/; // ISSUE ADDING DATE MATHS TO THIS ALSO
const validateDateExpression = (dateStr) => {
return ALLOWED_NOW_CONSTANTS.test(dateStr) || ISO_8601.test(dateStr);
}
const str = userInput.trim();
if (str.startsWith('[') && str.endsWith(']')) {
const dateExpression = trim(str, '[]').split(/(\bto\b)/i);
if (dateExpression.length !== 3) {
return '[startTime to endTime]'
}
if ( !validateDateExpression(dateExpression[0].trim()) ) {
return `${dateExpression[0]} is not a valid format`;
}
if ( !validateDateExpression(dateExpression[2].trim()) ) {
return `${dateExpression[2]} is not a valid format`;
}
return ''
}
So my issue with my regex is for the optional "rounded" date maths as well as the date maths for ISO8601. I want to be able to put in the valid date maths but the : now, now/d, now-3M/y, now-1h/d, 2017-03-22+1y, 2020-12-25T14:48:10.78Z+5w/M, 2020-12-25T14:48:10.78Z/M, etc. are cases where I can't seem to get a regex working for this.
This is because of the optional cases where if it is / then it has to be the yMwdhHms that follows instead of a digit. I can't figure out a regex to get this working (now+8h/d or now/y) .
This is also an issue for my ISO8601 date since they can add the date maths at the end and the ISO8601 date is so flexible.
Any help with this is appreciated.
If anything needs clarification on my end or if there's better solutions to this within my current restrictions let me know.
This question already has answers here:
Javascript: how to validate dates in format MM-DD-YYYY?
(21 answers)
Closed 6 years ago.
I am trying to validate date in js ("yyyy/mm/dd") format. After googling I found other date format checked but I can't get in this format.
Any one plz can help me out.
Here is my code.
function dateChecker()
{
var date1, string, re;
re = new RegExp("\d{4}/\d{1,2}/\{1,2}");
date1 = document.getElementById("visitDate").value;
if(date1.length == 0)
{
document.getElementById("showError").innerHTML = "Plz Insert Date";
document.getElementById("showError").style.color = "red";
}
else if(date1.match(re))
{
document.getElementById("showError").innerHTML = "Ok";
document.getElementById("showError").style.color = "red";
}
else
{
document.getElementById("showError").innerHTML = "It is not a date";
document.getElementById("showError").style.color = "red";
}
}
Try this:
var date = "2017/01/13";
var regex = /^[0-9]{4}[\/][0-9]{2}[\/][0-9]{2}$/g;
console.log(regex.test(date)); // true
console.log(regex.test("13/01/2017")); //false
console.log(regex.test("2017-01-13")); // false
If you use new RegExp then you must call compile on the resulting regular expression object.
re = new RegExp("\d{4}/\d{1,2}/\d{1,2}");
re.compile();
Alternatively you could write the regex this way which does not require compile to be called.
re = /\d{4}\/\d{1,2}\/\d{1,2}/;
EDIT
Note that the above regex is not correct (ie it can approve invalid dates). I guess the brief answer is, don't use regex to validate date times. Use some datetime library like momentjs or datejs. There is too much logic. For instance, how do you handle leap years, different months having different number of possible days, etc. Its just a pain. Use a library that can parse it, if it cant be parsed, its not a date time. Trust the library.
However you could get closer with something like this
re = /^\d{4}\/(10|11|12|\d)\/((1|2)?\d|30|31)$/;
Also if you want to get comfortable with regex, download Expresso
Hopefully I get this format right. I know this is a newbie question and probably pretty obvious but I am confused on how to check these fields. I have two input fields on a JSP file:
<input id="CMDScheduleNumber" type="number" class="textsmall" maxlength="5"
onKeyPress="return numbersonly(this, event)"/>
<input id="CMDContractYear" type="number" class="textsmall" maxlength="4"
onKeyPress="return numbersonly(this, event)"/>
I have a function in a script called "searchEFT" that is checking if either the schedule number or contract year is populated then both must be populated.
<script type="text/javascript">
//function for onchange
$(document).ready(function () {
$("#searchEFT").click(function () {
var Cmd_Sched_Number = document.getElementById("CMDScheduleNumber");
var Cmd_Contract_Year = document.getElementById("CMDContractYear");
var Cmd_Status = document.getElementById("CMDSchedStatus");
var Cmd_Creation_Date = ocument.getElementById("CMDCreationDate");
if (Cmd_Sched_Number == "") {
If(Cmd_Contract_Year !== "")
alert("Schedule Number and EFT Contract Year must be both populated");
return;
}
else if (Cmd_Sched_Number == "") {
alert("Schedule Number and EFT Contract year must be both populated");
return;
}
When I tried to do a debugger if the Cmd_Sched_Number field the value is shown as "" but the valueasnumber is shown as 'NaN'. So when I do a check, should I check it was "" or check it as numeric with isNaN and/or IsNull?
Thanks for the help
var Cmd_Sched_Number = document.getElementById("CMDScheduleNumber");
Gets the Element.
Use .value to get value from the Element
Something like:
var Cmd_Sched_Number = document.getElementById("CMDScheduleNumber").value;
Also, since you have jQuery already, consider using it.
Like:
var Cmd_Sched_Number = $("CMDScheduleNumber").val();
Custom code validations are really a mess. How many conditions you can check? There are a lot of open source libraries and they do the job pretty much well.
I would recommend you to use validate.js. Its very simple and easy to use. It sets the rules on the fields and validate according to them.
Probably you will have to do little more efforts right now to shift your code, but it will be very easy then.
As Aragorn correctly pointed out, make sure you're getting the values, not the Jquery objects or DOM elements.
function isPopulated(val) {
return !(val === '' || isNaN(val));
}
//and then in your click event handler...:
if((isPopulated(Cmd_Sched_Number) || isPopulated(Cmd_Contract_Year)) && !(isPopulated(Cmd_Sched_Number) && isPopulated(Cmd_Contract_Year))) {
//Handle the case where one is populated and the other isn't, assuming you want to treat any non-numbers as not populated.
}
This is if you want a common block for any scenario of one populated and the other not, it will be evaluated like an XOR.
The reason my isPopulated function checks for both an empty string and isNaN is that isNaN('') will evaluated false.
If you don't care whether the entered value is actually numeric or not, then you would maybe want to check value.length > 0, for example.
I am trying to take a string entered by user from a textbox. Check the length of that string and if the string is over a given number perform the slice operation on it.
Here's what I came up with but my code does nothing. Checked console, no errors given.
html:
<form id="slice">
Enter a pharse:<input type="text" id="text_box_2"><br>
<input type="button" value="slice" onclick="Slice()">
Result: <input type="text" id="slice_result"><br>
</form>
Javascript function:
function Slice(){
var UserString = document.getElementById("text_box_2").value;
var UserStringValue = UserString.length;
var Result = Userstring.slice(1,6);
if (UserStringValue > 6){
document.getElementById("Slice_result").value = Result;
}
else{
alert("Please enter a longer phrase.")
}
}
what or where did I go wrong?
Be mindful of case-sensitivity.
This:
var Result = Userstring.slice(1,6);
Should be using UserString (capital "S") as defined earlier in your code.
Next, the input ID should be all lowercase, slice_result, to match to HTML, but your code uses different casing:
document.getElementById("Slice_result")
Here's a working JSBin with these fixes.
EDIT: As JaromandaX mentioned in the comments, if you want to take the first 6 characters you should use slice(0, 6).
from cursory reading of your code. it seems caused by this line
var Result = Userstring.slice(1,6);
and also this one
document.getElementById("Slice_result").value = Result
it should be
var Result = UserString.slice(1,6);
and
document.getElementById("slice_result").value = Result
Usually use of the following
var Value = $('#input_id').val();
will pull the requested information for you.
You can also set up arguments for your slice function and pass in the value when you run onclick();
I'd also note that slice() is a current js function, though your implentation with the capital 'S' is some what different, it may be better practice to change that name a bit.
Is it possible to add something to this function that will set up the date format and require the user to enter MM/DD/YYYY? MASK is not working..
Fee Calculator Function:
function getDatePrice() {
var datePrice = 0;
var theForm = document.forms.form;
var purchasedate = theForm.elements.purchasedate;
var date = new Date(purchasedate.value);
if (Object.prototype.toString.call(date) !== '[object Date]') {
date = new Date();
}
var today = new Date();
var diffMilli = today - date;
var diffDays = Math.floor(diffMilli / 1000 / 60 / 60 / 24); // ..Divide!
if (diffDays > 30) {
datePrice = 20;
}
else {
datePrice= 0;
}
return datePrice;
}
Calling Function:
function calculateTotal()
{
var titleFees = getDatePrice();
var divobj = document.getElementById('totalPrice');
divobj.style.display='block';
divobj.innerHTML = "Estimated Transfer Fees $"+titleFees;
}
Input Button: (Requiring ColdFusion):
<cfinput
type="datefield"
name="purchasedate"
width="130"
required="yes"
message="Please enter purchase date."
value="#dateformat(now(),"mm/dd/yyyy")#"
oninput="calculateTotal();"
>
I am going to go ahead and add an answer here since another question has been opened regarding the same issue. I believe the problem is that the mask attribute on the <cfinput type="datefield" ... code only works when using Flash forms - documentation reference.
I have emphasized the text from that documentation below:
Masking cfcalendar and datefield input
In the cfcalendar tag and the Flash format datefield input control, you use the following masks to determine the format of the output. You can use uppercase or lowercase characters in the mask:
...
The following pattern specifies that the Flash form sends the date selected using a datefield input control to ColdFusion as text in the format 04/29/2004:
<cfinput name="startDate" type="datefield" label="date:" mask="mm/dd/yyyy"/>
Since you are not using a Flash form the mask is not working for you. You could try switching to a regular <cfinput type="text" ... input and change your mask to something like "99/99/9999". That would give you the correct format but the user could still enter invalid dates so you would need additional code to catch that.
In the comments you stated:
What is strange is that I have others that actually work like.. <cfinput type="text" name="odate" id="odate" validateat="onSubmit" validate="noblanks" required="yes" message="Please enter odometer date." value="" mask="99/99/9999" placeholder="08/05/2014"> but for some reason it is just the datefield that will not except the MASK
Notice that you are using a "text" input here so the mask works (as in my previous comment). It is only with the "datefield" type that the mask does not work; unless you are using a Flash form.
This is just another example of why using the built-in ColdFusion UI tags is not a good idea. They work for very simple examples but when you need more customization they fail you. You would be better off to use a JavaScript library (like jQuery) for client side validation. Adobe's own Ben Forta acknowledged this several years ago. And the ColdFusion-UI-the-Right-Way project was started because of this as well.
EDIT
Adam pointed out another reference in the ColdFusion documentation that reinforces my point. I have emphasized the text from that documentation below:
Masking input data
In HTML and Flash forms, the mask attribute controls the format of data that can be entered into a text field or that is selected in a datefield input control calendar. In HTML format, it does not prevent users from typing a date that does not follow the mask into a datefield input control. You can combine masking and validation on a field.