How can I restrict a time input value? - html

I want to display an input type hour from 08:00 to 20:00. I tried this:
<input type="time" id="timeAppointment" name = "timeAppointment" min="08:00" max="20:00" placeholder="hour" required/>
But when I display it I can still select any time, it does not restrict me as I indicate. What is the problem? If is necessary some code I work with Javascript.

The constraints within the input do not prevent from entering an incorrect value in this case. Here is an overview of what MDN says in their documentation:
By default, does not apply any validation to entered values, other than the user agent's interface generally not allowing you to enter anything other than a time value.
But you can write validations with JavaScript, or visual validations with CSS, like so:
.container{
display:flex;
align-items:center;
gap:1rem;
}
input:invalid+span:after {
content: '✖';
}
input:valid+span:after {
content: '✓';
}
<div class = "container">
<input type="time" id="timeAppointment" name = "timeAppointment" value="08:00" min="08:00" max="20:00" placeholder="hour" required/>
<span class="validity"></span>
</div>

Setting min and max properties in input tags do not inherently prevent you from accepting out of range values as inputs, but it controls the valid property of the tag, which can then be used such as in css to style your page accordingly. Some browsers do make it so that you cannot input out of the specified range, but it is not platform-independent behaviour.
See more here: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/time#setting_maximum_and_minimum_times
If you want to ensure that only the time between min and max are input, you could programmatically implement that using an onchange listener on your input element as follows:
Make sure to indicate to the user why their input is not changing (because it is not between min and max) using css and text, etc.
const timeInput = document.getElementById("timeAppointment");
timeInput.value = '15:56';
let previousValue = timeInput.value;
timeInput.onchange = () => {
console.log(previousValue)
console.log(timeInput.value)
if (timeInput.value < timeInput.min || timeInput.value > timeInput.max) {
timeInput.value = previousValue;
}
previousValue = timeInput.value;
}
<input type="time" id="timeAppointment" name="timeAppointment" min="08:00" max="20:00" required/>
However, there is a caveat to this. Imagine you are changing your time from 02:00PM to 11:00AM. You would go from left to right, and as soon as you change 02 hours to 11 hours, the javascript validation fails as it becomes 11:00PM and the value is not able to update.
Either you will have to write a convoluted way to get around all the edge cases, or the users will have to find a weird way to change their time. This is why this is generally a bad idea to validate on every input like this, and instead you can validate it when you submit the form, or onfocusout and let the user know by appropriate styling.

Related

angular ngModel style

Is it possible to style the value in the attribute ngModel of an input tag?
Example:
<input class="input" type="text" [(ngModel)] = "myService.text">
Let's say the value of text is '28 packages', can I put 28 in bold?
So if i understand correctly you want to have it bold whenever the value is 28 ?
yes its possible you can use a ng-class with a ternary expression like this
.bold{
font-weight:600;
}
<input type="text" ng-class="myService.text == '28 ? 'bold' : '''" class="input" ng-model="myService.text" />
This is not angular-related rather a CSS related question.
You cannot style only a part of an input in HTML/CSS so you won't be able to do it in angular.
Instead, you can use an input that is hidden behind a div. The idea is that when the user clicks the div, you actually focus the input. When the user types text, you capture the content of the input and fill the div with it, eventually adding <span class"highlight"> around the number of packages.
I prepared you a stackblitz in pure CSS/JS. You can adapt it in angular if you want.
Relevant pieces of code :
HTML :
<span id="hiddenSpan">This is the hidden div. Click it and start typing</span>
<div>
<label for="in">The real input</label>
<input id="in" type="text">
</div>
JS :
const input = document.getElementById('in')
const hiddenSpan = document.getElementById('hiddenSpan')
function onInputChanged() {
let text = input.value
const regex = new RegExp('(\\d+) packages')
let result = regex.exec(text)
if(result) {
hiddenSpan.innerHTML = '<span class="highlight">'+result[1]+'</span> packages'
} else {
hiddenSpan.innerHTML = text
}
}
// Capture keystrokes.
input.addEventListener('keyup', onInputChanged)
// Focus the input when the user clicks the pink div.
hiddenSpan.addEventListener('click', function() {
input.focus()
})
CSS :
#hiddenSpan {
background-color: pink;
}
.highlight {
font-weight: bold;
background-color: greenyellow;
}
Note : the downside is that the blinking caret is not visible anymore. You can take a look at this resource if you want to simulate one.
It is not possible to style certain parts of a text <input> field in bold. However, you can use a contenteditable div instead of a text <input> field. Inside the contenteditable div you can have other HTML tags like <strong> to style certain parts of the text however you like.
I created an Angular directive called contenteditableModel (check out the StackBlitz demo here) and you can use it to perform 2-way binding on a contenteditable element like this:
<div class="input" contenteditable [(contenteditableModel)]="myService.text"></div>
The directive uses regular expressions to automatically check for numbers in the inputted text, and surrounds them in a <strong> tag to make them bold. For example, if you input "28 packages", the innerHTML of the div will be formatted like this (to make "28" bolded):
<strong>28</strong> packages
This is the code used in the directive to perform the formatting:
var inputElement = this.elementRef.nativeElement;
inputElement.innerHTML = inputElement.textContent.replace(/(\d+)/g, "<strong>$1</strong>");
this.change.emit(inputElement.textContent);
You can change the <strong> tag to something else (e.g. <span style="text-decoration: underline"> if you want the text to be underlined instead of bolded).
When performing the formatting, there is an issue where the user's text cursor position will be unexpectedly reset back to the beginning of the contenteditable div. To fix this, I used 2 functions (getOriginalCaretPosition and restoreCaretPosition) to store the user's original cursor position and then restore the position back after the text formatting is performed. These 2 functions are kind of complex and they're not entirely relevant to the OP's question so I will not go into much detail about them here. You can PM me if you want to learn more about them.

