Jquery: change event to input file on IE - javascript

I have a form to upload files, and it should fire the submit after the file selection.
On FireFox/Chrome it goes well, and submits the form after file selection, but I can't do this on Internet Explorer.
Already tried with click/propertychange but nothing happens. Some code I already tried:
$("#attach").attr("onChange", "alert('I changed')");
$("#attach").live($.browser.msie? 'propertychange': 'change', function(e) { ... });
This input file is created on the fly; because of it I use .live() to bind the event.
Any suggestions?

I know this is several months late, but I just ran into the exact same behavior in IE7; in all other browsers, the change event for file inputs happens after file selection. In IE7, it happens only if you trigger the file select again, or on blur.
Here's how I ended up fixing it:
var $input = $('#your-file-input-element');
var someFunction = function()
{
// what you actually want to do
};
if ($.browser.msie)
{
// IE suspends timeouts until after the file dialog closes
$input.click(function(event)
{
setTimeout(function()
{
if($input.val().length > 0) {
someFunction();
}
}, 0);
});
}
else
{
// All other browsers behave
$input.change(someFunction);
}
Technically you could/should filter the hack condition to just IE7, since IE8 behaves properly on the change event, but it also has the same behavior as IE7 on suspending timeouts while browser-related chrome is visible (I guess it considers it blocking I/O), so it works as-is.

This is really late, but I was having the same problem, and I solved it by using a styled <label> tag with a slight workaround for Firefox.
http://jsfiddle.net/djibouti33/uP7A9/
The Goals:
allow user to upload a file by using standard html file input control
hide standard html file input control and apply own styling
after user selects file to upload, automatically submit the form
The Browsers:
Firefox, Chrome, IE8/9, Safari
IE7 didn't work, but it might if you add that browser to the workaround detailed at the bottom
The Initial Solution:
Hide the file input by positioning it offscreen. Important not to display:none as some browsers won't like this.
Add another styled element to the page (link, button).
Listen for a click on that element, then programmatically send a click to the file input to trigger the native 'file explorer'
Listen for the file input's onchange event (occurs after a user chooses their file)
Submit the form
The Problem:
IE: if you programmatically send a click to a file input in order to activate it (2), programmatically submitting the form (5) will throw a security error
The Workaround Solution:
Same as above
Take advantage of the accessibility features built in to the tag (clicking on a label will activate it's associated control) by styling
a tag instead of a link/button
Listen for the file input's onchange event
Submit the form
For some reason Mozilla browsers won't activate a file input by clicking on it's .
For Mozilla, listen for the click on the label and send a click event to the file input to activate it.
Hope this helps! Check out the jsfiddle for details on the html/js/css used to make it all work.

Format it like this:
$("#attach").change(function() {
alert('I Changed');
});
Update: After answering another question on this earlier, we realized this was fixed as part of the jQuery 1.4.2 event re-write, just update to the latest version to resolve the change event issue with <input type="file" /> in IE.

I used the following solution. I tried to make it as self-contained as possible.
(function($) {
if ($.browser.msie == false)
return;
$('input[type=file]').live('click', function(e) {
var self = this;
var blur = function() {
$(self).blur();
}
setTimeout(blur, 0);
});
})(jQuery);

This has always worked for me in IE6 ad IE7.
$('#id-of-input-type-file').change(function(){});

In IE onchange event works fine when it filled out in html tag directly. Like:
<input type="file" onchange="uploader.upload()" />

This is likely a problem with a race condition with input fields in IE. By using setTimeout the function that is executed will then register that a change happened. When the UI code is performed in the onChangeEvent, that event hasn't fired yet as it appears to IE.
I solved a similar situation by doing the following inside my change handler:
if (jQuery.browser.msie) { setTimeout(DoSomeUIChange, 0); } else { DoSomeUIChange(); }
The DoSomeUIChange is executed after the current code on the event queue and so removes the race condition.

I was having the same issue with IE (including IE 9). The UI logic is:
click on a div element triggers the click event on a file-input-element so that user click on a div trigger file open dialog
bind the change event handler to the file-input-element to ensure the form is submitted when file open dialog closed
The app (running inside an iframe) works like a charm on Chrome and FF. But soon I found it doesn't work on IE as when user selected a file and close the dialog the form didn't submit.
The final solution is to drop the logic #1 "click on div element trigger click event on file input element" and let user to click on the file input element directly, and then it works.
BTW, the reason we have a div element is we want to hide the browser rendered controls because we have everything in the background image. However set display to none makes the control not able to respond a user interaction event. So we move the file-input-element to outside of the view port and use a div element to replace it. Since this doesn't work on IE, we end up with move back the file-input-element and set it's opacity to 0. On IE 8 or less which doesn't support opacity, we use filter to make it transparent:
#browse {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
filter: alpha(opacity=0);
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
}

