dojo onkeyup disabled after pressing tab on IE8 - javascript

I have a problem with events on IE8 (dread!), using dojo toolkit 1.4.3 (can't use any other version) on a Spring application running on Websphere Portal Server.
Now, I don't believe the backend has anything to do with this, since the problem with IE8 tabbing is known:
press on any field of a webpage and press tab all the way, the focus goes back up to the url input and buttons and doesn't return to the document after repeating it, if you click on an element in a website it re-adds the focus to that element, but when you press tab again it goes back to the top of the browser.
Now, my problem happens AFTER tabbing all the way and getting the focus out of the document.
It would seem the browser is removing events from the DOM, I have debugged the code on IE8 and it seems to not trigger the callback function, while it behaves normally when not doing the whole tab thing.
I've tried using dojo.disconnect() and re-adding the events by subsequently calling dojo.connect() to no avail, here's a small snippet:
var connectedObjects = {};
dojo.query(".someClass").forEach(function(inputField){
connectedObjects[inputField.id] = {};
connectedObjects[inputField.id].onfocus = dojo.connect(inputField, "onfocus", function(event){
if(connectedObjects[inputField.id]){
dojo.disconnect(connectedObjects[inputField.id].onkeyup);
connectedObjects[inputField.id].onkeyup = dojo.connect(inputField, "onkeyup", someCallbackFunction);
}
})
});
Does anyone have any ideas on how to solve this?

so, this is a weird one, but there is a simple way to fix the problem, this also seems to fix other browsers from cycling through hidden input fields that have the css property display:none, so on to the code:
dojo.query("*").forEach(function(fieldID){
dojo.attr(fieldID, "tabIndex", "-1");
});

Related

Mobile keyboard does not open with Javascript focus event

Trying to focus a simple input text when page loads with Javascript events, my goal is to focus and open the virtual keyboard on mobile browsers but I've not gotten success.
My code looks like so simple as:
document.getElementById("anser-animation").focus();
document.getElementById("anser-animation").click();
I've tried on jQuery as well...
$('#answer-animation').focus();
$('#answer-animation').trigger('click');
On android input gets focus but not on iPhones. On both cases I don't get the keyboard intermediately on page loading. I'm not sure what's more I have to do.
To my knowledge. That is because Apple has decided to disable this functionality, when bind with $(document).ready(function (){});
What you could do (if target-page is reached via Ajax and/or if it's applicable in your case) is that when a button is pressed, i.e ("sign up") is trigger focus(); on the input field.
Like this:
$(".sign-up-button").click(function (){
$(".first_name").focus();
});
This is at least how I've solved it in the past, but if this won't work for you, then I'm sorry, but you're just out of luck, like so many of us. For now at least.
You have you do like this
$("#fname").trigger('focus');

WebDriver: Change event not firing

I have an application that is using KnockoutJS and I'm attempting to write some tests that test a form. If you don't know KnockoutJS, the short story for it is that it provides bindings from my view to my data model. This means that when I type a value in the an input field, my underlying object automatically gets updated with that input fields value. This is done through a change event by default.
The problem I am having is that when my WebDriver test is typing into the field, the change event is not firing so my underlying data model does not have the appropriate values. This causes my form validation to fail when it should not.
I've done everything I could find on the internet to make this work. I've:
sent the tab key
clicked away from the form field
send JavaScript code to fire focus and blur events (validation occurs on blur)
clicked the form field before typing
set waits just incase it was a timing issue
changed KnockoutJS to update input field on afterkeydown
None of these have worked for me.
In addition, I have verified that this is not an event bubbling issue as I removed all other events explicitly, leaving just the KnockoutJS change event.
for the solution i'm looking for is one that works for all browser drivers (... at least the main ones e.g. IE, FF, Chrome, Safari) and does not require the use of jQuery.
How do I solve the problem?
Here is the relevant code I'm using to type values into the field:
// find element
WebElement input = this.element.findElement(By.className("controls"))
.findElement(By.tagName("input"));
// to set focus?
input.click();
// erase any existing value (because clear does not send any events
for (int i = 0; i < input.getAttribute("value").length(); i++) {
input.sendKeys(Keys.BACK_SPACE);
}
// type in value
input.sendKeys(text);
// to fire change & blur? (doesnt fire change)
//input.sendKeys(Keys.TAB);
// to fire change & blur? (doesnt fire change)
driver.findElement(By.tagName("body")).click();
So I have found a way to work around this issue for now, but by far do I believe this is the correct solution. This does break my rule about not using jQuery, however I feel this is okay for me as KnockoutJS requires jQuery be loaded. There's probably a plain ol' JavaScript way of doing this. I have tested this with FireFox, Safari, and PhantomJS. I assume it will work just as well in Chrome. I give no promises for Internet Explorer.
I am NOT going to mark this answer as the correct answer. The correct solution should be through WebDriver browsers firing the proper events. Only when I believe this is not possible through WebDriver will I mark this as the correct answer.
// find element in question
WebElement input = this.element.findElement(By.className("controls"))
.findElement(By.tagName("input"));
// click it to fire focus event
input.click();
// erase any existing value
for (int i = 0; i < input.getAttribute("value").length(); i++) {
input.sendKeys(Keys.BACK_SPACE);
}
// enter in desired text
input.sendKeys(text);
// fire on change event (WebDriver SHOULD DO THIS)
((JavascriptExecutor) driver).executeScript(
"$(arguments[0]).change(); return true;"
, input);
// click away to fire blur event
driver.findElement(By.tagName("body")).click();
So I believe I have found out my problem. I will fully admit this was PEBKAC. I had forgotten that WebDriver has issues if the browser window is not in active focus on the machine (which is still weird to me). When I was debugging the problem, I was using my editor to step through the code. By running the code normally and without removing focus from the browser, the events fire as expected using all three solutions (tab, click-away, and javascript).
I have an example project showing all three methods, however I am a major noob with git and github and am having problems delivering the project. Once i figure that out, I will share the project with you all.
EDIT: Got the example code up on GitHub (https://github.com/loesak/knockout.webdriver.change.event.test). You can either start the project as a webapp in a server and run the test manually or you can run the tests via maven (mvn clean install). I didn't put a whole lot of effort into getting this to work robustly so it is assuming you have Firefox installed and port 0808 8080 is open.
EDIT: Fixed stated port number

iOS5 Safari: Keyboard does not hide in a home screen HTML app

I am working on a custom application for the iPad that runs as a homescreen app, but is made in all CSS/HTML/Javascript. (not using the SDK here)
I have run into an issue with a calculator I have built into my page not hiding the keyboard. No matter what I do, the keyboard stays up. I have searched this extensively and tried everything I can think of, but the keyboard stays up no matter what I do.
Explanation of what I have tried to hide the keyboard:
I have tried to blur all input fields to remove focus. I have tried setting focus onto non-text field items.
There were several threads on Stackoverflow from earlier this year/last year that suggested both of those options, but they do not appear to be working anymore.
To test further, I put a blank a href="#" on an img that was above the calculator, so that I could set focus on a non-entry and see if that would auto-minimize the keyboard. When I tap that item above the keyboard the focus changes and I am no longer in input mode, but the keyboard stays up.
Did Apple break this functionality with the latest update? If so, is there a work around?
Here is some example code that doesn't work:
$('input').blur(function(e) {
// Keyboard disappeared
window.scrollTo(0, 1);
});
That code successfully removes focus from the inputs, but the keyboard stays up. I have also attempted the inverse of that by just .focus ing on a non-text element. And additionally, as stated previously, I have straight-up just added a non-text element on the page and that still doesn't hide the keyboard.
Thanks so much for any help, and feel free to link/abuse me if I have mistakenly reposted. :)
you should be able to blur it just by using something like this
$('input').blur();
you should put this inside the function/procedure that happens when you want it to disappear, unless your looking to disable it completely?
document.activeElement.blur() inside a try catch block works for me. (Possibly you also need a setTimeout? I didn't need a timeout, and it is important to avoid timeouts wherever possible because they can easily cause nasty heisen-bugs!)
Also double check that you are not calling focus() somewhere within a mousedown or click event (which causes the keyboard to show). You can use a console.log(document.activeElement.tagName); or similar to help find what has current focus.
However if you don't find a solution then I am very interested in seeing how you get the keyboard to stay up... I have a use for that :-)

ANDROID WEBKIT: Select elements getting focus events, but not opening!

I have a series of select elements in a form on a mobile site. These select elements are inside a scrolling pane handled through JS and CSS3 transforms, so getting a touch/click/whatever event to register on the selects was enough of a pain in the first place. However, I'm now finding, on android only, that even though the selects are getting clicked, and are getting focus- they simply refuse to open. I'm 100% sure that the selects are getting their focus event (through debug), so honestly, I am completely stumped. Without the debug, there are no other focus/blur events on the selects. It works fine on iPhone... any ideas?
I've been banging my head against the wall with this same issue. It seems to be isolated to Android 2.1/2.2 (and maybe 2.0?). The selects work fine in Android 1.5/1.6. I even created a simple page that just changes the select's display style from none to block and the select still doesn't open consistently. Oddly, sometimes after page refresh it might work, then after another refresh it might be broken again. As you stated, focus and click/touch events do fire from the element, so I'm at a loss as to what the issue is.
Sometimes if I zoom the page I can get the select to open, but even then the value selected isn't represented in the select element on the page.
I submitted a bug report to the Android dev team, but even if it's fixed in future builds the problem will still exist in 2.1/2.2.
Anyone find a workaround for this yet?
//---- Update ------
If you use a webkit-transition to show/hide the element, attaching the following event to the element appears to fix the select inside of it:
.addEventListener("webkitTransitionEnd",function(e){
this.innerHTML = this.innerHTML;
},false);
I'm not entirely sure why this works, but re-writing the element to the DOM seems to help for some reason. Tested in Android 2.1/2.2 simulator, EVO4G and MyTouch.
I found the solution in this answer by a.meservy. Here is the answer, copied for everyone's convenience.
In this case the problem was actually caused by jQTouch. To fix it, just comment out these 4 lines in jqtouch.css
Under "body"
/*-webkit-perspective: 800;*/
/*-webkit-transform-style: preserve-3d;*/
Under "body > * "
/*-webkit-backface-visibility: hidden;*/
/*-webkit-transform: translate3d(0,0,0) rotate(0) scale(1);*/

How do I trigger the browser context menu on an element. (As if the user right-clicked)

I have the need to trigger the opening of the browser (IE, Firefox, Safari, etc) context-menu via javascript. The problem I am trying to solve, is when an overlaid element is right-clicked, the element below it shows its context menu. So if the top element is a label, when you right click, I need to show the context menu for the input element below.
I know how to keep the label's context menu from showing, but I don't know how to open a context menu arbitrarily.
Any help is appreciated!
Sorry to be the bearer of unfortunate news, but this is impossible to do with Javascript.
I don't want to frustrate you, quite the contrary, especially because you answered my own question :)
I don't think that a browser's contect menu is accessible via an ordinary script on a web page.
If what you are asking for was actually doable, then the browser makers would possibly consider this a bug and remove this behavior. Cross-browser, this behavior is very unlikely to be available today.
Why don't you capture mouse events, and whenever the mouse is directly in the area of the element below that you want to show the context menu for, push the covering element below, otherwise back on top?
That is one possiblity I could think of, basically revealing/exposing the hidden element depending on mouse position. Like cutting a hole into the overlay.
Or why don't you make the text field transparent and put the overlay below the text field entirely?
If this does not work out technically, then at least you have a point in filing bugs or enhancements against the targeted browsers.
BTW it looks like the context menu actually works if the user right-clicks directly at the position of the caret, so this might be another loophole for you to consider.
I have a possible solution that may suit your needs. It is not perfect yet, I have only done a few quick tests in a few browsers (Fox 3.6, IE7, IE8, Chrome 4, Safari 3 on xp) It will need to be tweaked and improved but its a start. Basically the idea is to remove the label on right-click mousedown so that the desired field is hit by the mouseup event and therefore fires up the context menu on the relevant field.
// Remove the contextmenu from "In-Field" Labels
base.$label.bind("contextmenu",function(e){
return false;
});
// Detect right click on "In-Field" label:
// hide label on mousedown so mouseup will target the field underneath.
base.$label.mousedown(function(e){
if ( e.which == 3 ){
var elLbl = $(this);
elLbl.hide();
var elFid = $(this).attr("for");
// bind blur event to replace the label when we are done.
$("#" + elFid ).bind("blur.infieldlabel",function(){
elLbl.show();
$("#" + elFid ).unbind("blur.infieldlabel");
});
return false;
}
});
The IE and Safari browsers experience a strange issue where you need to click in and out twice before the label will display again (something to do with event timing I think). You may be able to easily see why this is happening by looking at the code. Also noticed slight glitch sometimes in the fox after pasting into the field, on blur the label appeared for a split second when it should not. This should be a fairly simply thing to rectify if you decide to incorporate this method into your code.
You can make Your label/span element contenteditable="true" and handle any further actions with listeners. Making it contenteditable will enable normal, input-like contextmenu to show up on right click.
And if someone doesn't care for IE support:
pointer-events: none
Type the following in the console:
document.oncontextmenu = reEnable
That will print to the console the following:
reEnable()
{
return true;
}
Done, you can now use the context menu.

Categories

Resources