HTML5, autocomplete: How to combine postal-code and address-level2 in one single text field?

I have an online shop with a checkout form for typing in your name, address, and contact data.
The HTML5 autocomplete tags generally work for Chrome/Android users, but unfortunately, there is one text field for postal code and city combined in one field (for example, "10559 Berlin").
It seems that I can only tag this field with autocomplete='postal-code' or autocomplete='address-level2', but not both together in one field, so autocomplete='postal-code address-level2' makes Chrome insert only the city when autofill is used, but not the postal code. I'm also assuming that it goes vice versa the other way around (i.e. autocomplete='address-level2 postal-code would make Chrome fill in the postal code only.
Does anybody maybe know how to use both of these two autocomplete detail tokens into one single field with one autocomplete attribute?
That's not possible to do - in this way.
There are other ways like autofill city with postal code, my guess would be to do it the other way - to autofill postal code with given city/village etc. because its often the case that many villages have the same number (and also the same street names)!
You would go and listen oninput for the specific input field and add the postal code after the city is inserted so go for autocomplete="address-level2".
If you wanted to get really hacky, you could make it look like one input box, but each has its own autocomplete tag and it would automatically switch boxes when a space is typed or when the user tabs after selecting a value from the autofill list.
See this example:
var zipInput = document.getElementById('zipInput');
var cityInput = document.getElementById('cityInput');
zipInput.addEventListener('keyup', function() {
if (zipInput.value.slice(-1) != " ") {
return;
}
var text = zipInput.value.split(" ")[0];
cityInput.focus();
});
zipInput.focus();
input {
border: 1px solid black;
}
#zipInput {
border-right: none;
width: 75px;
}
#cityInput {
border-left: none;
width: 125px;
}
<h4>Postal Code & City:</h4>
<form onsubmit="javascript: return false;">
<input id="zipInput" autocomplete='postal code'><input id="cityInput" autocomplete='address-level2'>
<button type="submit">Submit</button>
</form>
<br><br>
Hello my German friends ;-)
Finally, I decided to separate the combined field for postal code and city into two fields, one for postal code and one for city. So I can use a single autocomplete token for each one, although the separation caused some changes also on other places within the code.
It's not possible but you can use an ugly trick. put the second input text anywhere in the site the user can't see :)
here is my jsfiddle: jsfiddle
Address: <input type="text" id="autocomp" value="" autocomplete="postal-code">
<input id="hid" type ="text" value="" autocomplete="locality" onchange="change()">
<script>
function change () {
var a = document.getElementById("hid").value;
var b = document.getElementById("autocomp").value;
var c = b + " " +a;
document.getElementById("autocomp").value = c;
}
</script>
in this example is the id="hid" is the second input field. (display : none is not working)

Adding functionality to UTF arrow

