Bizarre IE glitch when simulating input=file click using jQuery - html

I 'crafted' this piece of jQuery + html to accomplish the following:
There is a placeholder image that user can click, which causes a file selection dialog to open. Once a file is selected, the corresponding multipart form is uploaded to the server. I am trying to imitate AJAX behavior for this file upload, so I also use an invisible iframe to receive server response.
Let me present the code first, so it would be easier to explain the problem
jQuery("#myInput").change(function () { // Submit form upon file selection
// alert("myInput.val() = " + $('#myInput').val()); // alert 1
$('#form1').submit();
// alert("myInput.val() = " + $('#myInput').val()); // alert 2
});
<form id="form1" action="/do_upload.php" method="post" enctype="multipart/form-data" target="target_frame">
<input id="myInput" type="file" name="userfile" /><br>
</form>
<img src="/img/placeholder.png" onclick="$('#myInput').click();" >
<iframe id="target_frame" name="target_frame" src="#" style="width:0;height:0;border:0px solid #fff;"></iframe>
The code works perfectly on new Chrome/Firefox/Safari. (Interestingly it even works if I set visibility: hidden; on myInput. So apparently that's not much of a security concern). However both IE 9 and 10 show the same behavior: clicking the image brings up the dialog successfully, the file path is correctly set in "alert 1", but it is gone in "alert 2", and the form doesn't get submitted. On the other hand, clicking directly on the browse button of myInput properly brings up the dialog and submits the form.
I am absolutely confused by how this behavior can even be possible! Any suggestions on how to fight off the annoying IE would be greatly appreciated :)

I believe it is a safety feature of IE. it won't allow you to access the name attribute of the file input if using another trigger.
You must click the file input for IE and not use another trigger.
Edit: A workaround IE clears input[type="file"] on submit

I decided to go with the method of overlaying a transparent file element over my image. My inspiration came from this page: https://coderwall.com/p/uer3ow. Here is my HTML and CSS that were required:
.file_loader {
position: relative;
overflow: hidden;
border: solid gray 1px;
margin: auto;
width: 300px;
height: 400px;
}
.file_loader .hidden_file {
display: block;
background: white;
font-size: 80px;
height: 100%;
width: 100%;
opacity: 0;
position: absolute;
top: 0;
left: 0;
}
.placeholder {
height: 100%;
width: 100%;
}
<div class="file_loader">
<img src="/img/placeholder.png" id="placeholder1" class="placeholder" >
<form id="form1" action="/do_upload.php" method="post" enctype="multipart/form-data" target="target_frame">
<input id="myInput" class="hidden_file" type="file" name="userfile" /><br>
</form>
</div>
As you can see the height and width of the "file_loader" class enforce the dimensions of the placeholder image and of the transparent input=file element overlay. There is one thing in this CSS that is truly brilliant, and it came from that link. I'm talking about setting the very large font-size for file element. It is key for making it work in IE, because it happens to make the "Browse" button so gigantic that it fills the whole placeholder. Without changing the font-size, in IE you would end up with only part of the image being able to bring up file dialog (the rest would be a transparent text field). I'll point out that in Chrome/Firefox/Safari this font-size trick is unnecessary, as the whole file element is clickable there.

Related

HTML time input type - how to let select time menu view when click anywhere not only clock icon click

I working on time input type in html , my problem is when i click on small clock icon on the right side of input ,selectable time menu viewed but i need to show it when i click anywhere on input .
I found this question but this not solve my problem because it's about timepacker not html only .
show timepicker on click whole input type time HTML5 field not only on little clock icon
HTML :
<label for="first" class="">{{__('From Hour')}}</label>
<input type="time" class="form-control input-md"name="" id="from_hour" value="">
Credit to #StepPen-codes at How To Open HTML Date Picker Dialog On Click Anywhere Inside Input?
You can use CSS to do the trick. It works but in my case, the calendar icon disappears. I try to bring it back but the position isn't nice.
input#session-date::-webkit-calendar-picker-indicator{
display:block;
top:0;
left:0;
background: #0000;
position:absolute;
transform: scale(12)
}
For me, adding onfocus="this.showPicker()" attribute on the time input solved the problem.
source:
https://stackoverflow.com/a/72627382/10414071
This style works fine in my case:
input[type="time"] {
position: relative;
}
input[type="time"]::-webkit-calendar-picker-indicator {
display: block;
top: 0;
right: 0;
height: 100%;
width: 100%;
position: absolute;
background: transparent;
}

Is it possible to put "default TEXT" in "CSS style file"?

I need this "default text" in my CSS file, for example to an <input> tag and to a <textarea>,
so I search for something like:
<style>
testcss{
default:"DefaultText";
or
value:"DefaultText";
}
</style>
So, here is my question,
I have several <input> in my form, and I need to set them all "same default value"! for example same "placeholter" ou same "value" and, I need this by CSS <style>!
You can use javascript
var inputs = document.getElementsByTagName('input');
for (i = 0; i < inputs.length; i++) {
inputs[i].value = "Default Text";
}
Yes it is possible, with a <label> placed behind the input using z-index and a transparent background-color on the <input>. Use :focus to change to a white background. Use :valid :invalid that the placeholder don't shine through if text is entered. With .input:before your "styling" the content of the label. :first-line has sometimes some Firefox issues. With my Firefox for mac it worked with this code.
HTML
<label class="input"><input type="text" required="required"/></label>
CSS
.input {
color: gray;
display: block;
font-size: small;
padding-top: 3px;
position: relative;
text-indent: 5px;
}
input {
background-color: transparent;
left: 0;
position: absolute;
top: 0;
z-index: 1;
}
input:focus, input:first-line {
background-color: white;
}
.input:before {
content: "Some CSS Text";
}
input:valid { background-color:white; }
input:invalid{ background-color:transparent; }
Screenshot (chrome browser)
without Text
without text and focus
with text and focus
with text in it.
See https://jsfiddle.net/uueojg2g/1/ for testing.
Summary
Would I recommend using css for your task? Perhaps not, cause you should use css for presentation only. So I would always to try to get a html variant with placeholder
How it works with "pure" html
Preferred method, and works in all current browsers:
<input type="text" name="" placeholder="Full Name"/>
For IE9 and before, we just need some javascript:
<input type="text" name="" value="Full Name" onfocus="value=''" onblur="value='Full Name'"/>
Remember to use html for content and css for presentation.
So you could actually do that inside of inside of html input tag by using value attribute:
<input value="default text">
As for the text area, you put the default value in between the tags:
<textarea> default text </textarea>
You can use javascript or jquery to make it more convenient, like making the default text disappear when user clicks on textarea, or input element, but that is out of the scope of this question.

tabIndex doesn't make a label focusable using Tab key

