Login Register

Degradable AJAX forms with Dojo

While many of you are using Dojo to create high-powered, dynamic applications, I often find myself "sprinkling" Dojo here and there to improve the user experience on "normal" web pages. It is with that in mind that I present to you dojo.io.FormBind. FormBind allows you to quickly setup your "Web 1.0" form for asynchronous submission. How do you do it? Easy:
function magicForm() {
  var x = dojo.io.FormBind({
    // reference your form
    formNode: document.forms[1],

    load: function(load, data, e) {
      // what to do when the form finishes
      // for example, populate a DIV:
      dojo.byId('myDiv').innerHTML = data;
    }
  });
}

dojo.addOnLoad(magicForm);
You can play with the demo to see it in action. The code is hot off the press, so you'll have to get the latest nightly build to play with it. Update: I've added an onSubmit function which allows you to validate the form before sending and/or show some sort of loading/progress indicator. The demo has been updated with simple "Loading..." text (which you may miss if your connection is fast enough).

Nice hack!

Nice hack!

If it is part of core is it

If it is part of core is it still a hack? ;)

Thanks, David. ...this is

Thanks, David. ...this is apparently very cool. I just want to make sure I understand correctly. I am new to DOJO and AJAX, but find both very compelling (I hope that fact is something that encourages you guys, you're reaching the masses!) So if I have a standard form that submits to the server such as this: [continues on with some form submit link/ button and code, etc] So lets say, for example, in addition to calling “parse_entries()�, in the above example, if I have loaded the appropriate DOJO files/references and also call your DOJO function “magicForm()� (along with assigning the appropriate name of the div element where to write the loaded data, etc) this will take care of the AJAX (XMLHttpRequest for various browsers, etc) and the DOJO code will provide the server communication asynchronously for me? Is this all there is to it? Or am I missing something. Many thanks for any input there, Mark

Hi Mark, If I've understood

Hi Mark, If I've understood you correctly that's exactly it. I'm one of those masses too. My form handler supplies innerHTML so all I require is: var x = new dojo.io.FormBind({ formNode: "my_form_id", load : function(type, data, evt) { document.getElementById("id_for_results").innerHTML = data; } }); The difference between a FormBind inspired request and a full page submit is the presence of the key/value pair "dojo_transport" / "xmlhttp". So simple its brilliant. :) Cheers, Chris

Yes. You would tweak

Yes. You would tweak magicForm's formNode to point at the form you want. The easiest way to do it is to give you form an id and just set formNode to the id. Example: formNode: 'myFormId', And then you'd change 'myDiv' to point at the div you want to output the server HTML to.

Chris, one correction: we

Chris, one correction: we send along dojo.transport, not dojo_transport. So, on the server, you can check to see if dojo.transport comes through as xmlhttp. If so, you just return the fragment of HTML you need as opposed to the entire page! I should add that test case to my example.

It would be nice to have a

It would be nice to have a mini-library of small "hacks" like FormBind, which simplify mundane tasks. Especially it is useful for legacy cases, because it provides the easy way for migration to Dojo.

[...] Like all things in Web

[...] Like all things in Web 2.0 mashups are inevitable so I thought I’d mashup two dojo posts in to one and hence the mashed up title. What I’m referring to are Richard Rodger’s “Dojo: Progress!” post and David Schontzler’s “Degradable AJAX forms with dojo” post. [...]

Ah well, thats using php for

Ah well, thats using php for you, dots become underscores. Thanks for the explanation.

[...] With regard to

[...] With regard to FormBind, you’d specify that one of two ways: [...]

As long as we're simplifying

As long as we're simplifying forms, how about functions to: 1) Store form original values at some developer defined point (since a form might be in some part composed in the browser) 2) When submitting the form, send only values that have been modified since the form was stored. 3) Provide a JSON object, of some documented standard format, containing form(s) fields that should be updated as a response to the submitted form. But even this lacks other navigational aspects that may need to happen (ex. go to tab xyz, change to another page, etc.) This stuff is fantastic but it still feels like we're all handling the client side logic in a very individual way. While there are fairly standard controllers at the server level (struts,etc.) it seems that updating and navigational feedback at the browser level are still very much unstandardized despite great tools like dojo. Years ago, I used to use a VT-XXX terminal program manager on SCO Unix where you wrote your screen updates to a screen buffer, the host figured out what changed on the screen and then sent back the most efficient VT commands to update the client terminal screen. Sometimes that was a matter of cursor positioning. Sometimes block areas of the screen were redrawn. And finally, if enough had changed, it would just redraw the screen. It sounds rudimentary but it worked incredibly well and it didn't require the developer having to think about how to update the screen, just what to update. It almost feels like we might be coming full circle, just add in a lot more media aspects. Not quite there yet though.

Sorry I have a problem, I am

Sorry I have a problem, I am using struts, but I cant get any response, the struts action call is maded, nice, but I cant get any response...., maybe is because I am working with struts?

Is it possible to submit a

Is it possible to submit a form to a remote url and display the result in a div ? I tried with your example but I get returned to the post.php result page. I am pretty new to DOJO / AJAX. Regards.

i have tried to get this

i have tried to get this example working with a pear quickform but am having technical difficulties. what is in your post.php file??

cool example would need it

cool example would need it to work for my project please help me with the complete code source of this example

yep

yep

I am not able to use

I am not able to use formbind to submit a form containing a file input (ie a form that allows the user to upload file). Any example will be greatly appreciated. My current example did not submit the form.. dojoUploadFormAction = new dojo.io.FormBind({ formNode:"uploadUserDocumentForm", method: "post", file: true, load: function(t, data, e) { dojo.byId("formUploadSubmit").disable=false; alert('form uploaded'); closeUploadDialog(); } });

michael: other posts have

michael: other posts have outlined how to include the IframeIO transport which allows background file upload. The BrowserIO transport is smart enough not to try to upload files where it can't, so in order to get the system to automatically handle this, you'll need to add: dojo.require("dojo.io.IframeIO"); and then be sure to return a valid HTML document in the response to pull the content out of. Regards

I've found FormBind to be

I've found FormBind to be VERY useful. However, one glitch I can't seem to get around - if you submit a form more than once, without reloading the page, the form gets submitted multiple times. For an example see http://www.mofon.net/testmultiple.taf . Submit it once and it's fine. Submit it again and it submits the form twice. Submit it a third time and it submits the form three times, ad infinitum. Any way to prevent this? Thanks!

cool! i'm still looking for

cool! i'm still looking for an easy way to add ajax to my forms -- this is a big help! but as all examples i've seen it requires the user to click a button! how would i use it to send a form by onchange of a select-box? atm i have: AAA BBB CCC The form arguments sent to the server should appear here. which gives me the result in the div when i click the button. but i would like to have something like AAA BBB CCC The form arguments sent to the server should appear here. atm, id i try i get the results of the request in a new page, not in the div :-(

with <input

with

 
try using onValueChanged instead of onChange

oops. seems tags are simply

oops. seems tags are simply stripped instead of converted to html, hopefully this will be visible: _with_ button: <form name="selCar" action="test.php" method="post" id="test"> <select name="cars" id="cars" size="3" style="width:100px;"> <option label="AAA" value="0">AAA</option> <option label="BBB" value="1">BBB</option> <option label="CCC" value="2">CCC</option> </select> <input type="submit"/> </form> <div id="output">The form arguments sent to the server should appear here.</div> _without_ button: <form name="selCar" action="test.php" method="post" id="test"> <select name="cars" id="cars" size="3" style="width:100px;" onchange="submit"> <option label="AAA" value="0">AAA</option> <option label="BBB" value="1">BBB</option> <option label="CCC" value="2">CCC</option> </select> </form> <div id="output">The form arguments sent to the server should appear here.</div>

Hi guys, I've been more or

Hi guys, I've been more or less looking for this functionality but have had a problem with it. Basically I didn't like the way that you need to write a method for each form handler when in my case the form handling could be totally generic. So I thought it would be fine to write my magicForm() the way that Prototype handles it. i.e: function invoke(formId, targetDiv){ var x = dojo.io.FormBind({ formNode: dojo.byId(formId), load: function(load, data, e){ dojo.byId(targetDiv).innerHTML = data; } }) } dojo.addOnLoad(invoke); then in my tags I would just have a: But this doesn't seem to work. Complaining that method this.init() doesn't exist. so my javascript sucks and I'm wondering what init() method it's talking about. however I do notice that the demo source calls FormBind from inside an init() method, is this a requirement of using it? Doesn't that sort of prevent me from argumenting my own method? I'm pretty sure that my poor javascript fluency is the culprit here, but what do I need to do to argument the FormBind so that I can use just one for all my submissions? cheers,

whoops. I guess I can't

whoops. I guess I can't show the markup I was using. In any case imagine a form with an input button that has an onsubmit with invoke(this,'somediv') as the handler.

Hi David, at post 6 you

Hi David, at post 6 you mentioned: 'So, on the server, you can check to see if dojo.transport comes through as xmlhttp. If so, you just return the fragment of HTML you need as opposed to the entire page! I should add that test case to my example.' Could you please give an example of that test case, as I am at the stage whereby the entire page is being returned which I don't want! regards Andrew

I don't get the simplest

I don't get the simplest thing. If for example in my form I have action="post.php", how can I access the data from the form in post.php?

Anyone?

Anyone?

As mentioned by Patrick on

As mentioned by Patrick on topic´s 22 and 23 it could be very useful. I tried these solution too, but it doesn´t work, unfortunately. We could have one generic method like: function formActionDispatcher(formObject, divId) { formBinder = new dojo.io.FormBind({ url: formObject.action, formNode: formObject, load: function(type, data, evt) { dojo.widget.byId(divId).setContent(data); }, error: function(type, error) { dojo.widget.byId(divId).setContent(error); } }); formBinder.onSubmit = function(form) { dojo.widget.byId(divId).setContent("wait"); return true; } } Please let me now if there is a way to use this implementation! Thanks a lot, Bye.

In advance... here I have a

In advance... here I have a generic example that works fine with DOJO Menu2 (but doesn´t work with forms). function actionDispatcher(divId, action) { dojo.io.bind({ url: action, load: function(status, data) { dojo.widget.byId('bodie').setContent(data); }, error: function(type, error) { dojo.widget.byId('output').setContent(error); }, mimetype: "text/html", transport: "XMLHTTPTransport" }); } Just call the method in "onClick" DOJO Menu2 div:

I am new to dojo. Can

I am new to dojo. Can anybody let me know how to load a form(using dojo FormBind) when i hit submit button. Suppose I have a html page which has few fields and a submit button. Now what I want is when i hit that submit button another page should open using FormBind. tried modifying magicform example but could not figure out how to refer to another url. function magicForm() { alert('magic form'); var x = new dojo.io.FormBind({ url:"http://someurl/john/dojotest/testform.html", formNode:"form1", load: function(load, data, e) { // what to do when the form finishes // for example, populate a DIV: dojo.byId('output').innerHTML = data; });

When I submit the form it's

When I submit the form it's sending twice to my POST method. I'm using dojo-2006-09-27

So, why does the response

So, why does the response have to HTML? It is extremely limiting. Before the file upload I returned an XML document, which made processing the response very easy. The response had a status indicator, an error message (if any) and additional information I d used to populate combo boxes, input fields, etc. Now I can only return an HTML object and the only examples I can find anywhere show replacing the innerHTML of an existing document element. I do not want to display the response at all. I want to process it in a similar manner to the XML processing I used before. I changed my response to use div with ids (the ids match the names of the old xml elements). However, I can’t seem to find any way to access the individual items in the response object. Does anyone know how to do that?

To post #25

To post #25 (Zipman): post.php contains one line of code ---> echo $_POST["name"] . $_POST["loc"];

Using FormBind for file

Using FormBind for file uploads worked great in version 0.3 using dojo.io.IframeIO. However in 0.4 it doesn't. The form is submitted but the response is never received. I swapped out the IframeIO.js file for the old 0.3 version and it works fine now. Not sure what changed.

I think dojo should have a

I think dojo should have a library for support web1.0 operations (like submitting a form). This would make it easier to migrate to all dojo scripts

The do-it-yourself approach

The do-it-yourself approach works well enough for simple projects, but as your project grows you want to find an approach that requires less client-side coding.

I have the fallowing

I have the fallowing code: Code: var x = new dojo.io.FormBind({ formNode: 'form', error: function( type, error ){ // how can I display the page that the server sent?? alert(dojo.errorToString(error)); }, load: function(load, data, e) { // what to do when the form finishes } }); There is any way to display the actual information that the server send to the browser when an error occurs??

Only change the error

Only change the error function for: error: function( type, error, e ){ alert(e.responseText); }

Thank you

Thank you

If I formBind my formobject,

If I formBind my formobject, How do I unbind it? We have specific requirement where in some use-cases, we will let user go to next page and other cases,we submit with ajax. Any input?

Hmmm.. I've made a form

Hmmm.. I've made a form using this code, and it seems to work fine in Firefox 2.0. But in IE7 I get the following error (with debugging on): "FATAL exception raised: [object Error]" in IE7 Here's how I'm using the formBind: function form_init() { var x = new dojo.io.FormBind({ formNode: "p_adder", load: function(type, data, e) { dojo.byId("p_output").innerHTML = data; } }); x.onSubmit = function(form) { dojo.byId("add_button").innerHTML = " "; dojo.byId("close_button").innerHTML = ''; dojo.byId("p_output").innerHTML = "Loading..."; return true; } }

How to call a javascript

How to call a javascript method while clicking a dojo tab?

What about Web 2.0 forms

What about Web 2.0 forms processing with dojo?
The original post discussed 'sprinkling' dojo in with existing Web 1.0 code. What if you are writing form-processing logic using dojo from scratch? Where is a good example of submitting values from a form to a java or jsp server, and updating portions of the markup, instead of refreshing the whole form?

What about Web 2.0

What about Web 2.0 forms
What about Web 2.0 forms processing with dojo?
The original post discussed 'sprinkling' dojo in with existing Web 1.0 code. What if you are writing form-processing logic using dojo from scratch? Where is a good example of submitting values from a form to a java or jsp server, and updating portions of the markup, instead of refreshing the whole form?

The example is not available. I tried the link but no luck

Hi All!
Please excuse my post but I am trying to get a simple example of using the Dojo tools with simple form validation. (no ajax yet) I am wanting to use the Dojo tools to simplify the javascript validation of the form fields but I still want to process the page as before. It was my hope that the example above would do that. The link to the demo and the download are both non-functional.

"You can play with the demo to see it in action." /// not working
and "...get the latest nightly build to play with it." /// not working

Does anyone have an example of a simple page using dojo validation without ajax an calbacks. I want to use Dojo but I cannot rebuild the supporting pages before I have a better handle on it. Any help or links would be much appreciated.

Thank you for your help.
Don Myers