Is there anyway that I can add functionality to this arrow?
▼
I want it to be clickable and if clicked for it to increase a value of an input by one. So say there is the value of 5 in an input box, if the arrow was clicked, the value would show 6.
Is this possible to do or is there a better approach?
It sounds like you could be looking for the number input type. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input for a list of input types. The code to make a number input is:
<input type="number">
In HTML
<input type="text" readonly id="textbox" />
<a id="increment" style="cursor:pointer;">▼</a>
In Jquery, add this
$("#increment").click(function(e) {
var old_val = +$("#textbox").val();
var increment = +'1'
var new_val = old_val + increment;
$("#textbox").val(new_val);
});
This will increment the text field value on the arrow click.

How do i set the textbox to be already in focus when my webpage loads

I want a textbox to be in focus when my webpage loads. If you go to google.com you can see the textbox is already in focus. That's what I want.
Heres my form:
<form id="searchthis" action="#" style="display:inline;" method="get">
<input id="namanyay-search-box" name="q" size="40" x-webkit-speech/>
<input id="namanyay-search-btn" value="Search" type="submit"/>
Give your text input the autofocus attribute. It has fairly good browser-support, though not perfect. We can polyfill this functionality rather easily; I've taken the liberty to write up an example below. Simply place this at the bottom of your document (so that when it's ran, the elements already exist), and it will find your autofocus element (note: you should have only one, otherwise you could get inconsistent results), and draw focus upon it.
(function () {
// Proceed only if new inputs don't have the autofocus property
if ( document.createElement("input").autofocus === undefined ) {
// Get a reference to all forms, and an index variable
var forms = document.forms, fIndex = -1;
// Begin cycling over all forms in the document
formloop: while ( ++fIndex < forms.length ) {
// Get a reference to all elements in form, and an index variable
var elements = forms[ fIndex ].elements, eIndex = -1;
// Begin cycling over all elements in collection
while ( ++eIndex < elements.length ) {
// Check for the autofocus attribute
if ( elements[ eIndex ].attributes["autofocus"] ) {
// If found, trigger focus
elements[ eIndex ].focus();
// Break out of outer loop
break formloop;
}
}
}
}
}());
After some initial testing, this appears to provide support all the way back to Internet Explorer 6, Firefox 3, and more.
Test in your browser of choice: http://jsfiddle.net/jonathansampson/qZHxv/show
The HTML5 solution of Jonathan Sampson is probably the best. If you use jQuery, steo's sample should work, too. To be complete, here you go plain JS solution for all browsers and IE10+
window.addEventListener("load",function() {
document.getElementById("namanyay-search-box").focus();
});
$(document).ready(function(){
..code..
$('.textbox-class-name').focus();
..code..
});
Or you can try it on $(window).load()

Custom glyphs inside password input [duplicate]

Suppose I have a textbox and I want that when the user types inside it then each character will be converted to a password symbol after 1 sec by jQuery.
The same effect that we see on modern smart-phones when we type into password textboxes.
Does anyone have any suggestions? I know how to capture the key press and get the character user typed.
<input type="text" id="username" name="username" />
<script type="text/javascript">
$("#username").keypress(function(event){
// Get the keypress value
// ...?
var c = String.fromCharCode(e.which);
}
});
</script>
You can start with that: http://jsfiddle.net/89CF8/7/
But it works only if you type correctly.
You should save the value in another variable (I use letters array in the example), because standard input only allows you to change it's value for asterisks, losing all that user has been typed.
Issue #1. You should add checking for non-symbols. For example, Del key will add bad symbol to letters array.
Issue #2. You should add checking for backspace and use splice to remove elements.
Issue #3. If user deletes symbol from the middle of the text, it's very hard to synchronize new value with your variable, which stores the initial value.
After all, I think that it isn't good idea, but maybe my code will help you to find better solution.
You dont actually need to handle key press. Use 1sec timeout loop, and replace all characters in textbox with stars. And dont forget to store characters in a varaible.
Something like below would help you, but you have to spend some time to fix bugs.
http://jsfiddle.net/ymutlu/8BXDu/2/
custom mask password by javascript
custom mask password
<style>
.mask {
position: relative;
overflow: hidden;
}
input#pass {
position: absolute;
left: 0;
top: 0;
opacity: 0;
}
</style>
<script>
var txt = document.getElementById("txtMask");
var hdn = document.getElementById("pass");
hdn.addEventListener("keyup", function(evt){
txt.value = '';
for(let i=0; i<hdn.value.length;i++)
{
txt.value +='#';
}
});
</script>
<div class="mask">
<input type="text" id="txtMask" autocomplete="false">
<input type="text" id="pass">
</div>