I'm using Jorn Zaefferer's Autocomplete query plugin, http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/ and I wanted to add a button that will load all the elements the same as combobox.
So, I created a method that puts a div with image as background next to an input text:
var createDownArrow = function (input, request, options) {
var defaults = {
downArrowClass: 'autocomplete_DownArrow'
};
options = $.extend({}, defaults, options);
var offset = $(input).offset();
var width = typeof options.width == 'string' || options.width > 0 ? options.width : $(input).width();
var element = $('<div/>').addClass(options.downArrowClass).appendTo(document.body).
css({ position: 'absolute', top: offset.top, left: offset.left + width}).click(function () {
if (request && typeof request == 'function') {
request();
}
});
};
the input text has the following css:
border: 1px solid #888888;
height:15px;
font-weight: normal;
font-size: 12px;
font-family: Arial (Hebrew);
padding:0px;
margin:0xp;
this is the div css:
background-image:url(drop.jpg);
background-position:top right;
height:17px;
width:17px;
cursor:pointer;
and using this function on the input in the html:
<br /><br /><br /><br />
<input type="text" id="test" />
I get the result:
Which you can see is not the desire result.
How can I align the div next to the input? (I am using direction:rtl)
try enclosing in label tag
<label for="in"><img src=" " /><input name="in" /></label>
Write up your example that statically includes the arrow at all times in the html. When that works, replace the arrow's html by javascript that can generate it, and you'll be fine.
In more detail, I think you've got a problematic approach; you should use the right tool for the right job. So while it's possible to do what you want by manual positioning, you really don't want to be getting into this quagmire: Javascript is a poor tool for this. You probably can't get around using some javascript, but your life will be much easier if you do as much as possible in HTML+CSS - tools explicitly made for layout. In particular, that means making your arrow button statically first, and then adding exactly the html that works to the DOM-tree, rather that trying to manually control layout by computing width+height+position of the input; which you're almost certainly going to get wrong (not to mention when things get tricky, e.g. with overflow:scroll and the like).
Oh, and you could get rid of the <br/> tags and simply make the input display:block with a margin-top.
One possible CSS approach would be to follow the button by width-0 span (inline element) containing a position absolute (don't affect layout) block that shows whatever you want. E.g.: http://jsfiddle.net/emn13/nvY2F/
To get this to work as a plugin, you'd write javascript to create the span and div in the html; preferably the css would be in a linked stylesheet, but you could use inline styles too, of course. The CSS transitions are just for fun, of course.
In order to solve this, I canceled the absolute position and added display:inline-block to the div. Then I just inserted in before the input and thats all.
Related
Newbie CSS question. I thought width:auto for a display:block element meant 'fill available space'. However for an <input> element this doesn't seem to be the case. For example:
<body>
<form style='background:red'>
<input type='text' style='background:green; display:block; width:auto'>
</form>
</body>
Two questions then:
Is there a definition of exactly what width:auto does mean? The CSS spec seems vague to me, but maybe I missed the relevant section.
Is there a way to achieve my expected behavior for a input field - ie. fill available space like other block level elements do?
Thanks!
An <input>'s width is generated from its size attribute. The default size is what's driving the auto width.
You could try width:100% as illustrated in my example below.
Doesn't fill width:
<form action='' method='post' style='width:200px;background:khaki'>
<input style='width:auto' />
</form>
Fills width:
<form action='' method='post' style='width:200px;background:khaki'>
<input style='width:100%' />
</form>
Smaller size, smaller width:
<form action='' method='post' style='width:200px;background:khaki'>
<input size='5' />
</form>
UPDATE
Here's the best I could do after a few minutes. It's 1px off in FF, Chrome, and Safari, and perfect in IE. (The problem is #^&* IE applies borders differently than everyone else so it's not consistent.)
<div style='padding:30px;width:200px;background:red'>
<form action='' method='post' style='width:200px;background:blue;padding:3px'>
<input size='' style='width:100%;margin:-3px;border:2px inset #eee' />
<br /><br />
<input size='' style='width:100%' />
</form>
</div>
"Is there a definition of exactly what width:auto does mean? The CSS
spec seems vague to me, but maybe I missed the relevant section."
No one actually answered the above part of the original poster's question.
Here's the answer:
http://www.456bereastreet.com/archive/201112/the_difference_between_widthauto_and_width100/
As long as the value of width is auto, the element can have horizontal
margin, padding and border without becoming wider than its container...
On the other hand, if you specify width:100%, the element’s total
width will be 100% of its containing block plus any horizontal margin,
padding and border... This may be what you want, but most likely it isn’t.
To visualise the difference I made an example:
http://www.456bereastreet.com/lab/width-auto/
ORIGINAL answer using Angular: Because input's width is controlled by it's size attribute, this is how I initialize an input width according to its content:
<input type="text" class="form-list-item-name" [size]="myInput.value.length" #myInput>
UPDATE for JavaScript (10/01/2022): My original answer was from the time I was studying Angular. If you need pure, Vanilla JavaScript the solution is even simpler:
<input type="text" oninput="this.size = this.value.length">
Or add an "input" event listener to your input html element and run a code like this:
const myInput = document.querySelector('input');
myInput.addEventListener('input', this.typing);
(...)
typing(e) {
e.target.setAttribute('size', e.target.value.length);
}
Obs: Depending on the browser, input may restore to its default size of something between 150px and 250px if/when size gets the 0 value. In this case, just add +1 to value.length:
<input type="text" oninput="this.size = this.value.length + 1">
OR:
typing(e) {
e.target.setAttribute('size', e.target.value.length + 1);
}
As stated in the other answer, width: auto doesn't work due to the width being generated by the input's size attribute, which cannot be set to "auto" or anything similar.
There are a few workarounds you can use to cause it to play nicely with the box model, but nothing fantastic as far as I know.
First you can set the padding in the field using percentages, making sure that the width adds up to 100%, e.g.:
input {
width: 98%;
padding: 1%;
}
Another thing you might try is using absolute positioning, with left and right set to 0. Using this markup:
<fieldset>
<input type="text" />
</fieldset>
And this CSS:
fieldset {
position: relative;
}
input {
position: absolute;
left: 0;
right: 0;
}
This absolute positioning will cause the input to fill the parent fieldset horizontally, regardless of the input's padding or margin. However a huge downside of this is that you now have to deal with the height of the fieldset, which will be 0 unless you set it. If your inputs are all the same height this will work for you, simply set the fieldset's height to whatever the input's height should be.
Other than this there are some JS solutions, but I don't like applying basic styling with JS.
It may not be exactly what you want, but my workaround is to apply the autowidth styling to a wrapper div - then set your input to 100%.
If you're willing to include a little JavaScript to solve this, you can get exact sizing. This doesn't rely on approximating width with size or ems, doesn't rely on any hardcoded element widths, and works for e.g., type="number", which don't accept a size attribute.
The trick is to get your input sized exactly like a span with the same content, by actually having an invisible span with the same content.
Put your input inside a div along with a span that mirrors the input's value. Give both the input and the span the same styling, give the input 100% width, then hide the span and absolute-position the input to sit on top of the span.
This way, the container (and thus the input) are automatically sized by the visual appearance of the content of the invisible span.
https://codepen.io/spiffytech/pen/abwWRqo
<div id="relative-parent">
<span id="size-calibration"></span>
<input id="autosized-input" />
</div>
<style>
#relative-parent {
position: relative;
/* Have some width if the input is empty */
min-width: 1em;
/* Adjust size to match the span */
width: min-content;
}
#size-calibration {
visibility: hidden;
/* Prevent the span from wrapping the text when input value has multiple words, or collapsing multiple spaces into one */
white-space: pre;
}
#autosized-input {
position: absolute;
left: 0;
width: 100%;
}
#size-calibration, #autosized-input {
/* Normalize styles that the browser sets differently between spans and inputs.
Ideally, use a "CSS reset" here. */
font-family: "Arial";
padding: 0;
/* Demonstrate that this works for input with custom styles */
font-size: 24px;
}
</style>
<script>
function updateSize() {
const span = document.getElementById('size-calibration');
const input = document.getElementById('autosized-input')
span.innerText = input.value;
}
document.addEventListener('DOMContentLoaded', () => {
const input = document.getElementById('autosized-input');
input.oninput = updateSize;
// Provide some initial content
input.value = "I'm sized exactly right!"
updateSize();
})
</script>
After tried methods all above and failed, I workaround by modifying width property in style by unit em:
tgt.style.width = `${(tgt.value.length + 1) / 2}em`
The only option I can think of is using width:100%. If you want to have a padding on the input field too, than just place a container label around it, move the formatting to that label instead, while also specify the padding to the label. Input fields are rigid.
Answer 1 - "response" gave a nice answer/link for it. To put it in short, "auto" is the default, so it is like removing any changes in the width of an element
Answer 2 - use width: 100% instead. It will fill the 100% of the parent container, in this case, the "form".
Using JQuery
$(document).on('input', '.input-fit-width', (e) => {
$(e.currentTarget).attr('size',e.currentTarget.value.length);
})
Nowdays, flex or grid makes it much easier , it overrides default style/behaviors of https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input#size which has a default value set at 20 see : https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Input#size
Giving you 2 plain CSS options without requiring JavaScript nor setting width to 100% and deal with box-sizing.
flex/flex-grow
<form style='background:red;display:flex;'>
<input type='text' style='background:green; flex-grow:1'>
</form>
grid
<form style='background:red;display:grid;'>
<input type='text' style='background:green;'>
</form>
Jquery way of adjusting size of input automatically.
In general:
$('#my_input_id').width( ($('#my_input_id').val().length) + "ch" );
On text input:
$(document).on("input", '#my_input_id', function () {
$(this).width( ($(this).val().length) + "ch" );
});
I think the simplest solution is to set parent element's width:
form{
width: 100%!important;
}
I am building a lean & clean html/js-based text editor similar to Medium's writing tool. I use contenteditable to make divs editable.
I'd like to add inline markup for text links (e.g. typing [[Google|https://www.google.com]] instantly converts into <a href='https:www.google.com'>Google</a>, i.e. Google). All this should happen on the fly, i.e. while typing. That is, when the user types the second closing ] of the link markup or the cursor focus is set outside of a [[text|url]] element, JS recognizes this event and instantly converts the [[text|url]] into a html link. On the other hand, if the focus is set on an existing text link (i.e., inside an <a>...</a> html tag within the editable div, (1) the link's default opening behavior is blocked and (2) the text link is instantly converted back into the markup version for editing (e.g., Google becomes [[Google|https://www.google.com]]).
I am not very familiar with regex in JS. Any idea how this can be done?
Thanks very much for your help.
PS: I use jQuery 1.11.0
PSS: The disired behavior is somewhat similar to this text editor's when backspacing into a link (deleting ] converts the link into the markup version and typing the closing ] converts the markup version into a link). The difference is that I am not separating the writing field from the shown text, everything happens inline.
Check out this fiddle.
It is just a sample.
It converts [[Google|https://www.google.com]] to <a href='https://www.google.com'>Google</a>, i.e. Google.
I used this Regular Expression to detect the inline markup.
It has some bugs, but I think it will help you to implement what you need.
Here is the snippet.
$('.editor').keyup(function(e) {
if (e.keyCode === 221) {
var text = $('.editor').html();
var match = /\[\[(.+)\|(https?:\/\/.*\..+)\]\]/g.exec(text);
if (match !== null) {
text = text.replace(match[0], "<span><a href='" + match[2] + "'>" + match[1] + "</a></span>");
$('.editor').html(text);
}
}
});
.editor {
position: absolute;
border: black dashed 2px;
left: 5%;
right: 5%;
top: 10%;
bottom: 10%;
padding: 15px;
font-family: 'Lucida Console';
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="editor" contenteditable='true'>This is the Editor. write something here.</div>
On a page I'm working on, the results of the Google Places Autocomplete is showing up 70px below where it should, leaving a gap between the search box and the beginning of the results container.
The height of the gap happens to be the exact height of Chrome's autofill feature, so I'm suspicious that the Autocomplete library is for some reason taking that height into account when calculating the position, even though I've managed to disable that feature on my search box.
I'm able to fix the problem by overriding the value of the top attribute of the .pac-container class (replacing the value of 1234px which the API has calculated with 1164px), but I would rather have a way to do this dynamically or just based on an offset than have to hard-code that number.
Is there a way, with CSS or JavaScript/jQuery, to move the Autocomplete results container up by a certain amount?
A list of the CSS classes involved in the Autocomplete box can be found in Google's documentation.
I have tried many approaches and the best thing so far that worked for me is the good old (negative) margin.
I wanted the resulting menu to be shown on top and I did this:
<style type="text/css">
.pac-container{
margin-top: -210px;
}
</style>
Yes, you can style the Autocomplete
https://google-developers.appspot.com/maps/documentation/javascript/places-autocomplete#style_autocomplete
However, lets look at WHY the "gap" is happening.
Double check your HTML and BODY tags, see if they have margin/padding added to them
So, the way Autocomplete detects it's position is by calculating the X/Y from the top/left of the BODY tag. I had this same problem (autocomplete had a big gap between the result box and the field), I discovered that my CMS system was adding a 30px margin to the BODY tag for the admin bar, this pushed the Autocomplete box down by 30 pixals... (the real problem)
html, body{margin:0 0 0 0;}
and the autocomplete vertical position was proper and the gap was gone without any odd JS scripting...
The below snippet worked for me.
In this initially, it will remove the previous pac-container div anywhere in the DOM. Later on, It tries to find the pac-container div element inside autocomplete object and it will place pac-container the div element inside another div in this case it is "book-billing-address"
$(".pac-container").remove();
autocomplete = new google.maps.places.Autocomplete(input);
if(id_val == 'payment-address'){
setTimeout(function(){
if(autocomplete.gm_accessors_ != undefined){
var container_val = autocomplete.gm_accessors_.place.qe.gm_accessors_.input.qe.H
autocomplete.gm_accessors_.place.qe.gm_accessors_.input.qe.H.remove();
$('#book-billing-address').append(container_val);
}
}, 100);
}
and applied the following CSS, when div element moved inside book-billing-address div.
#book-billing-address .pac-container{
position: absolute !important;
left: 0px !important;
top: 36px !important;
}
please check parent element of searchbox, if parent element has margin-top, then convert it into padding-top
example code
`
.parent_element {
/* margin-top: 70px; */
padding-top: 70px;
}
</style>
<div class="parent_element">
<input type="text" class="autocomplete">
</div>`
I hope will work for you :)
It's perfectly work for me , no issue with position bug when scroll
function initAutocomplete() {
//....codes...
//....add this code just before close function...
setTimeout(function(){
$(".pac-container").prependTo("#mapMoveHere");
}, 300);
}
https://codepen.io/gmkhussain/pen/qPpryg
Add css on body tag with position: relative
It worked.
I'm a beginner web designer, and though I would try my hand at JavaScript and jQuery. After looking around W3Schools for a bit, I tried to make a simple jQuery animation, but it doesn't seem to work.
<html>
<head>
<script type="text/javascript" src="jQuery.js"></script>
<script>
$(document).ready(function(){
$("#name").blur(funtion(){
if(value==null || value==""){
$("#name").animate({background:#D23E42}, "slow");
}
});
});
</script>
<style type="text/css">
body
{
font-family: Arial;
}
#name
{
background:#6BAA64;
color: #FFFFFF;
border:2px none;
padding:5px;
-webkit-border-radius:8px 8px;
-moz-border-radius:8px 8px;
border-radius:8px 8px;
text-align: center;
}
</style>
</head>
<body style="text-align: center;">
Name:
<br />
<input id="name" type="text" value="Your Name" />
</body>
</html>
I was just trying to setup a simple contact/registration form model, so when the name field was left empty, or wasn't changed, would turn red (on blur).
You got many mistakes in that code:
$("#name").blur(function() {
if (!this.value) {
$(this).css('background-color', '#D23E42');
}
});
Mistakes:
funtion => function
value => this.value.
The value of an input can never be null, it can be only an empty string.
animate => css, and the reason is that you can't animate background-color changes without a plugin.
the color needs to be a string #D23E42 => '#D23E42'
background => background-color.
$("#name") => $(this)
It might be a good idea to stop learning at w3school as it doesn't seem to pay off...
Sorry but you can't animate background, unless you use jColor
From the docs:
All animated properties should be animated to a single numeric value,
except as noted below; most properties that are non-numeric cannot be
animated using basic jQuery functionality (For example, width, height,
or left can be animated but background-color cannot be, unless the
jQuery.Color() plugin is used).
jQuery.animate cannot animate background colours, but only properties like width, height, left, top etc. To animate background colours, you'll have to use a plugin like https://github.com/jquery/jquery-color
You have two mistakes:
The color value is a string, so you need quotes around "#D23E42". Otherwise you're probably seeing a syntax error.
JQuery doesn't actually animate colors anyway. There's a plugin that claims to add this feature though I haven't tried it out:
http://www.bitstorm.org/jquery/color-animation/
jsBin demo
$("#name").focusout(function(){
var value = $.trim($(this).val());
if(value === ''){
$(this).animate({backgroundColor:'#D23E42'}, 500);
}
});
In this demo I used the jQuery UI library to achieve the background fade color.
Use .focusout()
Use $.trim() to prevent empty spaces being accepted as valid input
Always use === to compare values
EDIT
Hede is a demo without the UI
You surely need to redo the color if the user reenter some text:
$("#name").focusout(function(){
var value = $.trim($(this).val());
if(value === ''){
$(this).css({background:'#D23E42'});
}else{
$(this).css({background:'#6BAA64'});
}
});
Demo without the UI library
I'm trying emulate the MS-DOS command prompt on my website. I don't need to accept keystrokes, but I'd like to append data at the bottom and optionally scroll upwards.
At first I looked at the asp:TextBox and asp:Label, but the flicker of using postbacks seemed to be too much. I'm now considering DIV tags and Javascript where I simply update the InnerHTML property, but there too I get flicker, and have issues with scrolling.
What solution would you recommend in this situation? Essentially I'm trying to count to infinity, with a 1 sec delay, only need the most current 300 or so entries, with the most current entry at the bottom of the screen.
Is this even possible with JS/CSS?
Do you wish to make it a little more stylous ? :)
see this page...
http://www.klaus.dk/Some_unknown_page
or this one
http://www.harryovers.com/404.html?aspxerrorpath=/Account/LoginPartial
here is the javascript source code.
http://code.google.com/p/c64-404-page/
With a little change, you can append your text on this code :)
I just built something very similar using jQuery. You can use the append method to add content to the bottom of your DIV. You can then set the scrollTop attribute to keep things scrolled to the bottom as follows:
$("#someDiv").attr({ scrollTop: $("#someDiv").attr("scrollHeight") });
I think "DOS-style window" is a bit misleading considering all you want to do is append text to a div and make sure it stays scrolled to the bottom.
function addLine(text) {
var box = document.getElementById('DOSBox') //teehee
var line = document.createElement('p');
line.innerHTML = text;
box.appendChild(line);
box.scrollTop = box.scrollHeight;
}
And style it as such
#DOSBox {
overflow: auto;
display: block;
height: 400px; width: 500px; /* or whatever */
/* and if you want it to look DOS-like */
background: #000;
color: rgb(192, 192, 192);
font-family: fixedsys;
}
#DOSBox p {
margin: 0;
}