#309 ✓resolved
Philippe D.

Fix Form.reset() to always return reference to an element

Reported by Philippe D. | August 28th, 2008 @ 02:09 AM | in 1.6.1

Form.reset() implementation does not allow to chain another function on the returned value. Example : Form.reset('my_form').select('#btn_save') returns : 'Form.reset('my_form').select is not a function'

To allow chaining, reset() function should return $(form) instead of just form, which usually is a string.

Comments and changes to this ticket

  • Juriy Zaytsev

    Juriy Zaytsev August 28th, 2008 @ 03:50 AM

    • State changed from “new” to “bug”
    • Assigned user set to “Juriy Zaytsev”
    • Tag changed from form, function to form, function, needs_patch, needs_tests
    • Milestone set to 1.7

    Actually, reset is not even added to form elements due to the way Element.extend works.

    Marking as a bug.

  • John-David Dalton

    John-David Dalton August 28th, 2008 @ 11:45 PM

    The Function.prototype.call.call trick works for this in IE and others:

    
    Form.reset = function(element) {
      element = $(element);
      var __method = element.reset;
      return (element.reset = function () {
        Function.prototype.call.call(__method, element);
        return element;
      })();
    };
    

    This would set it on the first time its used with Form.reset, but Element.extend needs to be patched to have it work with $(element).reset(), and some special mojo to back up the method.

  • Juriy Zaytsev

    Juriy Zaytsev August 29th, 2008 @ 01:21 AM

    reset and serializeElements are 2 "static methods" of Form and are never added to actual form elements (or HTMLFormElement.prototype where available).

    The documentation is actually somewhat misleading: Form.reset(element) is not equivalent to '$(element).reset().

    We should either "fix" this behavior or change docs.

  • John-David Dalton

    John-David Dalton August 29th, 2008 @ 04:06 AM

    Right, but I was pointing out how to create the method and that in order to set it we might need something like Form.extend() or something to backup the method and replace with the custom one.

  • Juriy Zaytsev

    Juriy Zaytsev August 29th, 2008 @ 02:18 PM

    You're right, John.

    I think we can go a little further and use generic reset "stolen" from a plain form:

    
    Form.Methods.reset = (function(){
      var el = document.createElement('form'),
          __reset = el.reset;
      el = null;
      return function(element) {
        element = $(element);
        Function.prototype.call.call(__reset, element);
        return element;
      }
    })();
    
  • John-David Dalton

    John-David Dalton August 29th, 2008 @ 03:09 PM

    I tried that initially and I couldn't get it to work, it didn't error, but it didn't reset the form either :'( .

    We could always have the method, insert a reset button, .click() it, then remove it.

    
      var button = new Element('input', {'type': 'reset' });
      element.appendChild(button).click();
      button.remove();
    

    I believe that works as well (I remember testing it out some time ago).

  • Juriy Zaytsev

    Juriy Zaytsev October 7th, 2008 @ 06:18 AM

    • Title changed from “Chaining impossible after Form.reset()” to “Fix Form.reset() to always return reference to an element”
    • Milestone changed from 1.7 to 1.6.1
    • Tag changed from form, function, needs_patch, needs_tests to form, function, patched, tested
  • Tobias H. Michaelsen

    Tobias H. Michaelsen November 1st, 2008 @ 11:09 PM

    I would like to take a step back:

    Why do we need a Form.reset() function anyway if it is just a wrapper for calling reset on the HTMLFormElement? You can just call $('form_id').reset()

    I would vote for removing the function entirely.

  • Juriy Zaytsev

    Juriy Zaytsev November 2nd, 2008 @ 01:25 AM

    Tobias,

    Good point, I don't see much use in it either (and don't think I ever used it).

    The method is, as you rightly noted, only a "wrapper" around native reset and, ironically, differs only in such way that it guarantees to return an element (since native reset is specified to return undefined [1])

    We can't remove it (just yet) for backwards compatibility, but we definitely need to fix it so that it at least serves its purpose : )

    [1] http://www.w3.org/TR/REC-DOM-Lev...

  • Tobie Langel

    Tobie Langel November 2nd, 2008 @ 01:18 PM

    Form reset will be useful with element wrappers.

  • Juriy Zaytsev

    Juriy Zaytsev November 2nd, 2008 @ 04:43 PM

    This is hardly relevant, but do we want to guard this method against null values? There's no check for either presence of what reset is being invoked on, nor for the presence of reset method itself.

  • Diego Perini

    Diego Perini November 2nd, 2008 @ 10:37 PM

    Well this maybe related, sorry for the ugly and lengthy example code, but I initially wanted to fix the bug where form elements may have overwritten the form properties if given one of the "reserved" names:

    [CODE]

    if (e.form && e.form[e.type].nodeName) {
      e.id = '';
      e.name = '';
      e.form['on' + e.type] = null;
      e.removeAttribute('id');
      e.removeAttribute('name');
      e.form.removeAttribute('on' + e.type);
      e.form[e.type] = document.createElement('form')[e.type];
      e.form[e.type]();
    }
    <\/code><\/pre>
    
    

    } }

    Handling forms with overwritten methods

    [/CODE]

    It seemed to me it had something to do with what Juriy described above as a possible alternative. I am talking about steal newly created form methods.

    In any case this has worked for me in all browsers. This is the best cross-browser bug I have found, ever. :-)

    -- Diego

    PS: Since I wasn't sure of the syntax results I attached the file...

  • Juriy Zaytsev

    Juriy Zaytsev November 2nd, 2008 @ 10:58 PM

    Diego, There are actually many more of those names : )

    I did some tests earlier: http://yura.thinkweb2.com/js/dom...

  • Diego Perini

    Diego Perini November 2nd, 2008 @ 11:00 PM

    Yes...firstChild...ha.

    -- Diego

  • Juriy Zaytsev

    Juriy Zaytsev February 22nd, 2009 @ 09:30 PM

    • Assigned user changed from “Juriy Zaytsev” to “Andrew Dupont”
  • GitHub Robot

    GitHub Robot February 22nd, 2009 @ 10:59 PM

    • State changed from “bug” to “resolved”

    (from [dc9d274d89f01cc21b69e4519e9b3f6a1fd59bf8]) Make sure Form.reset always returns a reference to the receiver element. [#309 state:resolved] (Phil, kangax) http://github.com/sstephenson/pr...

  • Tobie Langel

    Tobie Langel July 24th, 2009 @ 02:01 AM

    • Tag changed from form, function, patched, tested to function, patched, section:dom

    [not-tagged:"form" tagged:"section:dom" bulk edit command]

  • Tobie Langel

    Tobie Langel July 24th, 2009 @ 02:07 AM

    • Tag changed from function, patched, section:dom to patched, section:dom, section:lang

    [not-tagged:"function" tagged:"section:lang" bulk edit command]

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

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

The Prototype JavaScript library.

Shared Ticket Bins

Attachments

Referenced by

Pages