Simple Line-Duplicater with Prototype

Many programmers might have the problem with form where multiple input lines should be possible for one field. Most of the time this is solved by using multiple text inputs which are arranged in a table. To give the visitor the ability to add another line, most of the forms are “submitted” but without runnig the saving algorithm. Afterwards the form is reloaded with an additional line.

But thankfully we are much further today. A solution with JavaScript was even possible in the past, but with the use of modern JavaScript frameworks like Prototype the whole problem can be solved with a single line of code:

$$('#table tr').last().insert({'after' : this.cloneNode(true)});

I have to admit that I used some functions in row, but this line of code can easily be used in an inline event handler.

But what happens in this line? Let’s start with the $$() function. Here we use a CSS selector to get all TR tags from a table with the ID “table” and then select the last row using the last() function. On this line we then use the insert() function. The row itself is stored in the “this” variable. We can than use the cloneNode() function to duplicate the row. At last we can insert the duplicated row after the last row using “after” as the position option.

As the last row is copied all form fields wil also be copied. To avoid that the fields have to be reset. The code included in a function with two addition callback function looks like this:

function addRow(selector, options){
	var lastRow = $$(selector).last();
	var newRow = lastRow.cloneNode(true);
	if (options.reset) {
		newRow.select('select', 'textarea', 'input').each(function(elm){
			elm.clear().checked = '';
		});
	}
	if(options.beforeInsert) options.beforeInsert(newRow);
	lastRow.insert({'after': newRow});
	if(options.afterInsert) options.afterInsert(newRow);
}

When we set the reset parameter in the options hash to true, all the form fiels in the row will be reset before inserting the row. To reset the fields we first selct all of them using the select() function and using the each each() function we can than use the clear() function to reset them. On radiobuttons and checkboxes we also reset the “checked” attribute.

The function can now be assigned to any element. Usually you would use a link, a SPAN or an image for that:

<span onclick="addRow('table', {reset: true, beforeInsert: doSomeMagic})">Zeile hinzufügen</span>

In this example the reset parameter is set “true” and we added a callback function which will be called before inserting the new row. The callback function “beforeInsert” can be used to e.g. update the LABEL tags in the new row. The callback function afterInsert can be used to e.g. assign event hander or other functions to the an element of the new line, which should be done after inserting the new row. Both callbacks get a reference to the new row.

As a small example I changed my form of the previous post and used the function to add another e-mail address. Here you can see the example or download the sourcecode:

Demo Download

In this exmaple I used a much more complex CSS selector:

<span onclick="addRow('form dl:first-of-type dd ul li', {reset: true})">Add address</span>

As you can see, you can use the function on any element on which it make sens to duplicate it line by line.

If a jQuery pro is among you, I would like to see a solution using jQuery. But I am not experienced enough to write the same function in jQuery. If anyone has comments to the Prototype version I would also like to hear them.

Posted by

Bernhard is a full time web developer who likes to write WordPress plugins in his free time and is an active member of the WP Meetups in Berlin and Potsdam.

4 comments » Write a comment

  1. Den Zeilen Duplizierer finde ich sehr gut. Ich möchte eine Zeile kopieren, die einen Autocompleter von Scriptaculous enthält. Funktioniert das auch mit diesem Duplizierer? Könnte ich ein Beispiel bekommen?

    • Hallo trenied,

      ja das funktioniert. Und witziger weise habe ich die Funktion auch in einem solchen Fall im Einsatz. Aber da man das ganze etwas ausführlicher erklären sollte habe ich mich entschlossen dazu einen neuen Artikel zu schreiben: Zeilen-Duplizierer mit AutoComplete Felder nutzen. Ich hoffe, das ist genau das, was du suchst.

      Gruß
      Bernhard

Leave a Reply

Your email address will not be published. Required fields are marked *