Working on Forms with Prototype

Prototype besides its nices shortcuts provides some function to work with forms elements. So let’s see what prototype can do for us.

Fields

Sometimes it’s important for your application that some fields of your form gain focus programatically or you need to clear some fields when actions appends.
So here are some help from our lovely library :

Clear a field

1
2
3
4
5
6
7

1
2
3
4
5
6
7
// Clear field with id="myFieldID"
Field.clear(myFieldID);
Field.clear($(myFieldID));

// Clear fields with id="myFieldID" and id="mySecondFieldID"
Field.clear([myFieldID,mySecondFieldID]);
Field.clear([$(myFieldID),$(mySecondFieldID)]);

Set focus on a field

1
2
3

1
2
3
// Set the focus on a field and select it if the browser support it
Field.activate(myFieldId);
Field.activate($(myFieldId));

Check presence of content in Fields

This function retun false if one of the field to check is empty.

1
2
3
4
5
6
7

1
2
3
4
5
6
7
// Check if the field contains value
Field.present(myFieldId);
Field.present($(myFieldId));

// Check if multiple fields contains value
Field.present([myFieldId,myFieldId2, myFieldId3]);
Field.present([$(myFieldId),$(myFieldId2), $(myFieldId3)]);

Forms

Serialize a form

If you’re doing Ajax things you certainly reach a point when you need to send the values of a form to your server-side processing app. Prototype make it so much painless you’ll never do it manually.

1
2
3
4

1
2
3
4
// formSerialized then contains a querystring containing your form values
// ready to be send by ajax (POST or GET)
var formSerialized = Form.serialize(myFormId);
var formSerialized = Form.serialize($(myFormId));

Get all form elements

1
2
3

1
2
3
// elements then contains an iterable array of all elements composing your form.
var elements = Form.getElements(myFormId);
var elements = Form.getElements($(myFormId));

Get inputs by type and/or name

1
2
3
4
5
6

1
2
3
4
5
6
// inputs then contains an iterable array of all inputs
var inputs = Form.getInputs(myFormId);
// inputsPassword then contains an iterable array of all inputs of type ‘password’
var inputsPassword = Form.getInputs(myFormId, password);
// inputsPasswordByName then contains an iterable array of all inputs of type ‘password’ and whose name is ‘clear_password’
var inputsPasswordByName = Form.getInputs(myFormId, password, clear_password);

Disable a form

Each form elements will be disabled.




Form.disable(myFormId);

Enable a form

Counterpart of previous function, this one enable all form elements.




Form.enable(myFormId);

Get the first non-hidden/disabled element of a form

This one will make sense with the next one.




Form.findFirstElement(myFormId);

Focus the first element of a form




Form.focusFirstElement(myFormId);

Reset a form

Not really needed as it does not really shorten your code, but it allows you to interact with form in a consistent manner and when you’ll need to do more than emptying fields on reset, you’ll just need to override the function with your implementation.




Form.reset(myFormId);

I will not cover the Form.Element.Serializers and Form.Element, because theirs goals is essentially to simplify the writing of previous functions.

Easily get a form element value :

1
2

1
2
// value then contains the value of ‘myElementId’, this let you fetch value of any form element in a consistent manner 
var value = $F(myElementId);

Observers

Time Observers

Sometimes it can be handy to check the value of a form or only one form element periodically : live preview, live search, …
As you should have understand Prototype provides some handy Object to simplify your life.
An important thing to note : the callback will only be called if the value has change between two value check.

1
2
3
4
5
6
7
8
9

1
2
3
4
5
6
7
8
9
function liveActionCallback( element, value ) {
// do some fancy things here
}

// Check a ‘myElementId’ value all 2 seconds, sending the element and its value to a callback function
new Form.Element.Observer(myElementId, 2, liveActionCallback);

// Same thing but for a complete form, value contains Form.serialize(‘myFormId’)
new Form.Observer(myFormId, 2, liveActionCallback);

Event Observer

Sometimes continually looking for changes isn’t needed and you only want to be notify when changes occurs.

1
2
3
4
5
6
7
8
9

1
2
3
4
5
6
7
8
9
function handleValueChange( element ) {
// do what you want when a value change
}

// Observe changes of a form element
new Form.Element.EventObserver(myElementId, handleValueChange);

// Observer changes form-wide
new Form.EventObserver(myFormId, handleValueChange);

Next time i’ll go through Array/Hashes Prototype additions.