I found this solution
In HTML hide file element (don't use display: none, won't work in IE), prepare onchange event of IE:
<div style="width: 0px; height: 0px; overflow: hidden;">
<input id="ifile_template" type="file" onchange="this.focus(); this.blur();"/>
</div>
In javascript for IE bind function to blur, and for FF,CH bind function change():
$(iFile).blur(
function () {
...some code...
}
);
// FF, CH
$(iFile).change(
function () {
...some code...
}
);

For IE You can use the "onfocus" event to catch the change of uploading file. Once the file browsing dialog is closed the onfocus event is triggered. You can check this by adding this line to your page:
<input type="file" onfocus="javascript:alert('test');" />
Once the dialog is closed the alert message is shown.
This solution is only for IE, not for FF or Chrome.

My solution:
setInterval(function()
{
if ($.browser.msie) $("input[type=file]").blur();
},500);
Not pretty, but it works. ;D

I can confirm, at least that it only works after a blur event takes place, similar to a radio and checkbox in IE. I am probably going to have to add some kind of visual element for the user to click and tell me when they have picked their file.
lame.

$("#attach").attr("onChange", "alert('I changed')");
It works in IE, but if you want to emulate "live" behavior, you should add "onChange" attribute to each new element when create its.

jQuery doesn't seem to recognise the propertychange event. I added it to the DOM node using IE's attachEvent().
var userChoseFile = function($input) {
// ...
}
var $input = $(/* your file input */);
$input[0].attachEvent('onpropertychange', function() {
userChoseFile($input);
});

Look at these fiddle http://jsfiddle.net/uP7A9/531/
HTML:
<input type="file" name="PicturePath" id="fileUpload" accept=".png,.jpg,.jpeg,.gif,.tif" />
jQuery:
$("input[type=file]#fileUpload").on("change", function () {
alert('hi')
});
it works for all browsers, tested.

Related

Remove BS4 jQuery document.focus event programmatically

I have a Bootstrap 4 text field that I cannot give focus to. I have tried:
Clicking in the field
Using jQuery focus in console
Tabbing to it
Assigning autofocus attribute
When I look in chrome devtools Elements > EventListeners tab, go down to focus and remove the focus EventListeners, the field can get focus again. Also if I remove focusin listener it works.
I have tried in the console:
jQuery .off on the document object
$(document).off( "focusin");
jQuery .off on the window object
and
var customFunction = function (event) {
document.removeEventListener('focus',customFunction, false );
};
document.addEventListener("focus", customFunction, false);
Live Page
Here is what I mean about the devtools event listener screen
DevTools Screenshot with Annotation
Not really sure what to do next.
Thanks in advance.
This fixed the issue by removing jQuery's document.focus() EventListener which was blocking the input for some reason.
$btnSignContracts.on('click', function(e) {
$(document).off("focusin");
$(document).off("focus");
});
The field is working properly now.

jQuery - click-event is called twice on iPad

