Summary: I have 5 text inputs, one of which is using the Date attribute. I'm adding validation to the inputs, and one feature I would like to add is to limit the max date. I know I can do this in HTML, however it looks like that only works for the calendar functionality. My thoughts are using keyup, so the user is unable to exceed the year 2050 (for example) within the input in real time.
Effort: I looked into the Max attribute in HTML for a while, but it looks like I will have to do this manually in either Js or jQuery. My immediate thought is to pull the value from the input, slice the last 4 integers, and then create text validation from that.
I would rather use a text input and create the entire validation myself, but I would like to keep the calendar functionality without using any external resources. I'm curious if there is a simpler or more efficient way of doing this?
<input type="date" class="search__input" id="adv-input-2" placeholder="MM / DD / YY" max="2050-12-31"></span>
I've also noticed that using keyup is actually not firing when I use it on a date input, until the entire date is inputted:
// sets limits for date input
$('#adv-input-2').keyup(function(e) {
let input = $(this);
});
For example, 10/DD/YYYY will result in value: "" until the entire field is completed.
If you want to do this manually then you can use change event instead of keyup like this way.
// sets limits for date input
$('#adv-input-2').change(function(e) {
let input = $(this);
console.log(input.val());
if(input.prop('max') < input.val()) {
input.val('');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<input type="date" class="search__input" id="adv-input-2" placeholder="MM / DD / YY" max="2050-12-31"></span>
Related
I want the time input field on specific times, so that only times from 8 AM to 8 PM can be selected. Bookings booked for 8:01 PM onwards, till booked for 7:59 AM can't be selected.
How can I make this custom time picker using JavaScript/Jquery?
<input name="booking-time" type="time" id="book_time">
To pick times within a required range, you can add a min and max:
function show() {
let t = document.getElementById("book_time");
console.log(t.value);
}
function show2() {
let t2 = document.getElementById("book_time2");
let t2Hour = t2.value.substr(0, 2);
let t2Minute = t2.value.substr(3, 2);
if (t2.value.substr(0, 2) < t2.min) {
alert("Earliest time is " + t2.min);
t2.value = t2.min;
} else if (t2.value.substr(0, 2) > t2.max){
alert("Latest time is " + t2.max);
t2.value = t2.max;
} else {
console.log(t2.value);
}
}
#book_time::after {
content: "___";
position: relative;
left: -20px;
line-height:1.5em;
background-color: white;
color: white;
}
<input type="time" id="book_time" name="booking-time" min="08:00" max="20:00" required onchange="show();">
<input type="time" id="book_time2" name="booking-time2" min="08:00" max="20:00" required onchange="show2();">
UPDATE
There does seem to be a browser issue. Some browsers will honour the min/max values, others don't. The ones that don't show a clock symbol to the right of the HH:MM display. The ones that do, show up/down arrows instead.
The updated snippet above offers two possible solutions.
The first one hides the clock symbol by covering it with a block of white text on a white background defined by the ::after pseudo-selector in a css style. The down-side is that there is nothing to tell the user what to do - they have to know to click in the hour part of the input and use their up/down arrow keys to change the hour value. Additionally, there will be whitespace at the right of the box that can not be removed.
The second one uses javascript to confirm that the hour selected falls within the allowable range. If they select anything outside of those hours, they get an alert and their time is set to either the min or max value as appropriate.
The only other solution would be to provide separate select lists for hours and minutes and restrict the range that way. That's not as elegent as a simple input box but does ensure that the user can not select an invalid value.
Although I am a fan of native (browser only) controls, date (and time pickers) are difficult to handle cross-browser wise. Therefore it is best to use an existing library and to find out what your requirements are exactly.
There are lengthy articles on the topic, it would not make sense to copy them here, therefore I'd like to redirect you there.
UX/Usablity of date/time pickers:
https://uxdesign.cc/ui-mechanics-of-a-date-picker-792f2aceb8aa
https://www.smashingmagazine.com/2017/07/designing-perfect-date-time-picker/
I personally like to use flatpickr.
I have found the code below, that automatically adds '/' to an input with a date. I was wondering if there was a way instead of adding a '/' I could add a '-'? I am not very good with javascript and would appreciate any help.
<input id="dob" type="text" onkeyup="getAge()" />
<script type="text/javascript">
function getAge() {
document.getElementById("dob").value=document.getElementById("dob").value.replace(/^(\d\d)(\d)$/g,'$1/$2').replace(/^(\d\d\/\d\d)(\d+)$/g,'$1/$2').replace(/[^\d\/]/g,'');
</script>
This might be what you are looking for. I made the following adjustments to your original code:
used a variable to call the "dob" element to save lines of code
added event listener because that is preferable to declaring it in your HTML (so say the fancy developers)
changed "keyup" event to be "keydown", because I think it is more reliable
added maxlength to the input so that user cannot add more digits than a date should have
added placeholder to the input so user will know what format they should be able to enter
changed your RegEx to search for - instead of /
N.B. I have not added error checking to make sure user entered a "real" date (i.e. "02-31-2018") would not be caught.
var dob = document.getElementById("dob");
dob.addEventListener("keydown", getAge);
function getAge() {
dob.value = dob.value.replace(/^(\d\d)(\d)$/g,"$1-$2").replace(/^(\d\d\-\d\d)(\d+)$/g,"$1-$2").replace(/[^\d\-]/g,'');
}
<input id="dob" maxlength="10" placeholder="mm-dd-yyyy" type="text" />
I am using a range slider with text box, so whenever I slide the range, the value gets updated in the textbox. Also whenever I change the value in the textbox, the slider will move accordingly.
Here is the code I am using:
$('input[type="range"]').on('input change', function() {
$('#LoanAmntText').val($(this).val());
});
$('#LoanAmntText').keyup(function(e) {
var val = $(this).val().replace(/[^\d\+]/g, ""); // check only for digits
$('#LoanAmntRange').val(val).trigger("change");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="range" min="0" max="20000000" step="100000" value="4000000" id="LoanAmntRange" class="LoanAmntRange">
<input type="text" id="LoanAmntText" />
The slider's min, max and step values are used in a way that it will cover most common values while using the range slider. But when I use the textbox to enter the value, I would like to use any number starting from 0( for ex:I need to enter 2450003).But with current code, it's not allowing me to do so.
What will be the best way to achieve this?
Fiddle:https://jsfiddle.net/anoopcr/cy14pu1L/11/
Your keyup event will trigger after every key press. Since your slider has a step size of 100000 no one digit will able to comply with that. Either change your step size to 1 or use the change event instead.
I am using this html tag as a datetime picker:
<input type="datetime-local">
I want to be able to set a default value for the time part only so if
someone inserts a date and doesn't insert the time (leaves it as --:--:--) then I will be able to set it as 00:00:00 for example.
The problem is I know only how to set the a value including both the date and time and if someone inserts only a date w/o the time I can't read that value and getting a blank value.
Is it possible to overcome that? or is there any other datetime picker I could use for the described scenario?
We can not change the behavior of browser against an element. So this is an answer to the second question that if there is another solution for this scenario. I used two separate fields of date and time which control a single datetime-local field.
Please note that the date filed has no value unless the field is totally completed. So I used blur event instead of keyup or change.
$(document).ready(function() {
var mydate, mytime, mystring;
$("#dateField").blur(function() {
if ($(this).val()) {
setResult();
}
})
$("#timeField").change(function() {
setResult()
})
})
function setResult() {
mydate = $("#dateField").val();
mytime = $("#timeField").val();
mystring = mydate + 'T' + mytime;
document.getElementById('resultField').value = mystring;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="dateField" type="date"><input id="timeField" type="time" value="18:30">
<br>
<strong>Result</strong>:
<br>
<input id="resultField" type="datetime-local">
Footnote 1:
The change listener works on time field (when has default value) but I noticed a vague behavior in google-chrome that if you change the value of time filed by mouse clicks, the change event is triggered after mouseOut! This has no effect on the answer above.
Footnote 2:
You can hide the result field inside a display:none div.
Alternatively, is it possible to validate against another field's value with HTML?
A common example would be selecting a date range where "from" date should be less than or equal to "to" date. The following would described the desired relationship between the values, if only you could use element references in syntax:
<input type="date" name="from" max="to"> //todo: populate with ~to.value
<input type="date" name="to" min="from"> //todo: populate with ~from.value
It's possible to utilize html5 validation mechanism with some javascript to dynamically update min/max attributes:
//in this case a single input restriction is sufficient to validate the form:
$('#from, #to').on('change', function(){
$('#to').attr('min', $('#from').val());
});
Fiddled. Both min and max could be applied to the respective fields for enhanced UX if browser implementation of a datepicker respects range limitations (by disabling dates outside of the desired range)
Here, Web Components are very useful, however they are not full supported in all browsers yet .
The idea is to create a simple html Element, with two children (from and to) as the following:
<div id="fromToDate">
<div></div>
<div></div>
</div>
then create a template, which defines how the date picker should look:
<template id="fromToDateTemplate">
<label for="fromDate">from</label>
<input type="date" class="fromDate" select=":first" required="" />
<label for="toDate">to</label>
<input type="date" class="toDate" select=":last" required="" />
</template>
the select parameter defines, where the value is taken from so the first input field takes the first div from the "#fromToDate".
Last we have to populate the "shadow root" and define the logic:
var shadow = document.querySelector('#fromToDate').webkitCreateShadowRoot(),
template = document.querySelector('#fromToDateTemplate');
shadow.appendChild(template.content);
shadow.querySelector(".fromDate").addEventListener("change", function (e) {
var to = this.value;
shadow.querySelector(".toDate").setAttribute("min", this.value);
});
template.remove();
In the end two input fields are renderd and when selecting a date in the first datepicker, the second datepicker can't pick any lower data.
Fiddler example: http://jsfiddle.net/cMS9A/
Advantages:
Build as widget
Easy to reause
won't break pages
can be styled independently
Disadvantages:
Not supported in all browsers yet
Future reading:
http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom/
http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201/
https://dvcs.w3.org/hg/webcomponents/raw-file/tip/explainer/index.html
If you want to avoid issues with someone hacking / crashing yor site - validate input data with:
(optional) javascript before sending a form (protects against malforming data using javascript, inputting incorrect one, reduces traffic)
(mandatory) on server side (protects against more clever guys that might malform input data using fiddler for example)
This is the only (at least second point) approach that protects you and your site.
It's great to see things moving towards a pure HTML solution ... but why not take a look at using moment.js to fill in the gaps for the time being?
http://momentjs.com/
There are plenty of good examples there and a lot of useful utility methods.
I'm worry, that there's no chance how to validate a input value based on other input value. Only good old javascript.
But maybe you can use <input type="range" …> and set some minimal step (1 day / 1 hour / …). Then you can use min and max value by same-named attributes.