Fri, 21 Jul 2006 22:11 Posted in

  1. By ludo 09/11/2006 at 10h59


    And to Observe the focus on all form element ?

  2. By Tron Jonathan 15/11/2006 at 10h06


    There more than one way to do it but none of them are provided directly by Prototype.

    What I can imagine is something like :

    <pre> // Let's create a new object type Form.FocusObserver = Class.create(); Form.FocusObserver.prototype = Object.extend(new Abstract.EventObserver(), { getValue: function() { return Form.serialize(this.element); },

    // Override from Abstract.EventObserver because the original // check if there is differences between two invocations, // but for focus we want the event be triggered each time onElementEvent: function() { var value = this.getValue(); this.callback(this.element, value); }, // Override this one to handle the focus event registerCallback: function(element) { Event.observe(element, ‘focus’, this.onElementEvent.bind(this)); }

    });

    // Our callback function
    function onFormElementFocus(form, value) {
    console.log(value);
    }

    // Let’s observe a form with id=“formTest”
    new Form.FocusObserver(‘formTest’, onFormElementFocus);

    I hope this can help you.

  3. By Henrique Vicente 20/11/2006 at 06h18


    As of prototype-1.4.0.js you need to use handleValueChange(), not handleValueChange to call the function above.

    Also, even changing this is not working for me as desired. I think the specs of the Form.EventObserver changed a bit, but I’m a Javascript/Prototype newbie so I can’t say…

    Now I’m gonna study it more to fix my problems.

  4. By Tron Jonathan 20/11/2006 at 10h20


    Henrique : I should have mention I work with Prototype 1.5.0_rc1, but I don’t really see how handleValueChange() can work as it will be call to the function and not a reference to it. I don’t think this is related in any way with Prototype version.

  5. By Olivier 11/01/2007 at 15h10


    Hello,

    I bookmarked your post a little while ago.

    Now I come back and browse it :

    What’s the point of the first line ?


    Field.clear(‘myFieldID’); //useless and even buggy with FF.
    Field.clear($(‘myFieldID’));

  6. By Tron Jonathan 11/01/2007 at 22h15


    Olivier : most of prototype functions work on both the id (as a string) or the dom element returned by $() function. So the point of the first line was to specify you can have any of the 2 form : ‘elementid’ or $(‘elementid’). Prototype will do the $(‘elementid’) in the Field.clear function automagically.
    And what’s your problem on FF ? I never had any with this function using the first form.

  7. By AceoStar 17/03/2008 at 19h56


    This is a great tutorial. It touches on a lot of the powerful aspects of prototype without all the fluff. Thanks!

  8. By folklore 25/04/2008 at 14h30


    well how do if disable a form without disable it’s submit/click buttopn

  9. By Siddharth 07/06/2008 at 08h27


    Hi Jonathan,
    Nice article…was very helpful to me.I have a small problem and i’m Not able to get it right.How to i get Data from a database into a form using Prototype ajax…all the above deal with form submission…but how can one populate a form with database values using ajax? I am a newbie and would be very happy to get any kind of help….

    Thanks and regards

    Siddharth

  10. By Jonathan Tron 07/06/2008 at 09h51


    Hi Siddharth,
    there are multiple way to do it, if you only want a simple example just to get the grasp of it, here’s the basics (assuming you’re returning data as JSON in the X-JSON header) :

    var url = '/path/to/your/script/page';
    new Ajax.Request(url, {
      method: 'get',
      onSuccess: function(transport) {
    
        // Prototype automatically eval text in X-JSON header
        // It returns null if there is nothing to eval
      
        if ( response = transport.headerJSON )
        {
            // Assuming your JSON response looks like '[{name:"val"}]' 
    
            // Get the first element of the array response and overload it with Prototype Hash extensions
            var elements = $H(response.first());
    
            // Then for each element set the value of the corresponding input
            // we assume each form element has and id corresponding to keys in the return JSON
            elements.each(function(key, value) {
               $(key).value = value;
            });
        }
      }
    });
    

    And that’s it, a very little example of how you can do what you asked for.
    It’s not a production code example (no error checks other than JSON emptyness, etc.) but it should help you starting.

  11. By software_developer 31/08/2008 at 15h55


    Hi Tron.

    Thanks for useful shortcuts .. it will save some of my time..

  12. By Botnary 13/12/2008 at 16h59


    Hi Tron.
    Please help me! How can i parse an JSON response in this format




    {"results": [
    {"id": “My string 1”, “value”: “Other string 1”, “info”: ""},
    {"id": “My string 2”, “value”: “Other string 2”, “info”: ""},
    {"id": “My string 3”, “value”: “Other string 3”, “info”: ""},
    {"id": “My string 4”, “value”: “Other string 4”, “info”: ""},
    {"id": “My string 5”, “value”: “Other string 5”, “info”: ""},
    {"id": “My string 6”, “value”: “Other string 6”, “info”: ""}
    ]}

    with prototype 1.6 ..

    i started with this code



    new Ajax.Request(‘temp.php’, {
    method:‘get’,
    requestHeaders: {Accept: ‘application/json’},
    onSuccess: function(transport){
    var json = transport.responseText.evalJSON(true);
    }
    });

    so how i can access every ID and VALUE from json object.

  13. By Jonathan Tron 13/12/2008 at 18h26


    Botnary : You can do something like this

    json.each(function(e)
    { 
      console.log(e.id); 
      console.log(e.value); 
    });
    

    This will iterate over your response array and print to the Firebug console each id, value.

  14. By Botnary 14/12/2008 at 13h25


    Thanks Tron you saved my life :D

  15. By Carley 14/07/2011 at 12h05


    Cheers pal. I do arppiecate the writing.

Comment Working on Forms with Prototype