I am building an "autofill" function. When the user types something in an input field and the system finds this string in the database it should display the string into the input field in grey, similar to what google used to/still have/has.
Therefore I built two input fields, one that's clearly visible:
html:
<input id="email_input" type="text">
<input id="autofill" type="text">
css:
#email_input{
background-color: transparent;
z-index: 100;
}
Then I position the autofill input via JS exactly where email_input is.
function positionAutocompleteInput(){
var top = $('#email_input').position().top;
var left = $('#email_input').position().left;
$('#autofill').css({'top':top});
$('#autofill').css({'left':left});
}
positionAutoFillInput();
The actual autfill I do like this:
function autofill(context){
var input = $('#email_input').val();
var replacement = context[0].email;
replacement = replacement.slice(input.length);
var display = input + replacement;
$('#autofill').val(display)
}
I tried calling positionAutoFillInput(); onInput, so that it gets repositioned with each input. If I look at the positions of both input fields in the console, they both have the same positions.
Both input fields have the same font-size and font-family.
For some reason it still looks off:
Anyone know an answer?
Can you just position them with CSS like this? This way it requires no JavaScript to position it.
#autofill, #email_input {
font-size: 20px;
}
#autofill {
position: absolute;
color: #CCCCCC;
}
#email_input {
position: relative;
z-index: 1;
background: transparent;
}
<h1>Test</h1>
<div>
<input id="autofill" type="text" value="1234567890">
<input id="email_input" type="text">
</div>
Related
When I type the last number in, the first number goes inside the text-box (it disappears), it's adding one extra space.
After I click outside the text-box it looks good which I need during typing last character.
#number_text {
padding-left: 9px;
letter-spacing: 31px;
border: 0;
background-image: linear-gradient(to right, #e1e1e1 70%, rgba(255, 255, 255, 0) 0%);
background-position: left bottom;
background-size: 38px 1px;
background-repeat: repeat-x;
width: 220px;
box-sizing: border-box;
outline:none;
}
<input type="text" id="number_text" maxlength="6" pattern="\d{6}" value="1234" >
Help me to get out from this issues. Thanks
Add space for another number and clip the input using clip-path
#number_text {
padding-left: 9px;
letter-spacing: 31px;
border: 0;
background:
repeating-linear-gradient(to right, #e1e1e1 0 26px, transparent 26px 38px)
bottom/100% 1px no-repeat;
width: 260px;
clip-path:polygon(0 0, calc(100% - 38px) 0, calc(100% - 38px) 100%, 0 100%);
box-sizing: border-box;
outline: none;
}
<input type="text" id="number_text" maxlength="6" pattern="\d{6}" value="1234">
Or without clip-path by reducing the background-size:
#number_text {
padding-left: 9px;
letter-spacing: 31px;
border: 0;
background:
repeating-linear-gradient(to right, #e1e1e1 0 26px, transparent 26px 38px)
bottom left/calc(100% - 38px) 1px no-repeat;
width: 260px;
box-sizing: border-box;
outline: none;
}
<input type="text" id="number_text" maxlength="6" pattern="\d{6}" value="1234">
Use this code. its nicely work
var container = document.getElementsByClassName("wrap")[0];
container.onkeyup = function(e) {
var target = e.srcElement;
var maxLength = parseInt(target.attributes["maxlength"].value, 6);
var myLength = target.value.length;
if (myLength >= maxLength) {
var next = target;
while (next = next.nextElementSibling) {
if (next == null)
break;
if (next.tagName.toLowerCase() == "input") {
next.focus();
break;
}
}
}
else if (myLength <= maxLength)
{
prev=target.previousElementSibling;
while (prev = prev) {
if (prev == null)
break;
if (prev.tagName.toLowerCase() == "input") {
prev.focus();
break;
}
}
}
}
.wrap input {
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #000;
width: 3%;
display: inline-block;
outline: 0;
text-align: center;
}
<div class="wrap">
<input type="text" maxlength="1" />
<input type="text" maxlength="1" />
<input type="text" maxlength="1" />
<input type="text" maxlength="1" />
<input type="text" maxlength="1" />
<input type="text" maxlength="1" />
</div>
Try to add this script bellow the input-field:
<script>
var oInput = document.getElementById('number_text');
oInput.onkeypress = function(ev) {
setTimeout(function() {
if( oInput.value.length > 5 ) {
oInput.setSelectionRange(0,0);
oInput.blur();
}
}, 0);
}
</script>
This one forces your input-cursor to the beginning of the input after the 6th character was entered. I also added a blur() to the field so the cursor-jump to the beginning won't stick out.
The timeout is also needed. Without it the entered character will be inserted at the beginning. More about timeout: Is setTimeout a good solution to do async functions with javascript?
You can deal with it by adding a blur() event of js onkeyup of input box:
myFunction=()=>{
if(document.getElementById("number_text").value.length===6)
document.getElementById("number_text").blur();
}
#number_text {
padding-left: 9px;
letter-spacing: 31px;
border: 0;
background-image: linear-gradient(to right, #e1e1e1 70%, rgba(255, 255, 255, 0) 0%);
background-position: left bottom;
background-size: 38px 1px;
background-repeat: repeat-x;
width: 220px;
box-sizing: border-box;
outline:none;
overflow-y:hidden;
overflow-x:hidden;
}
<input type="text" id="number_text" maxlength="6" pattern="\d{6}" value="1234" onkeyup="myFunction()" >
<br/>
Please change on css below (it will works)
padding-left: 14px;
to
padding-left: 5px;
So I like Temani Afif's answer about using the clipping mask. Think it's great.
I wanted to propose another solution (a little less elegant). I used Firefox to also test this problem, and clicking outside the text area (losing focus) does not make the 1st digit re-appear or the string go back to normal in the text input there.
I believe the issue is the letter spacing css attribute you set:letter-spacing: 31px;, and the fact that I believe this would apply to the "blinking" caret that most browsers have. Using Chrome, it seems to remove this when it loses focus, while Firefox retains this even after losing focus.
The 1st solution was to use manually call the blur() function to make the input lose focus. This works in Chrome (using a Self-Executing Anonymous Function):
<input type="text" id="number_text" maxlength="6" onkeyup="(function()
{
var x = document.getElementById('number_text');
let value = x.value
if (value.length >= 6){
x.blur()
return false
}
})();"
pattern="\d{6}" value="1234" >
or even as a Defined Function called by the number_text input like so:
<script>
handleMaxInput = function(){
var x = document.getElementById('number_text');
let value = x.value
if (value.length >= 6){
x.blur()
return false
}
};
</script>
<input ... id='number_text' ... onkeyup="handleMaxInput()" ... >
You will notice a slight delay in Chrome, but calling this in Firefox will not resolve the issue.
We can essentially force this same behavior in Firefox. After some playing around, I figured that Chrome was refreshing/recalculating the letter spacing on a blur. My play session showed that you could force Firefox to recalculate this value programmatically:
Change the inline style of the input's letter-spacing attribute to a different value (as we cannot edit a CSS class of number_text programmatically without much effort, such as re-writing the entire style tag in the style section of a document).
Remove the Class number_text from the input.
1 and 2 are interchangeable, you need Firefox to fallback to only the inline style you set, without having the class attributes saved 'in memory'.
Remove the inline-style and reapply the number_text CSS class. This will force the browser to recalculate the letter-seperation as we need it to.
In code, it would look like the following JavaScript function:
handleMaxInput = function(){
var x = document.getElementById('number_text');
let value = x.value
if (value.length >= 6){ // if the input is 6 or more characters
x.classList.remove('number_text') // remove the class
x.style.letterSpacing = '0px' // reset the spacing
setTimeout(function() { // set time to let browser refresh updates
x.classList.add('number_text') // Re-add class after browser refresh
setTimeout(function() { // Remove inline-style after more reculculations
x.style.removeProperty('letter-spacing') // Remove inline style to let class styles apply
x.blur // optional, will force input field to lose focus. Else comment out to avoid that.
}, (1)); // waits 1 millisecond
}, (1)); // waits 1 millisecond
}
}
It will have that same flicker in Firefox as with Chrome, and all shall be well.
Note: The timeout functions are to give the browser time to refresh, and actually update what we need.
Note: You can choose to call .blur() in the function to make the textbox lose focus, or omit that and they will still be in the input field without the error with the digits.
Hope this helps your conceptual understanding, as well as solving the issue. Some other individuals gave good solutions that avoid the whole flicker thing, and work in both Firefox and Chrome!
It looks like a common UI issue I've encountered before.
I bet it only fails on some platforms as well (this is the nature of this particular bug.)
On some, but not all, platforms, a spacing character is used to indicate the caret.
On some, but not all, platforms, this character is non-spacing, but overlaying, on the next, not the last, character. Hence if there is no next character will be filled with the space until input is done.
In both these cases the display will act in this manner.
This is a case where the best solution is the simplest solution, accommodating for this common system quirk, not the solution that forces it to behave the way you want it to as some people suggested. This is less likely to introduce bugs, and more likely to work on all platforms.
The solution is give a little bit of spare room at the end of the entry for displaying this.
Increase "width" to 230 or 240 and you should be good.
Further, you could even better accommodate non-standard systems, especially accessibility systems with alternative fonts or size attributes, by simply detecting the width by entering full width spaces in the area, adding a quarter width space at the end, measuring them, then deleting them, or simply rigging it to overwrite the full width spaces as the user types (or otherwise enters data, don't presume it's a keyboard or even something that enters one character at a time.)
$(document).on('keyup','#numberinput',function(){
var aa = $(this).val();
var aa = aa.substring(1);
if(aa.length > 5)
{
$('#numberinput').val(aa);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" name="" id="numberinput">
N.B.: I should note that the proper solution to this is to just use the 'placeholder' attribute of an input, but the question still stands.
Another N.B.: Since, as Quentin explains below, the "value" attribute stores the default value, and the input.value IDL attribute stores the current value, the JavaScript I used to "fix" the problem in my below example is non-conforming, as it uses the (non-IDL) value attribute to store current, rather than default, values. Besides, it involves DOM access on every key press, so it was always just a flawed demo of the problem I was having. It's actually quite terrible code and shouldn't be used ever.
CSS selectors made me think that I could make an input with a label that acts as a preview without any JS. I absolutely position the input at 0,0 inside the label (which is displayed as an inline-block) and give it a background of "none", but only if it's got a value of "" and isn't focussed, otherwise it has a background colour, which obscures the label text.
The HTML5 spec says that input.value reflects the current value of an input, but even though input.value updates as you type into an input, CSS using the input[value=somestring] selector applies based only on what was explicitly typed into the document, or set in the DOM by the JavaScript setAttribute method (and perhaps by other DOM-altering means).
I made a jsFiddle representing this.
Just in case that is down, here is an HTML document containing the relevant code:
<!doctype html>
<head>
<meta charset="utf-8" />
<title>The CSS Attribute selector behaves all funny</title>
<style>
label {
display: inline-block;
height: 25px;
line-height: 25px;
position: relative;
text-indent: 5px;
min-width: 120px;
}
label input[value=""] {
background: none;
}
label input, label input:focus {
background: #fff;
border: 1px solid #666;
height: 23px;
left: 0px;
padding: 0px;
position: absolute;
text-indent: 5px;
width: 100%;
}
</style>
</head>
<body>
<form method="post">
<p><label>name <input required value=""></label></p>
</form>
<p><button id="js-fixThis">JS PLEASE MAKE IT BETTER</button></p>
<script>
var inputs = document.getElementsByTagName('input');
var jsFixOn = false;
for (i = 0; i < inputs.length; i++) {
if (inputs[i].parentNode.tagName == 'LABEL') { //only inputs inside a label counts as preview inputs according to my CSS
var input = inputs[i];
inputs[i].onkeyup= function () {
if (jsFixOn) input.setAttribute('value', input.value);
};
}
}
document.getElementById('js-fixThis').onclick = function () {
if (jsFixOn) {
this.innerHTML = 'JS PLEASE MAKE IT BETTER';
jsFixOn = false;
} else {
this.innerHTML = 'No, actually, break it again for a moment.';
jsFixOn = true;
}
};
</script>
</body>
</html>
I could be missing something, but I don't know what.
The value attribute sets the default value for the field.
The value property sets the current value for the field. Typing in the field also sets the current value.
Updating the current value does not change the value attribute.
Attribute selectors only match on attribute values.
There are new pseudo classes for matching a number of properties of an input element
:valid
:invalid
:in-range
:out-of-range
:required
A required element with no value set to it will match against :invalid. If you insist on using the value instead of placeholder, you could simply add a pattern or a customValidity function to force your initial value to be counted as invalid.
I'm trying to make an auto resize like input, like when the user type in, the input will adjust automatically to fit the value inside the input but seem's I can't make it right or working. Any ideas, help please?
$(document).ready(function(){
$('input').on('input',function(){
$(this).css('width',$(this).width()+$(this).val().length );
});
});
input{border:1px solid red;width:30px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text">
I suggest using contenteditable-span in this case, i hope it helps.
#test{border:1px solid red;width:30px;}
<span id="test" contenteditable>I'm trying to make an auto resize like input</span>
If your goal is for it to be just as wide as necessary, maybe with a 30px buffer, then the issue is you're adding to the width every time rather than recalculating it from scratch. It would also help if you knew how wide a character might be, so probably best to set the font size specifically or even use another hidden element to measure how wide the rendered text is; here I use a span for that:
$(document).ready(function(){
$('input').on('input',function(){
var $this = $(this);
// Get the value
var val = $this.val();
// Put it in the hidden span using the same font information
var $hidden = $(".hidden");
$hidden.text(val);
// Set the input to the span's width plus a buffer
$this.css('width', $hidden.width() + 30);
});
});
input {
border:1px solid red;
font-size: 14px;
width:30px;
}
.hidden {
font-size: 14px;
display: none;
}
<input type="text">
<span class="hidden"></span>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I have a JavaScript function that displays text based on input in a text field. When a value is entered into the text field, my program will check to see if the value is correct. If it is correct, my program displays, "You are correct!" and if it is incorrect, my program displays, "Try again!"
The text field and button are both centered horizontally on the page, but I cannot figure out how to center the "You are correct!" and "Try again!"
I feel like I have tried everything, but obviously I haven't, considering I can't get it to work.
Here is the code for my JavaScript function:
<center><p>Can you remember how many books I listed at the bottom of the page?</p></center>
<center><input id="numb"></center>
<center><button type="button" onclick="myFunction()">Submit</button></center>
<p id="demo"></p>
<div class="jsFunction">
<script>
function myFunction()
{
var x, text;
// Get the value of the input field with id="numb"
x = document.getElementById("numb").value;
// If x is Not a Number or less than five or greater than five
if (isNaN(x) || x < 5 || x > 5)
{
text = "Try again!";
}
else
{
text = "You are correct!";
}
document.getElementById("demo").innerHTML = text;
}
</script>
</div>
Here is the CSS code for the function:
.jsFunction
{
margin-left: auto;
margin-right: auto;
}
This specific CSS code is only one of many, many attempts I have made at centering the text in the function.
Here is a link to a picture that will show you the problem I am having:
http://i.stack.imgur.com/Hb01j.png
Please help!
Try setting a class on the p tag that contains text-align: center;
Edit
Nesting your script in a div is meaningless as script tags don't get rendered
You can either target #demo in your css (for the text alignment) or add a class align-center that contains the correct style.
I would recommend the latter as the becomes more reusable, whereas you can't reuse an id on the same page
The fact that you are using JavaScript isn't important to this question. I mention it because of the title "How to Center Text in a JavaScript Function" and your attempt to center the actual script element containing your JavaScript code.
You want to center the contents of an element that happens to be controlled by JavaScript, but the answer is CSS-only.
As Ryuu's answer mentions, text-align: center will do the job for (you guessed it) text and other inline-level content.
You should not use the deprecated center tag.
Your attempt to use margins will center something if you apply it to the correct element and the element has a width. That "something" is the element, however, not the contents of the element.
In other words, margin can be used to align the box, not the stuff within the box.
Example 1: centers the element, but the text is still left-aligned.
Example 2: centers the element and its inline-level contents.
.margin-example1 {
width: 200px;
background-color: #ddd;
/* shorthand for margin: 0 auto 0 auto, which is shorthand for specifying each side individually */
margin: 0 auto;
}
.margin-example2 {
width: 200px;
background-color: #aaccee;
margin: 0 auto;
/* we still need this to get the desired behavior */
text-align: center;
}
<div class="margin-example1">Example 1</div>
<div class="margin-example2">Example 2</div>
So how about a text input? Browsers usually style inputs as display:inline-block. This means we can center something inside them (Examples 1 & 2), but to center them within their container we need to change to display:block (Example 3) or because they are inline-like elements themselves, we can set text-align on the parent container (Example 4), see also.
.example1 {
width: 100%;
text-align: center;
}
.example2 {
width: 200px;
text-align: center;
}
.example3 {
display: block;
width: 200px;
text-align: center;
margin: 0 auto;
}
.example4 {
width: 200px;
text-align: center;
}
.example4-parent {
text-align: center;
}
<div>
<input type="text" value="Example 1" class="example1">
</div>
<div>
<input type="text" value="Example 2" class="example2">
</div>
<div>
<input type="text" value="Example 3" class="example3">
</div>
<div class="example4-parent">
<input type="text" value="Example 4" class="example4">
</div>
Layout in CSS can be complicated, but the basics aren't hard.
Note that I have over-simplified my explanation/definitions a bit (you can read all about the formatting model when you are ready).
I have been scratching my head since yesterday on this problem, which I cannot solve. I am a new starter to Twitter Bootstrap and everything was going well until yesterday.
I am using the latest JQuery v1.11.1 and Twitter Bootstrap v3.3.1. Yesterday I downloaded Bootstrap Tags Input, from here: http://timschlechter.github.io/bootstrap-tagsinput/examples/
The plugin works and I have changed the CSS styles to match my page layout but the problem I am having is that the placeholder attribute will not disappear when on focus. If I type in a tag and add a comma value the placeholder will show until I start typing and then it will disappear again.
I have tried using JQuery onfocus function to remove the attribute when onfocus but it doesn't do anything. What I want to achieve is that when onfocus the placeholder does not show at that point not even on blur.
My input field is demonstrated below:
<input type="text" name="customer_tags" id="customer_tags" value="" placeholder="Enter you tags" data-role="tagsinput" required />
two years later, but i found how to work around this issue. First, if you inspect the DOM , you will see a new input text, which inherits our placeholder text, but without the extra function onblur, onfocus that everybody mention before.
<div class="bootstrap-tagsinput">
<input placeholder="text inherited from our input" size="23" type="text">
</div>
Then, to fix this issue, you had to create a jquery function to point that input. Like this:
$('.bootstrap-tagsinput input').blur(function(){jQuery(this).attr('placeholder', '')})
pointing to element with the class "bootstrap-tagsinput" and then the "input" objects inside. You can add a .focus function too if you prefered. In my case, works when the user leave the object and the input tags look clean without placeholder.
HTML5 placeholder attribute will not disappear when you focus in the input tag... it will only disappear when you start typing. It is the default behavior.
You can see it # W3Schools as well...
Following code works in my case:
<input type="text" name="add_image_tags" id="add_image_tags" data-role="tagsinput"
class="form-control" placeholder="Enter tags" data-placeholder="Enter tags" value="" />
handlePlaceHolder(); //Call during page load
function handlePlaceHolder()
{
if($('#add_image_tags').val())
{
$('.bootstrap-tagsinput input').attr('placeholder', '');
}
else
{
$('.bootstrap-tagsinput input').attr('placeholder',$('#add_image_tags').attr('data-placeholder'));
}
}
$('#add_image_tags').on('itemRemoved', function(event) {
// event.item: contains the item
handlePlaceHolder();
});
$('#add_image_tags').on('itemAdded', function(event) {
// event.item: contains the item
handlePlaceHolder();
});
Try this, i hope it's working:
<form>
<div>
<label for="name" class="left-label">Your Name</label>
<input type="text" class="example-two" placeholder="Enter you tags" id="name" name="name">
</div>
</form>
CSS:
[placeholder]:focus::-webkit-input-placeholder {
transition: opacity 0.5s 0.5s ease;
opacity: 0;
}
.example-two:focus::-webkit-input-placeholder {
transition: text-indent 0.5s 0.5s ease;
text-indent: -100%;
opacity: 1;
}
body {
}
form {
display: inline-block;
margin-top: 20px;
}
label {
display: block;
text-align: left;
font: bold 0.8em Sans-Serif;
text-transform: uppercase;
}
.left-label {
float: left;
padding: 8px 5px 0 0;
}
input[type=text] {
padding: 5px;
text-indent: 0;
}
form div {
margin: 20px;
clear: both;
text-align: left;
}
JSFiddle
EDIT:
Working on IE too:
JSFiddle
That's how the plugin behaves. As soon as you hit "enter" or "comma" it creates a span tag (see image attached)and shift the input to the right. So now the input has no value and should show the placeholder.
In their docs it's mentioned [Search for confirmKeys]
Array of keycodes which will add a tag when typing in the input.
(default: [13, 188], which are ENTER and comma)
Change the confirmkeys to remove creation of tags when you type comma
Edit:
On your site I tried the below method in console and it worked.
$('input').tagsinput({
confirmKeys: [13]
});
I was able to do a quick fix using jquery. The behavior I wanted should do two things:
1) Remove placeholder while on page after I've focused and started typing. So I will run it on keyup.
$(document).on('keyup', '.bootstrap-tagsinput input', function(){
$(this).attr('placeholder', '')
})
2) If there are already labels in an input, then I don't obviously need a placeholder. I run this on page load.
$('.labels').each(function(){
var len = $(this).tagsinput('items');
if(len){
var $input = $($(this).prev().children('input').get(0));
$input.attr('placeholder', '');
}
})
In my case, after a little modification, it works fine.
$('#txtTimeSlot').on('change', function () {
var len = $(this).tagsinput('items').length;
if (len > 0) {
var $input = $($(this).prev().children('input').get(0));
$input.attr('placeholder', '');
} else {
var $input = $($(this).prev().children('input').get(0));
$input.attr('placeholder', $(this).attr('placeholder'));
}
});
for all who are still having this problem, just change the line in the javascript file:
from:
cancelConfirmKeysOnEmpty: true,
to
cancelConfirmKeysOnEmpty: false,
And thats all!