This project is archived and is in readonly mode.

#527 ✓invalid
Mike

IE7 and hasOwnProperty

Reported by Mike | December 19th, 2008 @ 05:30 PM | in 2.0 (closed)

When using mootool's forEach to loop through an array of elements, IE7 gives an error that 'hasOwnProperty' is not a property on any FORM elements. The foreach function attempts to use 'hasOwnProperty' on such elements and causes the script to error out.

Simplest fix we have found, in forEach:

change: if (this.hasOwnProperty(key)) fn.call(bind, this[key], key, this);

to be: if (this.hasOwnProperty) if (this.hasOwnProperty(key)) fn.call(bind, this[key], key, this);

...after that everything works fine.

Comments and changes to this ticket

  • Mike

    Mike December 30th, 2008 @ 07:30 PM

    • Tag changed from 1.2, ie7 to 1.2, 1.2.1, ie7

    Still an issue in 1.2.1,

    if (this.hasOwnProperty(A))

    replaced by

    if (this.hasOwnProperty && this.hasOwnProperty(A))

    for all instances seems to fix it

  • Valerio

    Valerio January 12th, 2009 @ 04:03 PM

    • State changed from “new” to “invalid”

    hasOwnProperty gets called only in objects, not in Arrays and definitely not in Array items.

    Maybe it would be helpful to see the actual code you're using, not just the resulting error.

    Invalid until we can see the code.

  • Mike

    Mike January 12th, 2009 @ 04:31 PM

    
    $each(
    		$( 'profile_' + section + '_information' ).elements,
    		function(value, key)
    		{
    			value.removeClass( 'error' );
    		} );
    

    Everything done here works fine in FF, Safari, and Opera. However in IE7 .elements includes the actual $lt; form > tags, and since $each uses forEach, which uses hasOwnProperty, IE7 gives an error.

    Whether this is intended use or not, it works perfectly after the small patch stated above.

  • Mike

    Mike January 12th, 2009 @ 04:32 PM

    oops, obviously meant < form >

  • Valerio

    Valerio January 12th, 2009 @ 04:51 PM

    The problem is you're using $each to loop a form's elements in internet explorer. The elements property there is probably a very customized object lacking standard Object prototypes. You could try this if you really need to use .elements:

    $$($(myForm).elements).each(function(){

    });

    However, i suggest simply using standard dom selection:

    $(myform).getElements('input, textarea, select').each(function(){

    });

  • Mike

    Mike January 12th, 2009 @ 05:03 PM

    Ok, thank you, I will give that a try.

    The problematic object in question is the form element itself. I stepped through the process with microsoft's javascript debugger and the form element is what it immediately failed on. We've done this in other places that did not include a form element and it seemed worked fine.

    Thanks again for the clarification.

  • Valerio

    Valerio January 12th, 2009 @ 05:07 PM

    "The problematic object in question is the form element itself"

    its actually the object called elements, present only in forms (form.elements).

  • Mike

    Mike January 12th, 2009 @ 05:14 PM

    My apologies for not making that clearer - I meant I can loop through a list of DOM elements with this same logic just fine:

    
    $each(
    		$(document.body).getElements('a'),
    		function(el)
    		{
                            //do stuff here
    		} );
    
    

    However, it does not work when form elements themselves are involved (with .elements). This is what caused the confusion on my part, as $each works fine in one scenario and not the other.

  • Valerio

    Valerio January 12th, 2009 @ 05:19 PM

    True (and no worries, it was very clear), but its currently impossible to correctly loop objects without hasOwnProperty.

    As a note, you're overusing $each, and $. In this case, a simple

    document.getElements('a').each(function(){

    });

    will suffice, and will be much faster too.

  • Mike

    Mike January 12th, 2009 @ 05:35 PM

    Ok, thanks for the help!

  • Shawn Tice

    Shawn Tice March 5th, 2009 @ 12:43 AM

    I just ran into this problem independently, and thought I'd say a little more about it. After a little digging, I found that the issue is that IE6 (and probably IE7?) returns 'element' for $type(someForm.elements), which causes the $each function to iterate over the 'elements' object with Hash.each instead of Array.each ($each only uses Array.each for 'arguments', 'collection', and 'array'). Firefox 3.0.5, on the other hand, (correctly) reports 'collection' for $type(someForm.elements). A simple workaround is to just use the Array.each method explicitly because the object is indeed an array, but ideally $each would get this correct. It may not be possible, however, since you'd generally want to iterate over something with type 'element' using Hash.each.

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

Shared Ticket Bins

People watching this ticket

Tags

Pages