2

When I have an HTML like this:

<input type="text" id="a" value="" />
<input type="text" id="b" />

If I do a $("#a").val() I cannot distinguish if exists a value and this is empty or if no value exists. Is there any way to distinguish these two cases?

3
  • 2
    What's the practical difference? Commented Oct 18, 2011 at 13:03
  • I have a "date" input that must set to today date iff don't have any value. In case it has a value="" it must remain empty Commented Oct 18, 2011 at 13:07
  • Note that none of the posted solutions work in IE8... Commented Oct 18, 2011 at 13:30

4 Answers 4

2

Yes, you can check for the existence of the value attribute.

$('#a[value]') this means to find the element with id a that also has an attribute value

If you want to check after you have selected the element, if it has a value attribute then

var elem = $('#a');
if ( elem.is('[value]') ) {
  // it has a value attribute
}
Sign up to request clarification or add additional context in comments.

1 Comment

This will give a false positive in IE7 and lower where the attribute doesn't exist, unfortunately.
2

You can use this:

$( '#a' ).is( '[value]' ) // true
$( '#b' ).is( '[value]' ) // false

Live demo: http://jsfiddle.net/simevidas/w8gFF/1/

5 Comments

Have you checked that is various versions of IE?
@ŠimeVidas: weird - I would have expected it to work in IE 8, which supports hasAttribute(). IE 7 and lower don't support hasAttribute and, even worse, the attributes collection is pre-populated with a list of possible attributes.
@AndyE IE9 implements hasAttribute, but not IE8 - source.
@ŠimeVidas: Wikipedia fails again - msdn.microsoft.com/en-us/library/cc304121(v=vs.85).aspx. I had already tested it and it's definitely there in IE 8.
@Andy Aha OK. I only have IE9 on my machines and I can confirm that it fails in IE9 Compatibility View.
2

Older versions of IE don't support hasAttribute, and as Šime Vidas discovered even jQuery can't be trusted on those browsers.

The way I had to do it when I needed something similar in an older version of IE was:

function hasAttribute(el, attr) {   
    if ("hasAttribute" in el)
        return el.hasAttribute(attr);

    else if ("outerHTML" in el) {
        return (el.outerHTML
                   // remove content
                   .replace(el.innerHTML, "")
                   // remove attribute values with quotes
                   .replace(/=(?:(["'])[^\1]*\1)?/, " ")
                   // remove attribute values without quotes
                   .replace(/=[^\s>]+/, "")
                   // normalize
                   .toLowerCase()
                   // search for attribute
                   .indexOf(" " + attr.toLowerCase()) > -1);
    }
}

In your case, you might use this function like so:

var hasValue = hasAttribute($("a")[0], "value");

Unfortunately, this still isn't very robust in Internet Explorer 8 and lower. False positives and negatives will be returned in those browsers for various attributes and, unfortunately, I don't believe there's a workaround.

8 Comments

+1, cool workaround. It would miss attributes without a value.. (like multiple for select elements, checked for radio/check boxes etc..) but it seems great ! maybe using a regex for the last part would make it more powerful..
@Gaby: indeed, I'd not thought about boolean attributes. Non-boolean attributes are normalized if you leave off the value and I think that's what threw me off. Looks like I'll have to write a regex and update the code I'm using... :-)
Thinking about it, such a regex would probably give a false positive if the name of the attribute was included in any other attribute's value. Since this piece of code is fine for the question, I'll leave it as is and see if I can get a more robust workaround in the project I have.
This is not working on Internet EXplorer 8.0. hasAttribute(el, "value") is returning always false for <input value="">
@Ivan: you're right, it looks like there's a bug in IE 8 where it returns false for attributes that are defined but empty. I've changed the code and quickly tested it in IE 8 and it worked well. I don't have the time to be more thorough until Monday, but I can't foresee any problems with it. I hope it fixes the problem for you, anyway.
|
1

It's good question, but I think you will not get any workaround in IE8 or early. I think so after some experiments which I made. By the way one can make the experiments with the IE9 or IE10 beta which one has installed. One should just uses meta "X-UA-Compatible" to change the Document Compatibility Mode (see here).

I tested with:

document.getElementById("a").outerHTML = "<input type='text' id='a' value='' />";
alert(document.getElementById("a").outerHTML);

and the alert(document.getElementById("a").outerHTML) only:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=7" />
</head>

<body>
    <fieldset><input type="text" id="a" value="" /></fieldset>
    <script type="text/javascript">
    //<![CDATA[
        //document.getElementById("a").outerHTML = '<input type="text" id="a" value="" />';
        alert('In IE7 outerHTML for <input type="text" id="a" value="" />:\n' +
            document.getElementById("a").outerHTML);
    //]]>
    </script>
</body>
</html>

In case of "IE=8" the code above displays the text "<INPUT id=a type=text>". If we would change the value of "X-UA-Compatible" to "IE=7" we will see even "<INPUT id=a">. The same code with "IE=edge" displays <input id="a" value="" type="text">. The corresponding demos are here: IE=edge, IE=8, IE=7.

So it seems that IE do some kind of "optimization" during parsing of HTML. The order and the case of attributes which will be get by outerHTML is different as in original code. IE parse HTML code with "optimization" and what we see later has no more value="". So no tricks of jQuery can help us to get no more existing attribute.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.