Debugging "Element is not clickable at point" error - google-chrome

I see this only in Chrome.
The full error message reads:
"org.openqa.selenium.WebDriverException: Element is not clickable at point (411, 675). Other element would receive the click: ..."
The element that 'would receive the click' is to the side of the element in question, not on top of it and not overlapping it, not moving around the page.
I have tried adding an offset, but that does not work either. The item is on the displayed window without any need for scrolling.

This is caused by following 3 types:
1.The element is not visible to click.
Use Actions or JavascriptExecutor for making it to click.
By Actions:
WebElement element = driver.findElement(By("element_path"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().perform();
By JavascriptExecutor:
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("scroll(250, 0)"); // if the element is on top.
jse.executeScript("scroll(0, 250)"); // if the element is on bottom.
or
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].scrollIntoView()", Webelement);
Then click on the element.
2.The page is getting refreshed before it is clicking the element.
For this, make the page to wait for few seconds.
3. The element is clickable but there is a spinner/overlay on top of it
The below code will wait until the overlay disppears
By loadingImage = By.id("loading image ID");
WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
wait.until(ExpectedConditions.invisibilityOfElementLocated(loadingImage));
Then click on the element.

You can also use JavaScript click and scrolling would be not required then.
IJavaScriptExecutor ex = (IJavaScriptExecutor)Driver;
ex.ExecuteScript("arguments[0].click();", elementToClick);

There seems to be a bug in chromedriver for that (the problem is that it's marked as won't fix)
--> GitHub Link
(place a bounty on FreedomSponsors perhaps?)
There's a workaround suggested at comment #27.
Maybe it'll work for you-

I had the same issue, tried all offered solutions but they did not work for me.
eventually I used this:
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("var evt = document.createEvent('MouseEvents');" + "evt.initMouseEvent('click',true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0,null);" + "arguments[0].dispatchEvent(evt);", findElement(element));
Hope this helps

Wow, a lot of answers here, and many good ones.
I hope I'll add something to this from my experience.
Well guys, in my case there was a cookie overlay hiding the element occasionally.
Scrolling to the element also works; but in my humble opinion (for my case, not a panacea for everyone) the simplest solution is just to go full screen (I was running my scripts on a 3/4 of the screen window)! So here we go:
driver.manage().window().maximize();
Hope that helps!

You need to use focus or scroll on that element. You also might have to use explict wait.
WebElement firstbutton= driver.findElement(By.xpath("Your Element"));
Actions actions = new Actions(driver);
actions.moveToElement(element);
actions.perform();
OR
The element is not clickable because of a Spinner/Overlay on top of it:
By loadingImage = By.id("loading image ID");
WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
wait.until(ExpectedConditions.invisibilityOfElementLocated(loadingImage));
OR
Point p= element.getLocation();
Actions actions = new Actions(driver);
actions.moveToElement(element).movebyoffset(p.x,p.y).click().perform();
OR
If still not work use JavascriptExecutor
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", firstbutton);

I have seen this in the situation when the selenium driven Chrome window was opened too small. The element to be clicked on was out of the viewport and therefore it was failing.
That sounds logical... real user would have to either resize the window or scroll so that it is possible to see the element and in fact click on it.
After instructing the selenium driver to set the window size appropriately this issues went away for me. The webdriver API is decribed here.

I was getting this error when running tests headless with xvfb-run. They were working flawlessly locally. Using chrome, versions of webdriver / chromedriver / chrome / java etc all identical.
The ‘won’t fix’ bug in chromedriver - GitHub Link pointed out by Tony Lâmpada suggested this may be related to what is / isn't visible on the screen.
Help message for xvfb-run shows the following:
-s ARGS --server-args=ARGS arguments (other than server number and
"-nolisten tcp") to pass to the Xvfb server
(default: "-screen 0 640x480x8")
Changing the resolution for xvfb made the error go away:
xvfb-run -s "-screen 0 1280x1024x16" ...

ruby/watir-webdriver/chrome
I use the following trick and seems like it works:
#scroll to myelement
#browser.execute_script "window.scrollTo(#{myelement.element.wd.location[0]},#{myelement.element.wd.location[1]})"
# click myelement
myelement.when_present.fire_event("click")

I, too, wrestled with this problem. Code works fine in FF, fails on Chrome. What I was trying to do was to click a tickbox - if it wasn't in view, I'd scroll to view and then click. Even scrolling into view works in Chrome, only the bottom few pixels of the tickbox wasn't visible so webdriver refused to click on it.
My workaround is this:
WebElement element = _sectorPopup.findElement(...);
((Locatable) element).getCoordinates().inViewPort();
try {
element.click();
} catch (Exception e) {
new Actions(getWebDriver()).sendKeys(Keys.PAGE_DOWN).perform();
element.click();
}
Chrome also has issues with sendKeys, using Actions is sometimes necessary. Obviously, you need to know which direction and how much you need to go so your mileage may vary. But I prefer this to the javascript hack, so I'm posting it here in case someone else will find it useful.

First, try to get the latest Chrome driver and check if it solves the issue.
In my case, it didn't fix the issue. But, the following solution worked for me so far. The following is C# code but you can follow same logic in your specific language. What we do here is,
Step 1: Focus on the element using the Selenium Actions object,
Step 2: Then do a click on the element
Step 3: If there's an exception, then we trigger a javascript "Click" event on the element by executing the javascript script through the Selenium browser driver's "ExecuteScript" method.
You can also skip step 1 and 2 and try only step 3 too. Step 3 would work on it's own but I noticed some strange behavior in one scenario in which step 3, even though it successfully clicked the element, caused unexpected behavior in other parts of my code after clicking the element.
try
{
//Setup the driver and navigate to the web page...
var driver = new ChromeDriver("folder path to the Chrome driver");
driver.Navigate().GoToUrl("UrlToThePage");
//Find the element...
var element = driver.FindElement(By.Id("elementHtmlId"));
//Step 1
new Actions(driver).MoveToElement(element).Perform();
//Step 2
element.Click();
}
catch (Exception)
{
//Step 3
driver.ExecuteScript("document.getElementById('elementHtmlId').click();");
}

I was getting the same issue while running selenium script in python. Here is what I used to click on the element:
from selenium.webdriver.common.action_chains import ActionChains
ActionChains(driver).click(element).perform()

When using Protractor this helped me:
var elm = element(by.css('.your-css-class'));
browser.executeScript("arguments[0].scrollIntoView();", elm.getWebElement());
elm.click();

I made this method based on a comment from Tony Lâmpada's answer. It works very well.
def scroll_to(element)
page.execute_script("window.scrollTo(#{element.native.location.x}, #{element.native.location.y})")
end

Today I got the same kind of issue. You don't believe me if i say how i solved the issue.
By maximizing the browser size
Yes, it is a pointer issue that means the size of the browser. For that, you just need to maximize the window size manually or through the code.

I was facing a similar problem whre i have to check two check boxes one after the other.But i was getting the same above error.hence i added wait in between my steps for checking the checkboxes....its working fine and great.here are the steps:-
When I visit /administrator/user_profiles
And I press xpath link "//*[#id='1']"
Then I should see "Please wait for a moment..."
When I wait for 5 seconds
And I press xpath link "//*[#id='2']"
Then I should see "Please wait for a moment..."
When I visit /administrator/user_profiles_updates

The reason for this error is that the element that you are trying to click is not in the viewport (region seen by the user) of the browser. So the way to overcome this is by scrolling to the desired element first and then performing the click.
Javascript:
async scrollTo (webElement) {
await this.driver.executeScript('arguments[0].scrollIntoView(true)', webElement)
await this.driver.executeScript('window.scrollBy(0,-150)')
}
Java:
public void scrollTo (WebElement e) {
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeAsyncScript('arguments[0].scrollIntoView(true)', e)
js.executeAsyncScript('window.scrollBy(0,-150)')
}

Apparently this is the result of a "Won't Fix" bug in the Chrome driver binary.
One solution that worked for me (Our Mileage May Vary) can be found in this Google Group discussion, Comment #3:
https://groups.google.com/forum/?fromgroups=#!topic/selenium-developer-activity/DsZ5wFN52tc
The relevant portion is right here:
I've since worked around the issue by navigating directly to the href of
the parent anchor of the span.
driver.Navigate().GoToUrl(driver.FindElement(By.Id(embeddedSpanIdToClick)).FindElement(By.XPath("..")).GetAttribute("href"));
In my case, I'm using Python, so once I got the desired element, I simply used
driver.get(ViewElm.get_attribute('href'))
I would expect this to only work, however, if the element you are trying to click on is a link...

Re Tony Lâmpada's answer, comment #27 did indeed solve the problem for me, except that it provided Java code and I needed Python. Here's a Python function that scrolls to the element's position and then clicks it.
def scroll_to_and_click(xpath):
element = TestUtil.driver.find_element_by_xpath(xpath)
TestUtil.driver.execute_script('window.scrollTo(0, ' + str(element.location['y']) + ');')
element.click()
This solved the problem for me in Chrome 34.0. It caused no harm in Firefox 28.0 and IE 11; those browsers aren't subject to the problem, but scrolling to the element's position before clicking it still isn't a bad thing.

This might happen if the element changes position while the driver is attempting to click it (I've seen this with IE too). The driver retains the initial position but by the time it actually gets to clicking on it, that position is no longer pointing to that element. The FireFox driver doesn't have this problem BTW, apparently it "clicks" elements programmatically.
Anyway, this can happen when you use animations or simply change the height of elements dynamically (e.g. $("#foo").height(500)). You need to make sure that you only click elements after their height has "settled". I ended up with code that looks like this (C# bindings):
if (!(driver is FirefoxDriver))
{
new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(
d => d.FindElement(By.Id(someDynamicDiv)).Size.Height > initialSize);
}
In case of an animation or any other factor you can't easily query for, you can utilize a "generic" method that waits for the element to be stationary:
var prevLocation = new Point(Int32.MinValue, Int32.MinValue);
int stationaryCount = 0;
int desiredStationarySamples = 6; //3 seconds in total since the default interval is 500ms
return new WebDriverWait(driver, timeout).Until(d =>
{
var e = driver.FindElement(By.Id(someId));
if (e.Location == prevLocation)
{
stationaryCount++;
return stationaryCount == desiredStationarySamples;
}
prevLocation = e.Location;
stationaryCount = 0;
return false;
});

I met this because a loading dialog cover on this element. I simplely solve it by add a waiting before working with the this element.
try {
Thread.sleep((int) (3000));
} catch (InterruptedException e) {
//
e.printStackTrace();
}
Hope this help!

Explanation of error message:
The error message simply says, that the element you want to click on is present, but it is not visible. It could be covered by something or temporary not visible.
There could be many reasons why the element is not visible in the moment of the test. Please re-analyse your page and find proper solution for your case.
Solution for particular case:
In my case, this error occures, when a tooltip of the screen element i just clicked on, was poping over the element I wanted to click next. Defocus was a solution I needed.
Quick solution how to defocus would be to click to some other element in another part of the screen which does "nothing" resp. nothing happens after a click action.
Proper solution would be to call element.blur() on the element poping the tooltip, which would make the tooltip disapear.

I was facing the same problem with clj-webdriver (clojure port of Selenium). I just translated the previous solution to clojure for convenience. You can call this function before doing click or whatever to avoid that problem.
(defn scrollTo
"Scrolls to the position of the given css selector if found"
[q]
(if (exists? q)
(let [ loc (location-once-visible q) jscript (str "window.scrollTo(" (:x loc) "," (:y loc) ")") ]
(execute-script jscript))))

Maybe it's not really clean solution but it works:
try:
el.click()
except WebDriverException as e:
if 'Element is not clickable at point' in e.msg:
self.browser.execute_script(
'$("{sel}").click()'.format(sel=el_selector)
)
else:
raise

I was getting this bug because I tested a hover and then needed to click on the link underneath the tooltip. The solution was to add page.find('.sp-logo').hover before click_link to get the tooltip out of the way.

It's funny, all the time I spent looking at the various responses, no one had tried the obvious, which of course, I hadn't either. If your page has the same id used multiple times, as mine did, ("newButton",) and the one you want is not the first one found, then you will in all likelihood get this error. The easiest thing to do (C#):
var testIt = driver.FindElements(By.Id("newButton"));
Note it's FindElements, not FindElement.
And then test to see how many results came back from the retrieval. If it's the second one, you can then use:
testit[1].Click();
Or get whomever reused ids to fix them.

After testing all mentioned suggestions, nothing worked. I made this code. It works, but is not beautiful
public void click(WebElement element) {
//https://code.google.com/p/selenium/issues/detail?id=2766 (fix)
while(true){
try{
element.click();
break;
}catch (Throwable e){
try {
Thread.sleep(200);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
}
public void click(String css) {
//https://code.google.com/p/selenium/issues/detail?id=2766 (fix)
while(true){
try{
driver.findElement(By.cssSelector(css)).click();
break;
}catch (Throwable e){
try {
Thread.sleep(200);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
}

I do a kind of brute force of clicks and it works for me.
try:
elem.click()
except:
print "failed to click"
size = elem.size
mid_of_y = int(size["height"])/2
stepts_to_do_to_left = int(size["width"])
while stepts_to_do_to_left > 0:
try:
print stepts_to_do_to_left, mid_of_y
action = webdriver.common.action_chains.ActionChains(driver)
action.move_to_element_with_offset(elem, mid_of_y, stepts_to_do_to_left)
action.click()
action.perform()
print "DONE CLICK"
break
except:
pass

If you have jQuery loaded on the page, you can execute the following javascript command:
"$('#" + element_id + "').click()"
Example using python executor:
driver.execute_script("$('#%s').click()" % element_id)

Try to maximize the browser when you are working with resolutions greater than 1024x768.
driver.manage().window().maximize();

Related

Java Selenium findelement is not acknowledging an element that is on the page

If I use developer tools in Chrome, and paste my By.name statement, the page highlights exactly what I'm trying to view.
Here are two java statements sitting right next to each other:
driver.findElement(By.xpath("//input[#name='firstName']")).clear();
driver.findElement(By.xpath("//input[#name='shippingCost']")).click();
I put these two next to each other to rule out that the driver was broken somehow at the point in the code that these come from. The first statement does clear the text box referenced, but the second is returning NoSuchElementError. I have also tried using By.name as mentioned above, I'm just chasing down why the second throws an error every time.
The page I'm working with is an EXTJS single page website, so the control is always there. I want to use the .getText().length() to validate that there is now text in this box.
Any help on why I'm unable to click, or even just reference this control, on a page where I'm able to use my xpath or name selectors to see the control on the page.
---Edit to add these pics of the code relevent to the above xpaths
Sorry, this is another place that doesnt work, [name='shippingTypeGroundDate']
This is the shippingcost location
And this is the working firstName location
Check whether if there is any duplicate elements in the chosen selector. According to your description name field is working as expected and you are facing issues with the shipping cost field. it is possible that there are duplicate elements in inactive status on the same page with the chosen selector.
you can get number of elements present using below java code :
List<WebElement> listOfElements =driver.findElements(By.xpath("//input[#name='shippingCost']"));
System.out.println("Number of elements:" +listOfElements.size());
if above solutions not working, try with javascriptexecutor , it will perform these actions even if this element is underneath another element.
Add explicit wait for the input textbox to be loaded. Then try to click the textbox with Javascript executor. Sometimes webdriver click may not work.
WebElement element = driver.findElement(By.xpath("//input[#name='shippingCost']"));
try {
if (element.isEnabled() && element.isDisplayed()) {
((JavascriptExecutor) driver).executeScript("arguments[0].click();", element);
} else {
System.out.println("Unable to click on element");
}
} catch (StaleElementReferenceException e) {
System.out.println("Element is not attached to the page document "+ e.getStackTrace());
} catch (NoSuchElementException e) {
System.out.println("Element was not found in DOM "+ e.getStackTrace());
} catch (Exception e) {
System.out.println("Unable to click on element "+ e.getStackTrace());
}

puppeteer element.click() not working and not throwing an error

I have a situation where a button, on a form, that is animated into view, if the element.click() happens while the animation is in progress, it doesn't work.
element.click() doesn't throw an error, doesn't return a failed status (it returns undefined) it just silently doesn't work.
I have tried ensuring the element being clicked is not disabled, and is displayed (visible) but even though both those tests succeed, the click fails.
If I wait 0.4s before clicking, it works because the animation has finished.
I don't want to have to add delays (which are unreliable, and a bodge to be frank), if I can detect when a click worked, and if not automatically retry.
Is there a generic way to detect if a click() has actually been actioned so I can use a retry loop until it does?
I have determined what is happening, and why I don't get an error, and how to work around the issue.
The main issue is with the way element.click() works. Using DEBUG="puppeteer:*" I was able to see what is going on internally. What element.click() actually does is:-
const box = element.boundingBox();
const x = box.x + (box.width/2);
const y = box.y + (box.height/2);
page.mouse.move(x,y);
page.mouse.down();
sleep(delay);
page.mouse.up();
The problem is that because the view (div) is animating the element's boundingBox() is changing, and between the time of asking for the box position, and completing the click() the element has moved or is not clickable.
An error isn't thrown (promise rejected) because its just a mouse click on a point in the viewport, and not linked to any element. The mouse event is sent, just that nothing responds to it.
One workaround is to add a sufficient delay to allow the animation to finish. Another is to disable animations during tests.
The solution for me was to wait for the position of the element to settle at its destination position, that is I spin on querying the boundingBox() and wait for the x,y to report the elements previously determined position.
In my case, this is as simple as adding at 10,10 to my test script just before the click, or specifically
test-id "form1.button3" at 10,10 click
And in action it works as follows, in this case, the view is being animated back in from the left.
00.571 [selector.test,61] at 8,410
test-id "main.add" info tag button displayed at -84,410 size 116,33 enabled not selected check "Add"
test-id "main.add" info tag button displayed at -11,410 size 116,33 enabled not selected check "Add"
test-id "main.add" info tag button displayed at 8,410 size 116,33 enabled not selected check "Add"
00.947 [selector.test,61] click
It wouldn't work for an element that was continually moving or for an element that is covered by something else. For those cases, try page.evaluate(el => el.click(), element).
Generic click with timeout function inspired by Andrea's answer. This one returns as soon as the element is clickable, so won't slow down tests.
click: async function (page, selector, timeout = 30000) {
await page.waitForSelector(selector, { visible: true, timeout })
let error;
while (timeout > 0) {
try {
await page.click(selector);
return;
} catch (e) {
await page.waitFor(100);
timeout -= 100;
error = e;
}
}
throw error;
}
The page.click() returns a promise, make sure to handle it as such, but also note that you may have issues if you are not referencing it as an xpath. That's what I had to do in order to get it working. I've tried using querySelectors and interacting with the objects that way, but I ran into issues.
page.evaluate(()=>{
await Promise.all([
page.click("a[id=tab-default-2__item]"),
//The page.waitFor is set to 15000 for my personal use.
//Feel free to play around with this.
page.waitFor(15000)
]);
});
I hope this helps.
i use a helper function to handle click
click: async function (page, selector) {
//selector must to exists
await page.waitForSelector(selector, {visible: true, timeout: 30000})
//give time to extra rendering time
await page.waitFor(500)
try {
await page.click(selector)
} catch (error) {
console.log("error clicking " + selector + " : " + error ;
}
}
using page.waitFor(500) is a VERY BAD PRACTICE in a THEORICAL WORLD, but it remove a lot of false positive in the practical with complex interfaces.
i prefer to wait 500ms more than obtain a false positive.
I've just had a very similar problem: I had Puppeteer script that used to work and now suddenly click stopped working. The culprit turned out to be zoom level. It started working again once I switched zoom to 100%. Apparently, Puppeteer does not adjust click coordinates to zoom level.
For me below code did the trick
const element = await page.$('[name="submit"]')
await this.page.evaluate(ele => ele.click(), element);

Element is not clickable in Firefox

I have problem with this kind of error:
Element is not clickable at point (791, 394). Other element would receive the click:
Command duration or timeout: 66 milliseconds
Anyone knows what is about? I am using selenium web driver 2.52 and firefox version 43.5
This is part of the code:
private static void waitForLoadingSpinner() throws Exception {
log("wait for loading spinner");
Thread.sleep(1000);
element = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//div[#id='loadingGlassPane']")));
element.click();
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[#id='loadingGlassPane']")));
After checking cities for example my apply button is not working.
Try with following code.
WebDriverWait wait =new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeClickable(By locator)).click();
From my own experience: When running automation in Firefox, if you want to click on a dojo button (seems what you are using), you can do it in 2 ways:
1) You should find the 'clickable' node - look at the picture below
2) Use your original button, but call: actions.moveToElement(yourButton).click()
I have solved my problem adding this part:
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("scroll(250, 0)");
js.executeScript("scroll(0, 250)");
Hope this will help someone :)
Regards

Strange IE11 form fields bug after selecting from dropdown

I'm experiencing a major bug in IE 11 (latest version 11.0.9600.16521 on Windows 7). When on any form if I open a select dropdown all the other form fields on the page freeze. I can 'unfreeze' them by adjusting the Window size (causing a redraw). This seems to happen on any form what-so-ever.
To reproduce:
Open IE 11.0.9600.16521
Go to http://www.wikipedia.org/
Select any language from the language dropdown
Result:
language dropdown does not appear to get updated on the screen
the search box appears to be frozen - i.e. focus on select box and start typing but no text appears. However if you adjust the window size the form fields are updated and go back to working as normal (until you interact with another select element)
I can't find much in Google for this issue so maybe it's just something specific to my settings. Only thing that sounds somewhat similar to what I'm experiencing is this: http://connect.microsoft.com/IE/feedback/details/806679/ie-11-desktop-selecting-an-item-from-a-drop-down-list-on-a-webpage-causes-the-tab-to-crash. Anyone else able to reproduce this?
I had a similar issue with IE11 that turned out to be any modification to the .text property of an SELECT-option element. I eventually found the "hint" on stackoverflow here
How to fix IE select issue when dynamically changing options.
In my case I use straight JavaScript, and with so many inter-dependent SELECT boxes had to come up with a generic solution, so my solution was to intercept (defineGetter) assignment to any .text property of an HTMLOptionElement, and set a 1 ms timer to perform an add element and remove element as in the referenced post that is titled "I have the fix. We have to add and remove options list to trigger the rendering in IE8." Notice the reference to IE8, AFAIK IE has had several issues with SELECT boxes since at least IE7, possibly earlier.
So the code I added to one of my global scripts is as follows:
try { var IE11; // IE10 and IE11 removed ActiveXObject from the window object but it can still be instantiated
IE11 = new ActiveXObject('MSXML2.DOMDocument.6.0');
IE11 = null;
if (typeof(HTMLOptionElement) != "undefined") {
try { HTMLOptionElement.prototype.__defineSetter__(
'text',
function(original) {
return function(newValue) { var sel;
original.call(this, newValue);
if (!(sel=this.parentElement).fixIE) sel.fixIE = window.setTimeout(_fixIE_(sel), 1);
}
}(HTMLOptionElement.prototype.__lookupSetter__('text')));
} catch(e) {};
}
} catch(e) {}
}
// IE11 broke SELECT boxes again, modifying any options .text attribute "freezes" the SELECT so it appears disabled
function _fixIE_(selBox) {
return _fixIE_;
function _fixIE_(){ var lc = selBox.options.length;
selBox.options.add(new Option('',''));
selBox.options.remove(lc);
selBox.fixIE = undefined;
}
}
Phil
Go to programs
Then widdcom folder
Right click bttray
Go compatibility
Tick run as admin
Restart
I had the same problem in IE 11 on Dell Windows 7.
It was solved by turning off hardware rendering in IE, as you suggested in your link.

TabIndex - hitting tab moves me to Address Bar - unable to work around this using Focus or +tab indexes

I read several threads that talk about how the Address Bar in IE is basically the first one to get focus when using TAB (MSDN's own docs talk about this).
Yet, I have seen situations where this doesn't always have to be the case....
I have a master page and inside my content area is a formView.
It defaults to INSERT view and can never leave it (they can only insert not edit and reading is handled elsewhere)
So on my page load for the page I have:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If fvwLogEntry.CurrentMode = FormViewMode.Insert = True Then
'Set the default field to position the cursor there...hopefully
Dim FCtxtHrEmployeeId As TextBox
FCtxtHrEmployeeId = CType(fvwLogEntry.FindControl("txtHrEmployeeId"), TextBox)
Page.SetFocus(FCtxtHrEmployeeId.ClientID.ToString)
End If
Now that works, when the page loads it sets the cursor to the employeeID text box inside the formview's INSERT template.
HOWEVER, when I hit TAB it takes me to the address bar and THEN if I hit tab again it takes me through the rest of the items on the page.
I set the tab index of the first item to 11 and then incrimented from there (I had read that IE's toolbars have tab indexes too so I thought perhaps using a higher number would bypass those, but again that doesn't REALLY make sense since it would still start at the lowest number, but I gave it a shot thinking it would move forward from where the focus was set.) If I click on the textbox and then hit TAB it DOES move through the page like I would expect.
It is just when the page loads and gets the focus set to the employeeID textbox that hitting tab moves it to the address bar.
I also tried setting the other controls to -1 (those I didn't want it to tab to), still no luck there.
So... what can I do to get around this?
There MUST be a simple way to set the focus to the employeeID textbox and ensure that pressing TAB after that moves to the next control in the formview's insert template and does NOT jump up to the address bar?
The following jquery code seems to be working fine for me..
$(window).load(function () {
$('.myClass :visible:input:enabled:first').focus();
});
$('body').on('keydown', '.myClass :visible:input:enabled:first', function (e) {
if ((e.which == 9) || (e.keyCode == 9)) {
$('.myClass :visible:input:enabled:first').focus();
}
});
I found another better option which is fastest as of what I tried.
Here's the code for that
function handleTabOrder() {
$('.myClass :visible:input:enabled').each(function (index) {
$(this).attr('tabindex', index + 10);
});
$('.myClass :visible:input:enabled:first').keydown(function (e) {
if (e.keyCode == 9 || e.which == 9) {
$("[tabindex=10]").focus();
}
});
}
What I have done here is to assign Tab order to all the visible controls on the page, then I have handled the key down event of only first control(that shifts the control to address bar) and now it shifts the control to next visible input item on the screen..
Its just a work around but works faster than any of the other things mentioned in the thread.
Just write the above function and all it in on-load event of page.
I was having this issue as well. For me, it was being caused by the use of the .select() method in order to bring focus automatically on a text field as soon as the page loaded. I changed my code to instead use JQuery's .focus() method and that resolved the issue.
I faced similar problem in IE. After some analysis I found that, this problem occurs if there is any HTML content outside form.
for example:
<html>
<div id="1">
</div>
<form>
//other code
</form>
</html>
It worked for me, after I moved all HTML inside form tag.
<html>
<form>
<div id="1">
</div>
//other code
</form>
</html>
Have a look at: http://www.w3schools.com/tags/att_global_tabindex.asp
Your txtHrEmployeeId element should have tabindex 1 and all other elements should have higher values.
-1 is not valid
Also verify that the tabindex are correct in the html that gets rendered (right-click in page and "view source").
I realize this is an old post, but an even simpler method is to add a "tab-stop" attribute to the form element with the last tabindex. Then bind a keydown listener and force focus to the first tabindex when the tab-stop is encountered.
Here's a simple example:
<input type="text" tab-stop />
$document.bind("keydown", function(event) {
var attrs = event.currentTarget.activeElement.attributes;
if (attrs['tab-stop']) {
angular.element.find('select')[0].focus();
event.preventDefault();
}
});
};
The answer mentioned in my other post works fine but it made the page take a huge performance hit because with every key press on the page the whole DOM was being searched for the elements.
So I found a new more optimized solution
var myNameSpace = function(){
this.selector = '.myClass :visible:input:enabled:first';
this.myElement = $(selector);
this._body = $('body');
var _self= this;
this._body.on('keydown',_self.selector,function(e){
if ((e.which == 9) || (e.keyCode == 9)) {
_self.myElement.focus();
}
});
};
The general idea being to 'cache' the node to be accessed. No need to traverse the DOM again and again for just selecting.
I had this same problem. It turns out mine was related to the ajax modal popup extenders. a modal popup was being shown, even though technically i could not see it because it was wrapped inside a parent div that was hidden. if you are using modal popup extenders, this could be causing an issue like this.
If you are using JSF or Primefaces, you can make use of:
<p:focus for"formname"></p:focus>