Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 8 of 8
  1. #1
    New to the CF scene
    Join Date
    Jul 2002
    Posts
    4
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Adding Methods to Predefined Object Prototypes

    The advanced tutorial on prototypes (http://www.javascriptkit.com/javatutors/proto2.html) states that JavaScript only allows you to use the prototype object of prebuilt objects that are created with the "new" keyword.

    I find this constraint unfortunate, as I'd prefer to write a little framework for input validation by adding methods to predefined DOM classes instead of to the global object.

    Can anybody provide some background/elaboration on this constraint, or perhaps give me some URLs to ECMA/W3C/Netscape/MSDN pages that provide further documentation?

    Thanks in advance.

  • #2
    jkd
    jkd is offline
    Senior Coder jkd's Avatar
    Join Date
    May 2002
    Location
    metro DC
    Posts
    3,163
    Thanks
    1
    Thanked 18 Times in 18 Posts
    HTMLElement.prototype.delete = function() {
    this.parentNode.removeChild(this);
    }

    In Gecko browsers, you can prototype core DOM classes, but not in IE.

    Could you give a further elaboration of what you want?

    BTW, you don't need to use the new keyword...

    Object.prototype.getFirstProp = function() {
    for (var i in this) return this[i];
    }

    {a: 1, b: 2}.getFirstProp() == 1

    works just fine on literals.

  • #3
    New to the CF scene
    Join Date
    Jul 2002
    Posts
    4
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Originally posted by jkd

    In Gecko browsers, you can prototype core DOM classes, but not in IE.
    Why is that? For which browser versions is that true? Is there any documentation of these facts from the browser vendors?

    Could you give a further elaboration of what you want?
    Sure. I want to add some methods to Form/HTMLFormElement and Input/HTMLInputElement to validate user input and submit the form or display validation errors. For example I'd like to be able to invoke document.someForm.validateAndSubmit(), which iterates its input elements and invokes their validate(), collecting validation errors (if any). An Input's validate() method will eval a document-supplied validationStatement property that invokes fine-grained validation methods (isAlphabetic(), isNonWhitespace()) added to Input.

    I know I can accomplish the same thing in other ways, such as by adding functions to the global object, that take the form / input elements as parameters - or by adding my own class that implements the behavior and takes the form as a parameter. But my preference is to simply add these behaviors to the DOM classes where they naturally fit, if that is possible.

    BTW, you don't need to use the new keyword...

    Object.prototype.getFirstProp = function() {
    for (var i in this) return this[i];
    }

    {a: 1, b: 2}.getFirstProp() == 1

    works just fine on literals.
    I understand your point; thanks for the example. I think what the tutorial author meant in regards to the "new" keyword is that you can only "prototype" classes that you would normally instantiate (via new) in your client code - as opposed to DOM classes.

    Thanks for joining the discussion.

  • #4
    jkd
    jkd is offline
    Senior Coder jkd's Avatar
    Join Date
    May 2002
    Location
    metro DC
    Posts
    3,163
    Thanks
    1
    Thanked 18 Times in 18 Posts
    Like I said, unfortunately only Gecko browsers (these include NS6, NS7, Mozilla, Beonex, Galeon, and K-meleon) support prototyping of any DOM interface.

    Oddly enough in IE, Object.prototype.bla will not show up in an instance of a DOM object, despite that fact that all Javascript "objects" are supposed to inherit from it.

    I like how you want to go about this though - excellent coding practice not to pollute the Global namespace, despite it being so common nowadays .

    HTMLFormElement.prototype.validateAndSubmit = function() {
    var errors = [];
    var inputs = this.getElementsByTagName('input');
    for (var i = 0; i < inputs.length; i++) {
    try {
    inputs.item(i).validate();
    }
    catch (error) {
    errors[errors.length] = error.message;
    }
    }
    if (errors.length == 0) this.submit();
    else alert(errors.join('\n\n'));
    }

    Gotta love how simple that is. Have HTMLInputElement.prototype.validate()
    Code:
    throw new Error('friendly error message to alert later');
    If it encounters something wrong, which is then caught in submitAndValidate()... etc etc

    Excellent example of why I think Gecko is by far the best browser in existance (and why I promote its use whenever I get a chance).

    There is an ugly way to accomplish the same in IE though - element behaviors.

    form {
    behavior: url(formextensions.htc);
    }

    And in form.....htc:

    Code:
    <script type="text/javascript">
    element.submitAndValidate = function() {
    // whatever
    }
    </script>
    You'd need an individual HTC file for each element you are extending, and remember you're not prototyping anything, but rather adding a method each time a form element has CSS applied to it - I'd assume the performace as compared to prototyping is much worse.

  • #5
    New to the CF scene
    Join Date
    Jul 2002
    Posts
    4
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Originally posted by jkd
    Oddly enough in IE, Object.prototype.bla will not show up in an instance of a DOM object, despite that fact that all Javascript "objects" are supposed to inherit from it.
    Yeah. That's messed up.

    I like how you want to go about this though - excellent coding practice not to pollute the Global namespace, despite it being so common nowadays .
    <...>
    Gotta love how simple that is
    As an old-time Smalltalk programmer, I can't help it. Put the behaviors where they naturally fit. Simpler is better.

    Thanks for your help, jdk. The things you students learn these days! (I'm an old fart by comparison ) I think I'll give up on the idea and revert to a wrap-and-delegate approach. As usual, whenever I try to do something simple and elegant and object-oriented outside of Smalltalk, I find some less enlightened technology/vendor standing in my way. I appreciate you sharing your time and knowledge.

  • #6
    jkd
    jkd is offline
    Senior Coder jkd's Avatar
    Join Date
    May 2002
    Location
    metro DC
    Posts
    3,163
    Thanks
    1
    Thanked 18 Times in 18 Posts
    Originally posted by stafford

    As an old-time Smalltalk programmer, I can't help it. Put the behaviors where they naturally fit. Simpler is better.
    I always wanted to learn Smalltalk, but have settled for Python and Ruby.
    Still wouldn't mind learning it though...

    Originally posted by stafford
    I think I'll give up on the idea and revert to a wrap-and-delegate approach. As usual, whenever I try to do something simple and elegant and object-oriented outside of Smalltalk, I find some less enlightened technology/vendor standing in my way.
    *sigh* Now if everybody used Gecko....
    Kind of interesting the "less enlightened vendor" you are referring to is the largest software company in the world. (Not that I dislike MS in general, but imho IE could disappear off the face of the earth and I'd be a very happy person ).

    Though like I said before, you *can* achieve this amount of encapsubility (word?) in IE through element behaviors, though I stand by my previous assertion that it is a cheap hack. (Well, maybe not a hack, but certainly a Bad Way of going about this).

    good luck

  • #7
    New to the CF scene
    Join Date
    Jul 2002
    Posts
    4
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Actually it looks like a decent hack. Thing is, I have to support multiple browsers, so I don't know if I want to go to all the trouble of conditionally doing it this way for IE and conditionally doing it that way for NN, etc. Especially since I'd have to eventually retrofit it into some 230 JSPs. BTW, I just checked the 4th edition of the O'Reilly JavaScript book and it doesn't say anything about this, ahem, "limitation" of IE. I've already emailed the author. Thanks again. TTYL.

  • #8
    jkd
    jkd is offline
    Senior Coder jkd's Avatar
    Join Date
    May 2002
    Location
    metro DC
    Posts
    3,163
    Thanks
    1
    Thanked 18 Times in 18 Posts
    You don't necessarily need to test this conditionally. You can accomplish this in Gecko (in another way) similar to IE's element behaviors:

    form {
    behavior: url(formextension.htc);
    -moz-binding: url(formextension.xml#ext);
    }

    Since that is CSS, IE will ignore -moz-binding (doesn't support XBL), and Moz will ignore behavior (doesn't support behaviors).

    You've seen what the HTC file looks like, and this what is the XBL file would like like:

    Code:
    <?xml version="1.0"?>
    <bindings xmlns="http://www.mozilla.org/xbl">
      <binding id="ext">
        <implementation>
          <method name="submitAndValidate">
            <body>
              <![CDATA[
                var inputs = this.getElementsByTagName('input');
                for (var i = 0; i < inputs.length; i++) {
                  // blabla
                }
                //blabla
              ]]>
            </body>
          </method>
        </implementation>
      </binding>
    </bindings>
    You can implement this site-wide by using an external CSS file with a <link/> tag...

    But this is still limited to IE5+/Gecko(NS6+)


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •