Adding form fields via ajax with Mootools
I am currently working on a project where the administrator needs to be able to upload any number of items within one master project.
Clearly I didn’t want to present them with a long page of repetative form fields and anyway, there was no way of knowing whether they would need 1, 2 or 20 items.
The solution?
Use some simple mootools ajax magic to fetch the form fields dynamically from an external file.
I choose to use ajax rather than coding the form fields directly into the javascript for several reasons.
- Firstly because they where a rather complicated mix of all sorts of form fields that would be a nightmare to create through javascript.
- Some of the form fields contained data fetched from the database which again would get complicated in amongst “normal” javascript
- By using an external file and sending it a defining value, I could use the same code for different forms (using a php switch on the “type” value passed) without having to touch the javascript again.
Here is how I did it:
The HTML
<form method="post" id="item_form" enctype="multipart/form-data"> <div id="form_data"> <!-- the form fields will be loaded here via ajax --> </div> <div> <span id="loading"></span> <input type="button" id="add_item" value="Add New Form"> <input type="submit" value="Submit"> </div> </form>
The JAVASCRIPT (mootools)
window.addEvent('domready', function() { var counter=0; function new_rows(){ counter=counter+1; var myHTMLRequest = new Request({ url:'load.ajax.php', method:'get', autoCancel:true, data: {'type':'item','field_name':'add',num:counter}, onRequest: function() { $('loading').set('html','<img src=\"images/ajax-loader.gif\">'); }, onComplete: function(responseText) { var new_rows = new Element('div', { 'html': responseText }); // inject new fields at bottom new_rows.inject($('form_data'),'bottom'); // remove loading image $('loading').set('text',''); // scroll down to new form fields var myFx = new Fx.Scroll(window).toElement('table_'+counter); } }).send(); } $('add_item').addEvent('click', function(e){ e.stop(); // stop the default submission of the form new_rows(); }); //load first set of rows - all rows are loaded via ajax new_rows(); });
The PHP (ajax loaded file)
// check we have data if(!isset($_GET["field_name"])) die("error with data"); if(!isset($_GET["type"])) die("Error with data"); // define vars (should do more checking here) $field_name = $_GET["field_name"]; $form_type = $_GET["type"]; $num = $_GET["num"]; switch($form_type){ case "item": echo ' <table id="table_'.$num.'"> <tr> <td rowspan="4">Table '.$num.'</td> <td>Image</td> <td><input type="file" name="file_2_upload[]" style="width:99%;"></td> </tr> <tr> <td>Title</td> <td><input type="text" name="'.$field_name.'[title][]" value="" style="width:99%;"></td> </tr> <tr> <td>Color</td> <td> <select name="'.$field_name.'[options]"> <option value="1">White</option> <option value="2">Red</option> <option value="3">Blue</option> <option value="4">Yellow</option> </select> </td> </tr> <tr> <td>Description</td> <td><textarea name="'.$field_name.'[summary][]" style="width:99%; height:100px;"></textarea></td> </tr> </table> '; break; default: echo "nothing doing, sorry"; break; }
Clearly my php file is just an example, you could define and format the form fields however you need for your aplication.
I hope you find it useful 🙂
chris@cbolson.com
There are 19 comments in this article: