Workaround for file input label click (Firefox) - html

<label for="input">Label</label><input type="file" id="input"/>
In Firefox 7 it is not possible to trigger the open file dialog by clicking on the label.
This SO question is very similar but that's green checked with it's a bug in FF. I'm looking for a workaround.
Any ideas?

thank you for this q&a... helped me out.
my variation of #marten-wikstrom's solution:
if($.browser.mozilla) {
$(document).on('click', 'label', function(e) {
if(e.currentTarget === this && e.target.nodeName !== 'INPUT') {
$(this.control).click();
}
});
}
notes
using document.ready ($(function() {...});) is unnecessary, in either solution. jQuery.fn.live takes care of that in #marten-wikstrom's case; explicitly binding to document does in my example.
using jQuery.fn.on... current recommended binding technique.
added the !== 'INPUT' check to ensure execution does not get caught in a loop here:
<label>
<input type="file">
</label>
(since the file field click will bubble back up to the label)
change event.target check to event.currentTarget, allowing for initial click on the <em> in:
<label for="field">click <em>here</em></label>
using the label element's control attribute for cleaner, simpler, spec-base form field association.

I came up with a feasible workaround:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$("label").click(function () {
$("#input").click();
});
});
</script>
<label for="input">Label</label><input type="file" id="input"/>
Quite strange that FF allows you to simulate a click on a file input. I thought that was considered a security risk...
UPDATE: This is a generic workaround:
<script type="text/javascript">
$(function () {
if ($.browser.mozilla) {
$("label").live("click", function (event) {
if (event.target == this) {
$("#" + $(this).attr("for")).extend($("input", this)).first().click();
}
});
}
});
</script>

A couple problems arise when using the jQuery browser detection, most notably the anti-pattern of using browser detection rather than feature detection, in addition to the fact that 1.9+ doesn't provide that functionality.
Perhaps, then, the solution I arrived at is a bit hypocritical, but it worked well and seems to adhere to most best practices today.
First, ensure you're using Paul Irish's conditional classes. Then, use something like:
if($("html").hasClass("ie")) {
$("label").click();
} else {
$("input").click();
}
Otherwise, I found the event would be double-fired in browsers such as Chrome. This solution seemed elegant enough.

The file-selection dialog can be triggered in all browsers by the click() event. An unobtrusive solution to this problem could look like that:
$('label')
.attr('for', null)
.click(function() {
$('#input').click();
});
Removing the for attribute is important since other browsers (e.g. Chrome, IE) will still ratify it and show the dialog twice.
I tested it in Chrome 25, Firefox 19 and IE 9 and works like a charm.

