How can I determine the element type of a matched element in jQuery?
Asked Answered
K

9

73

I'm matching ASP.Net generated elements by ID name, but I have some elements which may render as text boxes or labels depending on the page context. I need to figure out whether the match is to a textbox or label in order to know whether to get the contents by val() or by html().

$("[id$=" + endOfIdToMatch + "]").each(function () {
    //determine whether $(this) is a textbox or label
    //do stuff
});

I found a solution that doesn't work, it just returns "undefined":

$("[id$=" + endOfIdToMatch + "]").each(function () {
    alert($(this).tagName);
});

What am I missing?

Kakalina answered 4/12, 2008 at 20:16 Comment(0)
S
92

Just one jQuery too much:

$("[id$=" + endOfIdToMatch + "]").each(function () {
    alert(this.tagName);
});
Sofa answered 4/12, 2008 at 20:24 Comment(8)
Or $(this).get(0).tagNameStoneware
@Znarkus: True, but makes no sense. ;)Sofa
No, not in this case. But if you have a variable with a jQuery object, this would be how you'd have to do it :)Stoneware
No. If you'd have a jQuery object, you'd use $(anything)[0].Sofa
BTW, this can be useful in handling event bubbling where you might be wanting to handle an checkbox INPUT in a TD, yet the TD and the INPUT permit a click. (The TD for the row click, the INPUT for the checkbox click.) You can use tagName to determine which was clicked and use e.preventDefault() and return false in order to cancel the event bubble.Philcox
@Volomike: That's what delegate() and, as of v1.7, on() does more elegantly, I think.Sofa
Moreover, according to this -> #4878984 article, it's recommended to use nodeName, for it results in "better consistency between browsers".Plated
@MCEmperor: I don't think that's necessary. You will never deal with attribute nodes as a result of a jQuery operation, so tagName (a DOM Level 2 property that is supported consistently, even back to ancient implementations) will work perfectly here. There is no gain in using nodeName, but of course it will produce the same result.Sofa
P
32

Consider this solution without using each():

var elements = $("[id$=" + endOfIdToMatch + "]");
var vals = elements.is("input").val();
var htmls = elements.is("label").html();
var contents = vals.concat(htmls);

Have a look at the documentation for is.

Phonsa answered 17/7, 2009 at 12:2 Comment(0)
L
25

you could also use something like this:

if ($(this).is('input:checkbox'))

replace "this" with whatever instance you need and 'checkbox' with whatever input type you need.

Leatherman answered 18/2, 2010 at 20:45 Comment(0)
K
6

First time I've answered my own question. After a little more experimentation:

$("[id$=" + endOfIdToMatch + "]").each(function () {
   alert($(this).attr(tagName));
});

works!

Kakalina answered 4/12, 2008 at 20:24 Comment(1)
Still one jQuery too much. :-) You have the DOM element already with "this", no need to wrap it again!Sofa
B
3

tagName what a nice tip. I would like to suggest also to use tagName.toLowerCase() since the value returned depends on the document type (HTML or XML/XHTML).

See: http://reference.sitepoint.com/javascript/Element/tagName

Betroth answered 10/3, 2009 at 15:55 Comment(0)
R
3

in jquery 1.6 use prop()

Example

var el = $('body');

if (el.prop('tagName') === 'BODY') {
    console.log('found body')
}
Rancid answered 2/7, 2011 at 21:37 Comment(0)
A
1

This the best way to Get the element type

function tgetelementType( elmentid )
{

    var TypeName = $('#' + elmentid).get(0).tagName;
    var TypeName2 = $('#' + elmentid).get(0).type;


    if($('#' + elmentid).get(0).tagName== "INPUT")
    {
       return $('#' + elmentid).get(0).type.toUpperCase()
    }
    else 
    {
        return $('#' + elmentid).get(0).tagName.toUpperCase() ; 
    }
}
Alduino answered 28/4, 2011 at 14:36 Comment(0)
E
1
$("[id$=" + endOfIdToMatch + "]").each(function(){
    var $this=jQuery(this),ri='';
    switch (this.tagName.toLowerCase()){
        case 'label':
            ri=$this.html();
            break;
        case 'input':
            if($this.attr('type')==='text'){ri=$this.val();}
            break;
        default:
            break;
    }
    return ri;
})

The question is, what do you intend to do after you've determined the tag name? You could just as easily filter the jquery list using an additional selector combined with .end() to do the same thing:

$("[id$=" + endOfIdToMatch + "]")
    .find("input:text")
    .each(function(){
         /* do something with all input:text elements */
    })
    .end()
    .find("label")
    .each(function(){
        /* do something with label elements */
    })
    .end()

This could still be chained if you needed to do further things with this particular collection of elements...just like the example above.

In either case, you'd have to do something with the values while inside the each() statements

Ermeena answered 27/7, 2011 at 17:39 Comment(0)
M
0

Yet another solution, arguably more elegant, is to write two separate functions for each element type:

$("input#" + id).each(function() { alert(this + " is an input"); });
$("label#" + id).each(function() { alert(this + " is a label"); });
Missal answered 23/2, 2012 at 0:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.