I'm trying to replace checkbox/radio inputs with icons. For this, I need to hide the original checkbox/radio. The problem is, I also want the form to properly support keyboard input, i.e. let the input remain focusable by Tab key and selectable using Spacebar. Since I'm hiding the input, it cannot be focused, so instead, I'm trying to make its <label> focusable.
This documentation and various other sources led me to believe I can do that using tabindex attribute (corresponding to HTMLElement.tabIndex property). However, when I try to assign tabindex to my label, it remains as unfocused as ever, however much I try to Tab to it.
Why doesn't tabindex make the label focusable?
The following snippet demonstrates the issue. If you focus the input with your mouse and try focusing the label using Tab, it doesn't work (it focuses the following <span> with tabindex instead).
document.getElementById('checkbox').addEventListener('change', function (event) {
document.getElementById('val').innerHTML = event.target.checked;
});
<div>
<input type="text" value="input">
</div>
<div>
<label tabindex="0">
<input type="checkbox" id="checkbox" style="display:none;">
checkbox: <span id="val">false</span>
</label>
</div>
<span tabindex="0">span with tabindex</span>
(The JavaScript code just allows to see that clicking on the label properly (un)checks the checkbox.)
Why doesn't tabindex make the label focusable?
Short Answer:
Label is focusable.
TabIndex won't make any difference.
Welcome to the world of browser/agent inconsistencies.
tl;dr;
The label (Ref) element is very much focusable. Its DOM Interface is HTMLLabelElement which derives from HTMLElement (Ref) which in turn implements GlobalEventHandlers (Ref) and hence exposes the focus() method and onfocus event handler.
The reason you are unable to get hold of proper specification / reference document for labels focus behaviour, is because you might have been looking at HTML5 Specs. Interestingly, HTML5 refs do not state anything relating to that, which adds to the confusion.
This is mentioned in the HTML 4.01 Ref here: http://www.w3.org/TR/html401/interact/forms.html#h-17.9.1
Specifically near the end of section 17.9.1 and just before 17.10:
When a LABEL element receives focus, it passes the focus on to its
associated control.
Also, elsewhere (I am unable to get hold of that part of the ref) I have read that it depends on the implementing agent. (Don't take my word for that, am not too sure).
However, what it means is that when you focus a label (or a label received a focus), that focus is passed on to its associated labeleable control. This will not result in two different focuses, but one focus on the input (in your case a checkbox). Because of this behaviour, tabindex property cannot play a role.
There is also a test suite by W3C for website accessibility (WAAG) here: http://www.w3.org/WAI/UA/TS/html401/cp0102/0102-ONFOCUS-ONBLUR-LABEL.html which, discusses the implementation of onfocus and onblur for a label. Ideally a keyboard or an assistive technology that emulates the keyboard should implement this. But...
This is where the browser inconsistencies play their role.
This can be demonstrated by this example. Check the following snippet in different browsers. (I have tested it against IE-11, GC-39 and FF-34. All of them behave differently.)
Click the button "Focus Label"
It should focus the label, then pass the focus and highlight its associated checkbox outline in blue.
Chrome-v39 works. IE-v11 it doesn't (somehow html and body do respond to :focus). FF-v34 it works.
Talking about browser inconsistencies, try using the "access key" L. Some browsers will focus the checkbox whereas some will click it i.e. pass the action to it.
Here is a fiddle to test it: http://jsfiddle.net/abhitalks/ff0xds4z/2/
Here is a snippet:
label = $("label").first();
$("#btn").on("click", function() {
label.focus();
});
* { margin: 8px; }
.highlight { background-color: yellow; }
:focus {
outline: 2px solid blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="txt" type="text" value="input" /><br />
<label for="chk" accesskey="L">Checkbox: </label>
<input id="chk" type="checkbox" /><br />
<input id="btn" type="button" value="Focus Label" />
Hope that clears up your doubts.
.
Your problem:
Now focussing (sic) on your original problem of not being able to focus a label, because you want to style a checkbox differently by placing an icon kind of thing in its place.
In order to do that, one option for you is to not hide it completely by doing a display:none;. Rather, make it 1x1 pixel and shove it under your icon. This way it will still receive focus naturally and yet be effectively hidden.
For example, if your icons are a checkmark and a cross, then change the position of the checkbox and make the icons out of ::before or ::after pseudo-elements on the label. That will cause the checkbox to still receive focus, and make the icon respond to that. That will give the apparent illusion of the icon taking the focus.
Demo Fiddle: http://jsfiddle.net/abhitalks/v0vxcw77/
Snippet:
div.chkGroup { position: relative; }
input#chk {
position: absolute;
width: 1px; height: 1px;
margin: 0; margin-top: 4px; outline: none;
border: 1px solid transparent; background-color: transparent;
}
label::before {
content: '\2714';
position: relative;
width: 18px; height: 18px;
background-color: #fff;
margin-right: 8px; padding: 2px;
display: inline-block;
border: 1px solid transparent;
}
input#chk:checked + label::before {
content: '\2716';
}
input#chk:focus + label::before {
border: 1px solid #00f;
}
<input id="txt" type="text" value="input" /><br /><br />
<div class="chkGroup">
<input id="chk" type="checkbox" />
<label for="chk" accesskey="L">Checkbox</label>
</div>
.
Since this old post is one of the top google results for html label tabindex I want to add my very simple working solution. As #Abhitalks mentioned in the accepted answer, the focus of a label is passed to it's associated control. So to bypass this behavior, just add a tabindex to the label and use event.preventDefault() in a focus EventListener.
#Heretic Monkey kind of had the right idea in his answer but you don't need a wrapper element to achieve this. You will, however, need to manually forward any required keystrokes (like spacebar) through.
For example:
'use strict';
let field = document.getElementById('hidden-file-chooser');
let label = document.querySelector('label[for=hidden-file-chooser]');
// prevent focus passing
label.addEventListener('focus', event => {
event.preventDefault();
});
// activate using spacebar
label.addEventListener('keyup', event => {
if (event.keyCode == 32) {
field.click();
}
});
#hidden-file-chooser {
display: none;
}
input[type=text] {
display: block;
width: 20rem;
padding: 0.5rem;
}
label[for=hidden-file-chooser] {
display: inline-block;
background: deepskyblue;
margin: 1rem;
padding: 0.5rem 1rem;
border: 0;
border-radius: 0.2rem;
box-shadow: 0 0 0.5rem 0 rgba(0,0,0,0.7);
cursor: pointer;
}
<input type="text" placeholder="Click here and start tabbing through ...">
<input id="hidden-file-chooser" type="file">
<label for="hidden-file-chooser" tabindex="0"> Select a File </label>
<input type="text" placeholder="... then shift+tab to go back.">
P.S: I used input[type=file] in my example because that's what I was working on when I ran across this issue. The same principles apply to any input type.
Edit: The following was a misreading of the spec:
Looking that the full
specification,
you'll see that there is something called tabindex focus
flag,
which defines if the tabindex attribute will actually make the field
"tabbable". The label element is missing from that list of suggested
elements.
But then again, so is the span element, so go figure :).
That said, yYou can make the label text focusable by wrapping the whole thing in an another element, or using some JavaScript to force the issue. Unfortunately, wrapping (here in an anchor) can men a fair amount of extra work in CSS and JS to get working like a normal label element.
document.getElementById('checkbox').addEventListener('change', function(event) {
document.getElementById('val').innerHTML = event.target.checked;
});
document.getElementsByClassName('label')[0].addEventListener('click', function(event) {
event.target.getElementsByTagName('label')[0].click();
event.preventDefault();
});
document.getElementsByClassName('label')[0].addEventListener('keypress', function(event) {
if ((event.key || event.which || event.keyCode) === 32) {
event.target.getElementsByTagName('label')[0].click();
event.preventDefault();
}
});
.label,
.label:visited,
.label:hover,
.label:active {
text-decoration: none;
color: black;
}
<div>
<input type="text" value="input">
</div>
<div>
<a class="label" href="#">
<label tabindex="0">
<input type="checkbox" id="checkbox" style="display:none;">checkbox: <span id="val">false</span>
</label>
</a>
</div>
<span tabindex="0">span with tabindex</span>
As previous posters said:
Label focus always goes directly to the input element.
Quite an annoyance if somebody has fancy (but fake) checkboxes, hiding the original ones, with an actual focus for keyboard navigation nowhere to be seen.
best solution I can think of: javascript.
Style-away the actual focus, in favor of a fake one:
input[type=checkbox]:focus {
outline: none;
}
.pseudo-focus {
outline: 2px solid blue;
}
and watch for changes on the (in many scenarios visibly hidden) original checkbox:
$('input[type=checkbox')
.focus( function() {
$(this).closest('label').addClass('pseudo-focus');
})
.blur( function() {
$(this).closest('label').removeClass('pseudo-focus');
});
Full jsfiddle here.
For input type radio or checkbox:
opacity: 0;
height: 0;
width: 0;
min-height: 0;
line-height: 0;
margin: 0;
padding: 0;
border: 0 none;
and the Js above does the trick sweetly.