It seems to be fixed in FF 23, so browser detection becomes hazardous and leads to double system dialogs ;(
You can add another test to restrict the fix to FF version prior to version 23:
if(parseInt(navigator.buildID,10) < 20130714000000){
//DO THE FIX
}
It's quite ugly, but this fix will be removed as soon as old the version of FF will have disappeared.

A work around when you don't need/want to have the input box (like image upload) is to use opacity: 0 in the element and use pointer-events: none; in the label.
The solution is really design specific but maybe should work for someone who comes to this. (until now the bug doesn't been fixed)
http://codepen.io/octavioamu/pen/ByOQBE

you can dispatch the event from any event to the type=file input if you want
make the input display:none and visibility:hidden, and then dispatch the event from,
say, the click|touch of an image ...
<img id="customImg" src="file.ext"/>
<input id="fileLoader" type="file" style="display:none;visibility:hidden"/>
<script>
customImg.addEventListener(customImg.ontouchstart?'touchstart':'click', function(e){
var evt = document.createEvent('HTMLEvents');
evt.initEvent('click',false,true);
fileLoader.dispatchEvent(evt);
},false);
</script>

Using the answer of Corey above in a React environment I had to do the following:
(Firefox check is based on: How to detect Safari, Chrome, IE, Firefox and Opera browser?)
const ReactFileInputButton = ({ onClick }) => {
const isFirefox = typeof InstallTrigger !== 'undefined';
const handleClick = isFirefox ? (e) => {
e.currentTarget.control.click();
} : undefined;
const handleFileSelect = (e) => {
if (e.target.files && e.target.files[0]) {
onClick({ file: e.target.files[0] });
}
}
return (
<>
<input type="file" id="file" onChange={handleFileSelect} />
<label htmlFor="file" onClick={handleClick}>
Select file
</label>
</>
);
};

Reverse the order of the label and input elements. iow, put the label element after the input element.

Try this code
<img id="uploadPreview" style="width: 100px; height: 100px;"
onclick="document.getElementById('uploadImage').click(event);" />
<input id="uploadImage" type="file" name="myPhoto" onchange="PreviewImage();" />
<script type="text/javascript">
function PreviewImage() {
var oFReader = new FileReader();
oFReader.readAsDataURL(document.getElementById("uploadImage").files[0]);
oFReader.onload = function (oFREvent) {
document.getElementById("uploadPreview").src = oFREvent.target.result;
};
};
</script>

Related

Ho to hide the " | " cursor symbol on click of the input box in IE? [duplicate]

I have a simple input field:
<input id="myInput" class="someClass"></input>
and some JQuery code:
$(e.currentTarget).prop('readonly', true);
where e.currentTargetis that [object HTMLInputElement] as IE11 names it.
I'm only trying to set this input field to be readonly. In chrome that code works but in IE not.
I tried already:
.prop('readonly','readonly');
.prop('readonly', '');
.attr('readonly', true);
but none of them works in IE11 ( in chrome everyone of them works)
Okay, this is bizarre: If you make the field read-only while it has focus, IE11 seems to go a bit bonkers, and one of the ways it goes bonkers is to let you keep modifying the field while the cursor is there — with some keystrokes, but not others. Here's an example: Fiddle
$("#myInput").one("click", function(e) {
$(e.currentTarget).prop('readonly', true);
display("e.currentTarget.readOnly: " + e.currentTarget.readOnly);
});
$("#myInput").on("keydown", function(e) {
display("e.currentTarget.readOnly: " + e.currentTarget.readOnly);
});
function display(msg) {
$("<p>").html(String(msg)).appendTo(document.body);
}
Adding this line before setting readOnly fixes it (fiddle):
$(e.currentTarget).blur();
Side note: You don't need jQuery to set the readOnly property, just:
e.currentTarget.readOnly = true; // Note the capital O
'Read-only' input element doesn't work consistently in IE 8,9, 10 or 11.
In this case, we can use onkeydown="javascript: return false;" in the input element.
I have used Focusin() function in jquery side with Id. When I click on textbox then we remove readony attribute as below:
HTML:
<input type="text" id="txtCustomerSearch" readonly class="customer-search"
placeholder="Search customer:" maxlength="100" autocomplete="off">
Jquery:
$("#txtCustomerSearch").focusin(function () {
$(this).removeAttr('readonly');
});
Note: it will working in IE11 and other browser.

How to disable autocomplete for all major browsers

How do you disable Autocomplete in the major browsers for a specific input and/or the complete form.
I found this solution:
<input type="text" name="foo" autocomplete="off" />
However, this does not seem to work in all browsers. I've had problems in firefox for instance.
Edit:
My firefox issue has been resolved. That leaves the following: Can I disable autocomplete on a form or do I have to give every input autocomplete="off"
Autocomplete should work with the following <input> types: text, search, url, tel, email, password, datepickers, range, and color.
But alas, you could try adding autocomplete='off' to your <form> tag instead of the <input> tag, unless there's something preventing you from doing that.
If that doesn't work, you could also use JavaScript:
if (document.getElementsByTagName) {
var inputElements = document.getElementsByTagName(“input”);
for (i=0; inputElements[i]; i++) {
if (inputElements[i].className && (inputElements[i].className.indexOf(“disableAutoComplete”) != -1)) {
inputElements[i].setAttribute(“autocomplete”,”off”);
}
}
}
Or in jQuery:
$(document).ready(function(){
$(':input').live('focus',function(){
$(this).attr('autocomplete', 'off');
});
});
You could try manually clearing text fields on page load with javascript, for example:
window.onload = function() {
elements = document.getElementsByTagName("input");
for (var i=0; i<elements.length; ++i) {
elements[i].value = "";
}
};
This might not work if it's executed before the autofill. Another option is to generate part of the name attributes for your inputs randomly each time the page is rendered (and strip them out when the server handles the submit), then the browser won't try to autocomplete.
See also Is autocomplete="off" compatible with all modern browsers?
I found this one. It hides on chrome, edge and opera
<form autocomplete="off">
<input role="presentation" />
</form>
IE: autocomplete
Firefox, Chrome, Opera: disableautocomplete
<input type="text" autocomplete="off" disableautocomplete id="number"/>

Required Attribute Not work in Safari Browser

I have tried following code for make the required field to notify the required field but its not working in safari browser.
Code:
<form action="" method="POST">
<input required />Your name:
<br />
<input type="submit" />
</form>
Above the code work in firefox. http://jsfiddle.net/X8UXQ/179/
Can you let me know the javascript code or any workarround? am new in javascript
Thanks
Safari, up to version 10.1 from Mar 26, 2017, doesn't support this attribute, you need to use JavaScript.
This page contains a hacky solution, that should add the desired functionality: http://www.html5rocks.com/en/tutorials/forms/constraintvalidation/#toc-safari
HTML:
<form action="" method="post" id="formID">
<label>Your name: <input required></label><br>
<label>Your age: <input required></label><br>
<input type="submit">
</form>
JavaScript:
var form = document.getElementById('formID'); // form has to have ID: <form id="formID">
form.noValidate = true;
form.addEventListener('submit', function(event) { // listen for form submitting
if (!event.target.checkValidity()) {
event.preventDefault(); // dismiss the default functionality
alert('Please, fill the form'); // error message
}
}, false);
You can replace the alert with some kind of less ugly warning, like show a DIV with error message:
document.getElementById('errorMessageDiv').classList.remove("hidden");
and in CSS:
.hidden {
display: none;
}
and in HTML:
<div id="errorMessageDiv" class="hidden">Please, fill the form.</div>
The only drawback to this approach is it doesn't handle the exact input that needs to be filled. It would require a loop accross all inputs in the form and checking the value (and better, check for "required" attribute presence).
The loop may look like this:
var elems = form.querySelectorAll("input,textarea,select");
for (var i = 0; i < elems.length; i++) {
if (elems[i].required && elems[i].value.length === 0) {
alert('Please, fill the form'); // error message
break; // show error message only once
}
}
If you go with jQuery then below code is much better. Just put this code bottom of the jquery.min.js file and it works for each and every form.
Just put this code on your common .js file and embed after this file jquery.js or jquery.min.js
$("form").submit(function(e) {
var ref = $(this).find("[required]");
$(ref).each(function(){
if ( $(this).val() == '' )
{
alert("Required field should not be blank.");
$(this).focus();
e.preventDefault();
return false;
}
}); return true;
});
This code work with those browser which does not support required (html5) attribute
Have a nice coding day friends.
I had the same problem with Safari and I can only beg you all to take a look at Webshim!
I found the solutions for this question and for this one very very useful, but if you want to "simulate" the native HTML5 input validation for Safari, Webshim saves you a lot of time.
Webshim delivers some "upgrades" for Safari and helps it to handle things like the HMTL5 datepicker or the form validation. It's not just easy to implement but also looks good enough to just use it right away.
Also useful answer on SO for initial set up for webshim here! Copy of the linked post:
At this time, Safari doesn't support the "required" input attribute. http://caniuse.com/#search=required
To use the 'required' attribute on Safari, You can use 'webshim'
1 - Download webshim
2 - Put this code :
<head>
<script src="js/jquery.js"></script>
<script src="js-webshim/minified/polyfiller.js"></script>
<script>
webshim.activeLang('en');
webshims.polyfill('forms');
webshims.cfg.no$Switch = true;
</script>
</head>
I have built a solution on top of #Roni 's one.
It seems Webshim is deprecating as it won't be compatible with jquery 3.0.
It is important to understand that Safari does validate the required attribute. The difference is what it does with it. Instead of blocking the submission and show up an error message tooltip next to the input, it simply let the form flow continues.
That being said, the checkValidity() is implemented in Safari and does returns us false if a required filed is not fulfilled.
So, in order to "fix it" and also show an error message with minimal intervention (no extra Div's for holding error messages) and no extra library (except jQuery, but I am sure it can be done in plain javascript)., I got this little hack using the placeholder to show standard error messages.
$("form").submit(function(e) {
if (!e.target.checkValidity()) {
console.log("I am Safari"); // Safari continues with form regardless of checkValidity being false
e.preventDefault(); // dismiss the default functionality
$('#yourFormId :input:visible[required="required"]').each(function () {
if (!this.validity.valid) {
$(this).focus();
$(this).attr("placeholder", this.validationMessage).addClass('placeholderError');
$(this).val(''); // clear value so it shows error message on Placeholder.
return false;
}
});
return; // its invalid, don't continue with submission
}
e.preventDefault(); // have to add it again as Chrome, Firefox will never see above
}
I found a great blog entry with a solution to this problem. It solves it in a way that I am more comfortable with and gives a better user experience than the other suggestions here. It will change the background color of the fields to denote if the input is valid or not.
CSS:
/* .invalid class prevents CSS from automatically applying */
.invalid input:required:invalid {
background: #BE4C54;
}
.invalid textarea:required:invalid {
background: #BE4C54;
}
.invalid select:required:invalid {
background: #BE4C54;
}
/* Mark valid inputs during .invalid state */
.invalid input:required:valid {
background: #17D654 ;
}
.invalid textarea:required:valid {
background: #17D654 ;
}
.invalid select:required:valid {
background: #17D654 ;
}
JS:
$(function () {
if (hasHtml5Validation()) {
$('.validate-form').submit(function (e) {
if (!this.checkValidity()) {
// Prevent default stops form from firing
e.preventDefault();
$(this).addClass('invalid');
$('#status').html('invalid');
}
else {
$(this).removeClass('invalid');
$('#status').html('submitted');
}
});
}
});
function hasHtml5Validation () {
return typeof document.createElement('input').checkValidity === 'function';
}
Credit: http://blueashes.com/2013/web-development/html5-form-validation-fallback/
(Note: I did extend the CSS from the post to cover textarea and select fields)
I use this solution and works fine
$('#idForm').click(function(e) {
e.preventDefault();
var sendModalForm = true;
$('[required]').each(function() {
if ($(this).val() == '') {
sendModalForm = false;
alert("Required field should not be blank."); // or $('.error-message').show();
}
});
if (sendModalForm) {
$('#idForm').submit();
}
});
The new Safari 10.1 released Mar 26, 2017, now supports the "required" attribute.
http://caniuse.com/#search=required
You can add this event handler to your form:
// Chrome and Firefox will not submit invalid forms
// so this code is for other browsers only (e.g. Safari).
form.addEventListener('submit', function(event) {
if (!event.target.checkValidity()) {
event.preventDefault();
var inputFields = form.querySelectorAll('input');
for (i=0; i < inputFields.length; i++) {
if (!inputFields[i].validity.valid) {
inputFields[i].focus(); // set cursor to first invalid input field
return false;
}
}
}
}, false);
Within each() function I found all DOM element of text input in the old version of PC Safari, I think this code useful for newer versions on MAC using inputobj['prpertyname'] object to get all properties and values:
$('form').find("[required]").each(function(index, inputobj) {
if (inputobj['required'] == true) { // check all required fields within the form
currentValue = $(this).val();
if (currentValue.length == 0) {
// $.each((inputobj), function(input, obj) { alert(input + ' - ' + obj); }); // uncomment this row to alert names and values of DOM object
var currentName = inputobj['placeholder']; // use for alerts
return false // here is an empty input
}
}
});
function customValidate(){
var flag=true;
var fields = $('#frm-add').find('[required]'); //get required field by form_ID
for (var i=0; i< fields.length;i++){
debugger
if ($(fields[i]).val()==''){
flag = false;
$(fields[i]).focus();
}
}
return flag;
}
if (customValidate()){
// do yor work
}

apply html5 tag "required" to every browsers

in html5, there is tag "required" for input,
eg:<input type="text" required="required" value="" />
but it is working on Firefox,Opera and Chrome, but not for IE and Safari, i tried to include <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>, but it is still not working !
As Explosion Pills mentioned in his comments, the required form attribute is not supported by Safari or versions of Internet Explorer lower than 10.
You can get around this by using a third-party JavaScript plugin that will enforce form validation regardless of browser version. See https://github.com/dilvie/h5Validate.
You can't use html5shiv to add require.
Try something like this (uses JQuery): http://jsfiddle.net/DfCHu/
$('form').submit(function() {
var empty_fields = $('input').filter(function() {
//return empty required fields
return $(this).attr("required") && $(this).val() === "";
});
// if empty required field stop the form submitting and let the user know
if(empty_fields.length){
alert('something required');
return false;
}
});

disable text drag and drop

There is a common feature of modern browsers where a user can select some text and drag it to an input field. Within the same field it causes moving of text, between different fields it does copying.
How do I disable that? If there is no portable way, I am mostly interested in firefox. This is an intranet webapp, so I am also interested in modifying the browser/getting a plugin to do this. Maybe some system-level settings (I`m on windows XP)?
I need to keep the default select-copy-paste functionality.
The background is I have multiple-field data entry forms, and users often drag something by mistake.
For archival purposes:
<body ondragstart="return false" draggable="false"
ondragenter="event.dataTransfer.dropEffect='none'; event.stopPropagation(); event.preventDefault();"
ondragover="event.dataTransfer.dropEffect='none';event.stopPropagation(); event.preventDefault();"
ondrop="event.dataTransfer.dropEffect='none';event.stopPropagation(); event.preventDefault();"
>
does what I wanted. You can add the ondrag* handlers to form elements, too, like <input ondragenter=...>
reference url: https://developer.mozilla.org/En/DragDrop/Drag_Operations
This thing works.....Try it.
<BODY ondragstart="return false;" ondrop="return false;">
hope it helps. Thanks
This code will work in all versions of Mozilla and IE.
function preventDrag(event)
{
if(event.type=='dragenter' || event.type=='dragover' || //if drag over event -- allows for drop event to be captured, in case default for this is to not allow drag over target
event.type=='drop') //prevent text dragging -- IE and new Mozilla (like Firefox 3.5+)
{
if(event.stopPropagation) //(Mozilla)
{
event.preventDefault();
event.stopPropagation(); //prevent drag operation from bubbling up and causing text to be modified on old Mozilla (before Firefox 3.5, which doesn't have drop event -- this avoids having to capture old dragdrop event)
}
return false; //(IE)
}
}
//attach event listeners after page has loaded
window.onload=function()
{
var myTextInput = document.getElementById('textInput'); //target any DOM element here
if(myTextInput.addEventListener) //(Mozilla)
{
myTextInput.addEventListener('dragenter', handleEvents, true); //precursor for drop event
myTextInput.addEventListener('dragover', handleEvents, true); //precursor for drop event
myTextInput.addEventListener('drop', preventDrag, true);
}
else if (myTextInput.attachEvent) //(IE)
{
myTextInput.attachEvent('ondragenter', preventDrag);
myTextInput.attachEvent('ondragover', preventDrag);
myTextInput.attachEvent('ondrop', preventDrag);
}
}
add the following to your field tags:
#ondragstart is for IE, onmousedown is for firefox
ondragstart="return false" onmousedown="return false"
ondraggesture is supported by older versions of Firefox instead of ondragstart.
Use the following code
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("Text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
and:
<input type="text" ondrop="drop(event)" ondragover="allowDrop(event)">
See: http://jsfiddle.net/zLYGF/25/
You can use :focus attribute to recognize over what your mouse is:
if(document.activeElement.tagName == "INPUT"||document.activeElement.tagName == "TEXTAREA"){
event.preventDefault()
return
}