I have a problem with my web application which is designed for iPad.
I use jQuery and jQuery UI for dragging elements on the screen. Because on iPad, the element can not be dragged by default, I added this library:
http://code.google.com/p/jquery-ui-for-ipad-and-iphone/
Including it, I can drag and drop elements on iPad, but also a problem occurs. I have on the draggable element also a div are with an image, which should be clickable.
So I integrate these lines:
$(document).ready(function() {
$(".note").draggable();
$('.closebutton').click(function() {
alert("test");
});
});
​
The problem is, including the drag-library, the alert message test pops up twice or the screen is frozen.
I created a full working demo here:
http://jsbin.com/oliwo/2/
On normal desktop browsers, like Firefox 4 Beta and Safari, it works, only one test message appears by clicking with the mouse on the x - delete image. On iPad, I get the message twice or the screen froze.
Does anyone can help me? Thank you a lot in advance & Best Regards.
This is not really a response, as i don't known why you have it twice. But you can try a workaround if you're sure your click event is the only click event behavior that should be attached to this button; Make an unbind() just before you're bind, this will remove any previous click binding (so if this is run several times, you'll get only one event):
$('.closebutton').unbind().click(function() { ...
or better:
$('.closebutton').unbind('click').click(function() { ...
I've found that events get fired twice when showing an alert box on a click. I've managed to overcome this problem by using a setTimeout to show the alert box...
$("#myButton").unbind("click").click(function () {
// Have to use a setTimeout else on iPhone the alert may appear twice in certain scenarios
setTimeout(function () { alert('The message'); }, 300);
return false; // Return false to prevent href being followed
});
I do not know why, but if I do not use alert messages, it will work. I create new elements and then it is only called once, on iPad and Desktop Safari.
I'm seeing this issue only on iPad, perhaps some version of webkit related. The unbind worked for me, and I also read this only exists if jquery code is in the body html tag, if its in head it is not an issue.
just simply avoid the propagation of the click
$("tr").live('click',function() {
...
$( event.toElement ).one('click', function(e){ e.stopImmediatePropagation(); } );
});

Mobile Safari Event Issue

I have designed a website with a menu that is initially invisible. When the user clicks on a button, the menu becomes visible. There are two ways for the user to hide the now visible menu:
Click the button that caused the menu to become visible
Click anywhere on the web page that isn't the menu
The way I have coded the second option is to tie an onclick event to the window element, and have it compare where the user clicked to the menu's position to determine if the menu should be hidden. This works great in Firefox and Safari, but it fails in Mobile Safari.
I noticed that the window onclick event only fires when I click on another element with an onclick event already assigned. If I click on an element with no event(s) assigned, the window's onclick event never fires. If I click on the button which displays the menu, it fires along with the event tied to the button.
Is it possible to assign events to the window element in Mobile Safari?
I'v been encountering this same problem. Here is what worked for me. (Note: I am working within a Modernizr and jQuery context)
First, I add a custom Modernizr class using Modernizr's addTest Plugin API to test for iOS, which will add the class appleios or no-appleios accordingly.
Because in my research the body seems to fire events on it's own agenda, I am taking a little precaution by wrapping all the document's content with an element in an iOS context. Then I add an event handler to this element.
$(".appleios body").wrapInner('<div id="appleios-helper" />');
$("#appleios-helper").bind("mouseup", function(){return;});
What was suggested earlier in this thread is using void(0). I did some quick testing, and found that void(0) as the event just wasn't causing touches on the body to be recognized. When I plugged in my own "empty" function in the form of function(){return;} things started working.
This all hinges on the fact that no events are fired in Mobile Safari unless the element explicitly has events to fire (Safari Web Content Guide.) By inserting this empty event on the wrapper, things will bubble up to the body.
If you're doing strait JavaScript with none of these libraries, the same effect could be achieved in the HTML markup
<html>
...
<body>
<div id="appleios-helper" onmouseup="function(){return;}">
...
</div>
</body>
</html>
This worked for me to hide tooltips when touching anywhere on the document's body. Your mileage may vary.
Simply adding the dummy onclick handler to the html body works for me:
<body onclick="void(0)">
Note that I am using usual live event handlers as shown below:
function liveHandler( event ) {
var target = event.target; ...}
window.addEventListener(evtype, liveHandler, true);
// evtype such as 'mousedown' or 'click'
// we use the capturing mode here (third parameter true)
This is an old question, but I struggled with the same thing today.
I found that using touchstart event works.
I solved it like this:
var isTouchDevice = 'ontouchstart' in document.documentElement;
if (isTouchDevice) {
// Do touch related stuff
$(document).on('touchstart', function (event) {
// Do stuff
});
} else {
// Do non-touch related stuff
$(document).on('click', function () {
// Do stuff
});
}
You could just add onclick="void(0);" to some <div> that covers the whole page so that no matter what, you are always clicking on an element that has an onclick event. Not a great solution, though.
I'd prefer not having the onclick event be tied to the window. Why don't you create a container <div> that has that event on it. Then handle it just like you currently are.
You can also:
$('body').css('cursor', 'pointer');
No idea what those "engineers" at Apple are doing. LOL.
This has problems though. You wouldn't want to do this on every touch device. Only touch devices that don't also have a pointing device (Laptops with Touch Screens, for example).
Source: http://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
The conclusion of the article is this:
So I don’t understand why all this is the case, but it most certainly is the case. If you’re having bubbling problems, just add an empty-function event handler anywhere between the body and the element, and you’re set to go. But it shouldn’t be necessary.

Any alternative to jQuery change() to detect when user selects new file via dialog box in IE8?

I am unable to detect when input type="file" changes its value after user selects file and the dialog box closes.
$('.myInput').change(function(){
alert($(this).val());
})
Above jQuery code works perfectly in all browsers apart from IE. For some reason IE detects the change only after input field loses focus.
Is there a way to detect the change immediately after dialog box closes? Or maybe to force input field to lose focus after dialog box closes so IE can detect it?
I'm puzzled. Thanks for any help.
This was a known bug that was resolved as part of the jQuery 1.4.2 release, 1.4.2 got a major event model re-write and this was fixed as part of that, just upgrade to resolve the problem :)
Edit - Nick is right, it's fixed in 1.4.2. http://jsfiddle.net/7wR2L/
You can detect click and keep track of it's last value. Something like..
$('.myInput').click(function() {
var $file = $(this);
if( $file.val() != $file.data('lastVal') ) {
// different
}
$file.data('lastVal', $file.val() );
});
Dan Heberden's comment about updating to 1.4.2 works.
However if another element is used to trigger the file file selection, the file input element no longer registers a "change" event.
The new question I created for this has a fork your fiddle to illustrate this case. See jQuery: "change" event on file input element does not fire if the file selection is triggered by an element other than the file input for details.

Javascript detect when drop down list is closed

Because of the issue explained in this question I have a situation where I need to attach the mousewheel event to the drop down list only when it is expanded (I do this in the onclick event). However I need to remove the mousewheel event when the list collapses. How do I go about detecting this?
I can't just use the onchange event because the user may not have actually changed their selection. I've tried the onblur event but in most browsers (except IE) the drop list stays focused when the list is collapsed.
Cheers.
var list = document.getElementById("list");
list.onclick = function (e) {
// attach mousewheel
list.onmousewheel = function (e) {
// ...
}
// attach click off
// This event fires fine in all browsers except FF when the list is expanded.
// In firefox it only fires when anywhere in the document is clicked twice.
// The first click closes the drop down list as expected and the second one
// fires the event.
window.document.onclick = function (e) {
list.onmousewheel = null;
window.document.onclick = null
}
};
EDIT:
Unfortunately meder's solution doesnt work in firefox. The click event on the document doesn't get fired until i click twice off the drop down list. How do I get around that? It works fine in IE.
EDIT2:
I've done some more testing and the following browsers behave as expected
IE 7,
Chrome 3
Opera 10
Firefox requires 2 clicks in the window to make it work & Safari doesn't work at all.
It appears that even when you click off the drop down list firefox maintains focus on it. It's not until the second click occurs that the drop down list eventually loses it's focus.
Are you looking for something like this? If the user clicks anywhere that's not within #el, it will branch out and you can do what you want, though this requires jQuery but it would take far too many lines of DOM Scripting.
var dropdown = $('#el');
$(document).click(function(e){
if ( (!$(e.target).is(dropdown)) || !$(e.target).closest('#el').length ) {
// do what you need to
}
});
If not, can you be more specific and include an example?
PS - I did not test the snippet, sorry if it isn't what you want.
OK, I still have no idea what you're trying to achieve with such a tightly-scripted select box, but in general trying to change the internal working of a native <select> isn't fruitful. There's no standard that says how events flow internally to the form element, and browsers that implement select as an OS-level widget (IE) can't do much to support it anyway.
If you must have this behaviour, I'd suggest using scripting to replace the <select> box on-fly with a JavaScript-powered analogue made out of <div>s. Then you can control exactly how each mouse and keyboard interaction behaves. There are many libraries that do this already, though again if you need to be very specific about the exact behaviour they might not suit you.

Categories

Resources