Set div size of its background image

Is it possible with CSS/HTML to resize some box to match exactly it's background image size? Without using javascript.
For instance let's say I have a simplest div:
<div class="image">TEST</div>
.image {
background-image: url(http://placehold.it/350x150);
width: 350px;
height: 150px;
}
And I would like to resize it to those 350x150 dimensions without hardcoding those values. Also I cannot put any content inside this div.
http://jsfiddle.net/5Dane/
EDIT: I see a lot of answers I already was aware of, thank you for them, but that's not the solution here unfortunately. Below I'm explaining why I need such functionality.
What I'm trying to do is a form with steps (buttons previous and next). In session I hold all the values the user has input but there are some buttons which will add more functionality for the user (like multiple dynamically added rows for data). I'm doing it with jQuery of course, but I want the form to be able to work when there is no java script enabled.
Now to the point - I was trying to find out how to tell the difference which button the user has clicked. The case is all my submit buttons need to be images and the simplest solution <input type="image"/> doesn't send info about the button clicked with POST data. That's why I came to this solution:
<input class="submit_img" type="submit" style="background-image:url(http://placehold.it/108x23); width:108px; height: 23px;" value=" " name="some" />
/* Submit button with image */
input.submit_img {
font-size: 1em;
border-radius: 0px;
box-shadow: rgba(0, 0, 0, 0.15) 0 1px 1px;
border: solid 0px #000000;
cursor: pointer;
}
http://jsfiddle.net/XRvqV/
This way my form will submit all the data AND I will know which button the user clicked. Also the button looks fine, like it should look. I was wondering though if it was possible to make it a little more portable - my buttons all have different widths for different functions. Can someone suggest another approach here?
No, you can't. CSS is not aware of the the image size. You can do it easily with JQuery.
JQuery exmaple
$(function(){
var bg = $("div.image").css('background-image');
bg = bg.replace('url(','').replace(')','');
var newImg = new Image();
newImg.src = bg;
$("div.image").css("width",newImg.width);
$("div.image").css("height",newImg.height);
});
This is a hack and doesn't use background-image (uses an img tag instead), but is the only way I can think of without using JS.
HTML
<div class="container">
<div class="image">
<img src="http://www.pandafix.com/pandafix/images/untitled_1.jpg"/>
</div>
<div class="content">
some text
<br/>
some more text
<br/><br/><br/><br/>
text text text
</div>
</div>
CSS
.container {
position: relative;
}
.content {
position: absolute;
height: 100%;
width: 100%;
top: 0;
left: 0;
color: red;
}
Basically, you allow an img tag to determine the height and width of a container. Then, overlay whatever content you want on top of the image (I'm assuming you want to put something on top).
jsFiddle
i would suggest you a alternative way to solve your problem. if you use bootstrap you can involve a div to make resizable image.
<div class="img-responsive">
<img src="test.jpg" width='xxx' height='yyy' alt='test'>
</div>
You can't do that using just HTML. But you can do this using HTML!
You should try this:
background-size: values;
This way, you will resize the background-image to the size of the container!
You can't do it directly.
The only solution it would be fetching the BG of the DIV element and attach new DOM img element to the DOM node, afterwards you could use the info of the image to add the proper with and height..
if you are willing to use jquery you can do this.
$(function(){
$('.image').each(function(index,element){
var _t = $(this);
_t.data("LinkedImg","LinkedImage"+index);
$('body').append(
$('<img />',{
id:"LinkedImage"+index,
src:_t.css('background-image')
}).hide());
});
$('document').on('load',function(){
$('.image').each(function(index,element){
var _t = $(this);
var _tmp_img = $('#'+ _t.data("LinkedImg"));
_t.css({
width:_tmp_img.width(),
height: _tmp_img.height()
});
});
});
})

Firefox does not show tooltips on disabled input fields

Firefox doesn't display tooltips on disabled fields.
The following displays tooltip in IE/Chrome/Safari except Firefox:
<input type="text" disabled="disabled" title="tooltip text."/>
Why doesn't Firefox display tooltip on disabled fields? Is there a work around this?
Seems to be a (very old, and very abandoned) bug. See Mozilla Bugs #274626 #436770
I guess this could also be explained as intended behaviour.
One horrible Workaround that comes to mind is to overlap the button with an invisible div with a title attribute using z-index; another to somehow re-activate the button 'onmouseover' but to cleverly intercept and trash any click event on that button.
I guess you are using some frameworks like bootstrap. If so, it add pointer-events: none to the 'disabled' element, so all the mouse events are ignored.
.btn[disabled] {
pointer-events: auto !important;
}
can fix the problem.
You can work around this with jQuery code like:
if ($.browser.mozilla) {
$(function() {
$('input[disabled][title]')
.removeAttr('disabled')
.addClass('disabled')
.click(function() {return false})
})
}
The z-indexing thing could be done like this:
.btnTip
{
position: absolute;
left: 0%;
right: 0%;
z-index: 100;
width: 50px;
/*background-color: red;*/
height: 17px;
}
(…)
<div style="background-color: gray; width: 400px;">
Set width of the tip-span to the same as the button width.
<div style="text-align: center;">
<span style="position:relative;">
<span class="btnTip" title="MyToolTip"> </span>
<input type="button" name="" disabled="disabled" value="Save" style="width: 50px;height:17px;" />
</span>
</div>
Left and right helps positioning the host on top of the disabled element.
The z-index defines what kind of layer you put an element in.
The higher number of a z-layer the more ‘on top’ it will be.
The z-index of the host and/or the disabled element should be set dynamically.
When the disabled element is disabled you want the tooltip host on top and vice versa - at least if you want to be able to click your element (button) when it is NOT disabled.
I have faced the similar issue and i could fix it using juery and small css class, you would require to create two new span elements and a css class which are as follows
Just add these in a general js and css file which is used in all over the application or web site
.DisabledButtonToolTipSpan
{
position :absolute;
z-index :1010101010;
display :block;
width :100%;
height :100%;
top :0;
}
To display tooltip for disabled button in firefox browser.
$(window).load(function() {
if ($.browser.mozilla) {
$("input").each(function() {
if ((this.type == "button" || this.type == "submit") && this.disabled) {
var wrapperSpan = $("<span>");
wrapperSpan.css({ position: "relative" });
$(this).wrap(wrapperSpan);
var span = $("<span>");
span.attr({
"title": this.title,
"class": "DisabledButtonToolTipSpan"
});
$(this).parent().append(span);
}
});
}
});
Hope this helps,
Preetham.
You could use javascript. Use the mouseover event.
(A lot of libraries like JQuery and Mootools have tooltip plugins available. Using these you can even style the tooltips).