I noticed the time is NOT showing in the input if the value does not have a leading zero… So 7:30 doesn’t work but 07:30 works.
Now about the min and max attributes of the time input…
There is no validation made out of the box by the browser yet…
You can notice that even the MDN example is not behaving has it should.
So I added somekind of a basic validation starter. It at least prevents the form submit and adds a class to the time element if the chosen value is incorrect.
$("#temple").on("change", function() {
var value = $('#temple').val();
var min = $('#temple option[value="' + value + '"]').data('opentime');
var max = $('#temple [value="' + value + '"]').data('closetime');
console.log(value, min, max)
$("#time").attr({
value: min,
max,
min
});
});
$("#timeForm").on("submit", function(e){
e.preventDefault();
let time = $("#time");
if( time.val() < time.attr("min") || time.val() > time.attr("max") ){
time.addClass("error");
return;
}
// if the time is correct, submit
$(this).submit();
});
$("#timeForm").on("change",function(){
$("#time").removeClass("error");
});
Here, when a Option is selected, the Min, Max, and Value of the Time input are update. once updated, we trigger an Input event, this will cause the Value to appear to the User. Values can be in the Input that are outside the Min and Max, this will cause the Input to be invalid. If the User then adjusts the time, it will forced to match the Min Max via jQuery.
Note: When the data entered by the user doesn’t adhere to the stepping configuration, the user agent may round to the nearest valid value, preferring numbers in the positive direction when there are two equally close options.
This property has some strange effects across browsers, so is not completely reliable.
Solution 3 :
As stated above, the problem with the OP code was merely a typo:
The input’s min and max attribute values must be strings in the form “hh:mm” (“h:mm” is invalid):
<input type="time" min="08:30" max="16:00">
However, this typo fix alone does not address browser incompatibilities. As MDN states:
… in Safari, and any other browsers that don’t support <time>, it [<input type="time">] degrades gracefully to <input type="text">.
and a degraded input will not be checked for min/max errors.
To address this browser incompatibility, the code below detects inputs that have been degraded to the form <input type="text" min="hh:mm" max="hh:mm">, and adds a validator script to the form.
If a validation error is detected, the error message will be shown in an overlay above the input (matching the native behavior in Chrome and Firefox).
// the "real" form submits
const timeForm = document.getElementById('formtime');
timeForm.onsubmit = function () {
alert('time form was submitted');
};
const textForm = document.getElementById('formtext');
textForm.onsubmit = function () {
alert('text form was submitted');
};
// time validator for degraded time inputs
// Note: This must be loaded AFTER all user form submitters have
// been added
(function () {
// error overlay custom element
class ErrorOverlay extends HTMLElement {
constructor () {
super();
// create a shadow root
let shadowRoot = this.attachShadow({mode: 'open'});
// create shadow DOM element
const overlay = document.createElement('div');
this.overlay = overlay;
overlay.className = 'error-overlay';
// create css for the shadow DOM
const style = document.createElement('style');
style.textContent = `
.error-overlay {
font-family: Helvetica, sans-serif;
position: absolute;
z-index: 1000;
border: 1px solid #808080;
border-radius: 4px;
color: #f8f8f8;
background-color: #808080;
padding: 0.2rem 0.4rem;
display: none;
}
.error-overlay::after {
content: " ";
position: absolute;
top: 100%;
left: 24px;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #808080 transparent transparent transparent;
}
`;
// attach shadow DOM to shadow root
shadowRoot.appendChild(style);
shadowRoot.appendChild(overlay);
}
// show error overlay above the input
show (input, message) {
const {top, right, bottom, left} = input.getBoundingClientRect();
const overlay = this.overlay;
overlay.style.top = Math.round(top - 34 + window.scrollY) + 'px';
overlay.style.left = Math.round(left) + 'px';
overlay.innerText = message;
overlay.style.display = 'block';
// hide overlay
function overlayHide () {
overlay.style.display = 'none';
// remove listeners
input.removeEventListener('keyup', overlayHide);
input.removeEventListener('blur', overlayHide);
}
// add input listeners and focus the input
input.addEventListener('keyup', overlayHide);
input.addEventListener('blur', overlayHide);
input.focus();
}
}
// create overlay instance & add to body
customElements.define('error-overlay', ErrorOverlay);
const errorOverlay = document.createElement('error-overlay');
document.body.appendChild(errorOverlay);
// convert time string to decimal hours
// time string patterns: "hh:mm AM", "hh:mm PM", "hh:mm"
function timeStringToDecimalHours (timeStr) {
let [hhmm, ampm] = timeStr.split(' ');
ampm = (ampm || '').toLowerCase();
let [hour, minute] = hhmm.split(':').map(el => Number(el));
if (ampm === 'pm' && hour < 12) {
hour += 12;
} else if (ampm === 'am' && hour === 12) {
hour = 0;
}
return hour + (minute / 60);
}
// get array of inputs that have this pattern:
// <input type="text" min="hh:mm" max="hh:mm">
function getDegradedTimeInputs (form) {
return Array.from(form.querySelectorAll('input'))
.filter(input => {
if (input.type !== 'text') { return false; }
return input.hasAttribute('min') ||
input.hasAttribute('max');
});
}
// validate inputs when form is submitted
function validateTimeOnFormSubmit (evt) {
// get form's inputs that have type="text", `min` and/or `max`
const form = evt.target;
const tInputs = getDegradedTimeInputs(form);
// validate that each input value is between min and max
for (const input of tInputs) {
const {value, max, min} = input;
// convert time strings into decimal hours
const valTime = timeStringToDecimalHours(value),
minTime = timeStringToDecimalHours(min),
maxTime = timeStringToDecimalHours(max);
if (valTime < minTime || maxTime < valTime) {
// show the error overlay and prevent the submit
errorOverlay.show(input, `Time must be between ${min} and ${max}`);
return false;
}
}
// complete the submit
return form.realOnSubmit(evt);
}
// add time validator to all forms that contain degraded time inputs
const forms = document.querySelectorAll('form');
function submitHandlerStub () { return true; }
for (const form of forms) {
if (getDegradedTimeInputs(form).length > 0) {
// store the real submit handler as `form.realOnSubmit`
const realOnSubmit = form.onsubmit || submitHandlerStub;
Object.defineProperty(form, 'realOnSubmit', {
value: realOnSubmit,
enumerable: false
});
form.onsubmit = validateTimeOnFormSubmit;
}
}
})();
<h1>Validate a form's degraded time inputs</h1>
<p>Some browsers do not support <code><input type="time"></code>, degrading it to <code><input type="text"></code>.</p>
<p>This script detects these degraded inputs and validates them accordingly.</p>
<form id="formtime">
<label for="timeinput">TIME input (min 09:30, max: 14:00):</label>
<input id="timeinput" type="time" min="09:30" max="14:00" placeholder="hh:mm AM/PM" />
<button type="submit">Submit</button>
</form>
<form id="formtext">
<label for="degraded">TEXT input (min 09:30, max: 14:00):</label>
<input id="degraded" type="text" min="09:30" max="14:00" style="width: 5rem" placeholder="hh:mm AM/PM" />
<button type="submit">Submit</button>
</form>
Problem :
As you see in the code, i want to let users select the time between opening and closing time (min.max), but its not working, it’ll take all time entered and some times it’ll work only for max time. I’ve seen similar questions, i couldn’t find any solutions.
Welcome to Stack Overflow. It’s not clear fro myour example what you have tried. I see that it gathers the Min and Max, then what did you want it to do?
Comment posted by Nick
yes it even sets min and max properly but it wont work as intended, it’ll also take the time entered thats outside of min and max
Comment posted by browser support for input type=”time”
Have you checked the
Comment posted by Nick
ty, it works now, someone just answered it,( and removed the answer ) just had to add 0 in front of 9:30 , 7:30 , 8:30 like 09:30, 07:30, 08:30,