i'm having trouble in chrome opening the popup for the file upload of a file input type.
As you can see here: http://jsfiddle.net/cavax/K99gg/3/, clicking on an elements can trigger a click on the file input, but for example hovering a element wont trigger a click on the input.
$('#test').on('click', function(){
$('#upload').trigger('click');
});
$('#test').on('mouseenter', function(){
$('#upload').trigger('click');
});
In the real life i'm having this trouble because in a web app i'm loading throw ajax a content witch has inside an input file.
At the end of the load the popup file must open, but there is no way to get this works on Chrome (workign on FF).
The problem i guess is that the action is not generated by a mouse click (hover, timeout etc) so chrome wont trigger the fileupload.
I've also tryed this: http://jsfiddle.net/cavax/K99gg/7/, so click on the element, wait then trigger the click but nothing, because there is the "settimeout" in the middle of the click and the trigger :(
$('#test').on('click', function(){
setTimeout(function(){
$('#upload').trigger('click');
}, 3000);
});
if you remove the delay: http://jsfiddle.net/cavax/K99gg/8/ it works
Any idea to get this work?
If I remember correctly, mouseenter and mouseleave are specific to IE, not standard events. Maybe they were extended, but don't think they became a standard. So the event itself may generate you some problems.
To resolve this you can use a lib (like jQuery for example), that treats the browser differences (or you can check the code there and take what you need).
Second way... try mouseover... it worked better (again... didn't work with them for a while so things may have happened, but this is how I remember them to be).
There is no way to trigger click event of input file type, because of a security reason.
You may try a hack of this by setting your button/div position to absolute and top to -100px
It means positioning it outside the viewport by setting above style make it works.
But for mouseenter and mouseover i don't think it's going to work!
Edit:
Moved input outside the viewport and target click event
Example on click
Side note: Right now click occurs 2 times as you have written
$('#upload').trigger('click').click();
You just need
$('#upload').trigger('click'); // $('#upload').click()
unless you want it to fire more than single time.
Related
Recently we implemented the GoogleTagManager (GTM), and certain Jquery UI dialogs are not showing at all (some of them always work, some of them never work, consistently). Unfortunately, I cannot provide sample codes.
When a UI button is clicked that calls .dialog("open") the dialog is not shown but the entire page goes grey (div class="ui-widget-overlay ui-front"). I see in the html that the div has "display:none" style.
If I remove the display: none, the dialog is finally shown, but the form's UI is messed up. Somehow the width of the modal is 300px instead of 1000px, etc. Also, the event listeners from the save/cancel buttons are missing. If I put autoOpen: true on the jquery UI dialog declaration, the dialog is shown, but is still messed up the same way.
I noticed that when I have an adblocker, everything works properly, but when I don't, the bug appears. I also realized that a "fbevents.js" file is in the browser when GTM is used, and if I explicitly disable only this file with an adblocker, the bug disappears.
I also see a facebook.com/tr/ call that stays "pending" forever in the network tab in Chrome, when I click on the icon that calls the dialog("open").
And of course, if there is no GTM, the site works properly.
Do you have any idea what is this bug or how should I continue the investigation? (without updating jquery/jqueryUI or without switching to bootstrap modal)?
Without additional detail is very hard to guess, what causes your problem, but there is one thing, I will try ona first place.
Check, how is your trigger made.
There are some GTM configurations, that steps into link click event processing.
So maybe, there is an event listenning on an A element, that onlky pretends to be a link and GTM is waiting for response.
If this is a true, try to change event listener into just Generic click event (Click - All Elements).
I got lucky. I found a second form that exists for a short period of time, which was facebook related (GTM). I realized that a "xy.appendTo('form')" JS code inserts data into the wrong form... By changing the code to "xy.appendTo('#form1')" the problem is gone.
So a simple appendTo('form') started the domino effect, which resulted in duplicated IDs in the DOM, and messed up everything...
The facebook.com/tr call in the network tab is still in pending state, but I believe that is somehow related to Jakub Kriz's suggestion (I will update my answer soon).
UPDATE:
Even though the GTM debugger shows no trigger has been fired, the GTM sends requests to facebook.com/tr calls every time a "a/a href" or "input type="button"" is clicked. I believe this is a default functionality, and I understand why.
In some cases our website is using these html tags in an invalid way: "a" is used instead of a "div" and "input type button" is used for an icon that opens a modal dialog. If we change these, the unnecessary facebook.com/tr calls will be gone.
But I've got still no clue about the pending state. I believe when I apply the changes I mentioned above, the problem will be gone.
I'm using the MDL tab component. After a tab is clicked and it displays the content for that tab, I'd like to set the cursor focus in a certain text input within that tab's content.
My initial approach was just to handle the click event of the tab element and then set focus accordingly. The problem I'm having is that calling .focus() on the text input element isn't working because it tries to set focus before the text element is actually visible, which no browser seems to like doing for you. If I set focus inside a setTimeout() delay it works, but that doesn't feel like a very clean way to go about it.
Is there any kind of event that can be handled for when a tab is clicked and has finished displaying it's contents? I've also looked at using mutation observers to detect when the text input element is visible but browser support for those is fairly limited still.
No there is no such option. I think you have to use setTimeout or setInterval
You can look into the source. Perhaps write your own MaterialTabs constructor and register it.
Material-Design-Lite source, MaterialTab
I think there are also some libs that can do this like jQuery. You can also see
https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
This works only in modern browser but has a legacy implementation.
I've added this line :
window.dispatchEvent(new Event("tabSelected"));
to the material.js file, at the end of the selectTab() function. This way, the event is fired right after the tab content is shown.
I don't know if this is the effects of an update panel or what, but I basically have a drop down list that allows a user to select an item as a filter. When the item is selected it should bring back only one item into a grid view. That is this specific filter will at most bring back the record you are looking for. This works fine if the user clicks an "apply" link to apply the filter. Behind the apply link is some server-side code (C# within an ASP.NET Web Forms application).
We had a request by a user with something to the effect of:
"Why do I have to click the apply button if I make a selection in this
one drop down filter...it should simply get that one record I am
searching for. This helps me because I don't have to click the
"Apply" button."
I agreed with him and thought what is the easiest way to do this...I thought: Simple, I will have an on change event handler of the drop down such that when a selection is made I'll trigger a click event. Something to this effect:
$("#MainContent_ddlCompany").on("change", function() {
var companyId = $("#MainContent_ddlCompany").val();
$("#MainContent_hdnCompanyValue").val(companyId);
$("#<%=ddlCompany.ClientID %>").trigger("chosen:updated");
if (companyId.length > 0) {
$(".apply").click();
$(".apply").removeClass("applyButton");
$(".apply").addClass("resetButton");
} else {
//cleared selection of a company
$(".apply").removeClass("resetButton");
$(".apply").addClass("applyButton");
}
});
At first this didn't work, and I couldn't tell why, but then after some serious googling I changed this line:
$(".apply").click();
To this:
$('.apply')[0].click();
That worked great...so I decided to test it some more. As I kept selecting one filter value after another I noticed the page started to slow down. In fact by the 6th or 7th time it was pretty unusable. I don't know why it's happening, but I suspect again it has to do with the fact that this linkbutton with the class name .apply is inside an update panel.
But still I thought to myself, it was inside of an update panel before I changed my jQuery code to simulate the click event. So why does the page slow down and drag with this little piece of code? Is calling the event from jQuery code rendering something else in the HTML that could be causing this?
If I change my code back and force the user to click the apply button then we are back to a good normal speed. Why is it if I tell jQuery to simulate clicking the button my page slow down? It's doing the same thing, the simulation of the click of this link button is calling its server-side code method whether the user clicks it or I have jQuery click it.
For now I'm at a loss as to why this is happening because this button is in an update panel in either case, yet when I have jQuery click it via $('.apply')[0].click(); the page slows down after several attempts. Yet when I have the user simply click this button (without the jQuery click event) then it works fine?
What am I missing here?
Ugh, well, I found my issue. Because I was using updatepanels I had to wrap my jQuery code to include an add_endRequest. That is, you have something to the effect of:
$(document).ready(function() {
//Some initial event/triggers
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function () {
//Copy of some initial event/triggers
});
});
Why do I use the endRequest you ask? Well, because updatepanels basically throw away all your events after an asynchronous postback because the HTML at that point (after an update) is rendered again and at that point all events associated with any control inside an update panel are wiped away. At this point of course document.ready() does not run, so I have to resubscribe to these events inside of endRequest. Enter my issue...
I had a huge brain fart where I basically took everything, literally everything inside document ready and copied it into endRequest. In fact, if I remember correctly, I read articles which stated
Whatever you have in document ready simply copy paste into endRequest
That's fine, but you have to be careful here. I was throwing in events that were not wrapped around inside of an updatepanel into endRequest. The result is disastrous...at least for me.
These events would be attached then multiple times..or based on the number of asynchronous postbacks made. In my case, as I was testing I mentioned after the 6th or 7th time performance starts degrading. Well, by that time my controls were being attached that many times to events. For instance, my .apply button along with my dropdownlist were both outside of my updatepanel. But my jQuery code was attaching the change event of my dropdownlist in both document ready and endRequest.
The result is initially it's pretty fast, because it's only in document ready. But as I make asynchronous postbacks these events are being attached every time. For n tests I would have n attached events...in my case the test of 7 yields 7 on change event handlers!
Case in point, do not place any event handlers such as jQuery's on() event for any controls that are NOT inside an update panel. Otherwise you will run into what I ran into which was poor performance as events are happening.
There is a lot of material/posts on ghost clicks and I'm trying to understand it better. So the way I understand it, the reason for ghost clicks is the click event being dispatched ~300ms after the touch event. jQuery Mobile suggests to not use their vclick event whenever there is any chance of changing the content underneath the finger position.
My first question would be: Does that mean ghost clicks will only fire if the element targeted by click is different from the one originally touched? So, say, I write a database entry when a button is touched – nothing else. Is there a chance of ghost clicking or not?
If this is the case, wouldn't that mean that I can prevent ghost clicks altogether if I simply use only tap events and no click events whatsoever?
My last question would be if I can simply tell the browser to not use the 300ms delay when using PhoneGap (which would instantly solve the problem), but I'd just guess that I can't do that as it's probably hard-coded into the browser.
The click event is delayed by 300 ms to detect things like double tap or fat finger mistakes.
Yes, wherever possible you should use the touch events instead.
Yes, there are many ways to enable fast clicks by doing a bit of JS. For instance:
https://developers.google.com/mobile/articles/fast_buttons
https://forum.jquery.com/topic/how-to-remove-the-300ms-delay-when-clicking-on-a-link-in-jquery-mobile
http://labs.ft.com/2011/08/fastclick-native-like-tapping-for-touch-apps/
You don't have to live with the 300ms delay.
If everything on your page that can be clicked has the appropriate vclick jQuery event handlers installed, then one easy way of stopping ghost clicks is create a touchend event handler on the body and call preventDefault from it:
$(document.body).on('touchend', null, function(e) {
e.preventDefault();
});
Note that this will disable regular clicks from touches, so any conventional links or form inputs you have will stop working unless you add vclick handlers to them.
Simply put:
what I want:
you click something calls function xxx(), while you double click calls another function yyy()
when I put onclick and ondblclick together only xxx() executed, so how do I achieve the similar effect?
Thanks!!
The problem is that, in some browsers, your onclick handler grabs the first click of the pair, and the ondblclick handler never sees the action. In other browsers the click is seen twice and the double click as well. The potential timing for a double click will vary by operating system, browser, and user configuration.
Handling this in a portable way is, to say the least, difficult.
I would recommend only having click handlers. But have the click handler set a variable, and a timeout. If the timeout is hit without a second click, do the onclick action. If a second click happens in that time, make sure that the timeout will do nothing and do the ondblclick action. The drawback is that this means that your double clicks won't respect the rules of the local operating system, browser, and user configuration.
Try this out:var dbclkTimeout=-1;
somelement.onclick=function(){
if(dbclkTimeout==-1)
dbclkTimeout=setTimeout(function(){onclickcallback();dbclkTimeout=-1;} , 200);
else {
clearTimeout(dbclkTimeout);
dbclkTimeout=-1;
ondbclickcallback();
}
}