Sean
Sean

Reputation: 907

Finding part of a string via javascript

I have the following HTML check box

<input name="1" title="" id="1"  style="position: absolute; top: 333px; left: 760px; tabindex: 11; z-order: 99;" type="checkbox" CHECKED="checked" runat="server" value="on"/>

I want to grab the value given for tabindex inside the style attribute above. Things to note:

  1. I know that tabindex is in the wrong place (it shouldn't be in the style attribute text, it should be an attribute on its own). I can't change that, it's done by a (very old) tool I can't modify.

  2. I have to support IE8, and when I tried I ran into an issue with IE8 not handling \s in regular expressions quite correctly (it doesn't match hard spaces).

I tried to use .search() to do this but I don't know how to return the string value when I'm searching for my checkbox with the following line:

var test = document.getElementsByTagName("input");

The goal is to grab the value for tabindex from the style attribute and then assign it to the element correctly.

Upvotes: 3

Views: 84

Answers (3)

T.J. Crowder
T.J. Crowder

Reputation: 1074495

Updated Answer:

Re your comment:

I know it's in the wrong place, but I've no way of manually moving it.

Okay, so that's why we're using regex, gotcha.

So we have two tasks here:

  1. Get the text of the style attribute, which should be easy but is stupidly difficult on IE8.

  2. Get the value of the tabindex from that text.

First, getting the style attribute text: Unfortunately, by default IE8 will display "intranet" sites in the ridiculously-misnamed "compatibility view". (That is: Compatible with old broken IE7 and earlier, not compatible with, you know, standards.) And IE7 and earlier had a horrible bug: element.getAttribute("style") gave you the style object, not the style attribute text; the same object you get with element.style. And although they fixed that in IE8, in compatibility view it's broken (to be..."compatible").

So this:

var text = element.getAttribute("style"):

...will give us a string on any decent browser, and on IE8 when not in compatibility view, but will give us an object when in compatibility view.

So to get the text we have to look elsewhere. Fortunately, Microsoft were the ones who pioneered innerHTML and outerHTML, so we can do this:

var text = element.getAttribute("style"):
if (typeof text !== "string") {
    text = element.outerHTML;
}

That gives us more than just the style text, of course, but it's close enough. We're still not trying to parse HTML with regex (although we're pushing it a bit with outerHTML, but it's on an input and so fairly contained), we're looking for a limited thing within a limited string..

Now from that text we need the tabindex value: This expression matches tabIndex (case-insensitive) followed by any whitespace followed by : followed by whitespace followed by some number of digits, which we capture:

/\btabindex\s*:\s*(\d+)/i

We can then use the capture group to get the value from the incorrect location and set it in the correct location:

var element = document.getElementById("1");
var text = element.getAttribute("style");
if (typeof text !== "string") {
    // Bad IE! Bad!
    text = element.outerHTML;
}
var match = /\btabindex\s*:\s*(\d+)/i.exec(text);
var index = match && match[1];
if (index) {
    element.setAttribute("tabindex", index);
}
alert("Index: " + (index || "unknown"));

Live Example:

var element = document.getElementById("1");
var text = element.getAttribute("style");
if (typeof text !== "string") {
    // Bad IE! Bad!
    text = element.outerHTML;
}
var match = /\btabindex\s*:\s*(\d+)/i.exec(text);
var index = match && match[1];
if (index) {
    element.setAttribute("tabindex", index);
}
alert("Index: " + (index || "unknown"));
<input name="1" title="" id="1"  style="position: absolute; top: 333px; left: 760px; tabindex: 11; z-order: 99;" type="checkbox" CHECKED="checked" runat="server" value="on"/>

Re your comment:

But would the above still work if i changed the first line to document.getElementsByTagName("input");

Sure, you just do it in a loop:

var list, index, element, text, match;
list = document.getElementsByTagName("input");
for (index = 0; index < list.length; ++index) {
    element = list[index];
    text = element.getAttribute("style");
    if (typeof text !== "string") {
        // Bad IE! Bad!
        text = element.outerHTML;
    }
    match = /\btabindex\s*:\s*(\d+)/i.exec(text);
    tabindex = match && match[1];
    if (tabindex) {
        element.setAttribute("tabindex", tabindex);
    }
}

(I called the tabindex tabindex there, since loop indexes are frequently called index.)


Original Answer:

Your tabIndex is in the wrong place: It's not a style property, it's a stand-alone attribute:

<input name="1" title="" id="1" tabindex="11" style="position: absolute; top: 333px; left: 760px; z-order: 99;" type="checkbox" CHECKED="checked" runat="server" value="on"/>
<!-- Here ----------------------^                                                       -->

Then use the tabIndex reflected property:

var index = document.getElementById("1").tabIndex;

Live Example:

alert(document.getElementById("1").tabIndex);
<input name="1" title="" id="1" tabindex="11" style="position: absolute; top: 333px; left: 760px; z-order: 99;" type="checkbox" CHECKED="checked" runat="server" value="on"/>


Side note: While valid in HTML, id values starting with digits are very difficult to work with in CSS; best to avoid them.

Upvotes: 9

dcremo
dcremo

Reputation: 11

First, you should use getElementById which is more appropriate in complex scenarios. If you want to access the raw string value of your attribute you can use:

document.getElementById("1").getAttribute("style")

and then process it as you wish (using search, substr, etc.)

Upvotes: 0

Dropout
Dropout

Reputation: 13866

Never parse HTML elements by regex. See this question for some fun.

If you have an HTML element you can access all of it's attributes either via .getAttribute or in case of CSS style attributes using for example .style.top for the top attribute.

The problem in your case is probably that you are placing your tabindex property inside the style attribute. According to this page, you should set it as a separate attribute, so you can get it afterwards by

document.getElementById("1").getAttribute("tabindex");

Upvotes: 0

Related Questions