I have a script which dynamically adds rows to a form with default values:
$(document).ready(function() {
var defaults = {
'name[]': 'Name',
'email[]': 'Email',
'organisation[]': 'Organisation',
'position[]': 'Position'
};
var setDefaults = function(inputElements, removeDefault)
{
$(inputElements).each(function() {
if (removeDefault)
{
if ($(this).data('isDefault'))
{
$(this).val('')
.removeData('isDefault')
.removeClass('default_value');
}
}
else
{
var d = defaults[this.name];
if (d && d.length)
{
this.value = d;
$(this).data('isDefault', true)
.addClass('default_value');
}
}
});
};
setDefaults(jQuery('form[name=booking] input'));
$(".add").click(function() {
var x = $("form > p:first-child").clone(true).insertBefore("form > p:last-child");
setDefaults(x.find('input'));
return false;
});
$(".remove").click(function() {
$(this).parent().remove();
});
// Toggles
$('form[name=booking]').delegate('input', {
'focus': function() {
setDefaults(this, true);
},
'blur': function() {
if (!this.value.length) setDefaults(this);
}
});
});
For the following form:
<form method="post" name="booking" action="bookingengine.php">
<p><input type="text" name="name[]">
<input type="text" name="email[]">
<input type="text" name="organisation[]">
<input type="text" name="position[]">
<span class="remove">Remove</span></p>
<p><span class="add">Add person</span><br /><br /><input type="submit" name="submit" id="submit" value="Submit" class="submit-button" /></p>
</form>
I would now like to split the form into 2 sections, each of which can have rows added dynamically to it. The second section would only have spaces for name and email, so the form as a whole, before any additional rows are added, would look something like this:

But I’m not sure how to achieve this. Either I would create a separate form with a seperate script, and then would need to know how to submit the information from both forms together, or I would just have one form but would then need to work out how to add rows dynamically to each section.
Could someone help with this?
Thanks,
Nick
I’ve implemented this in a fully functional example here.
I cleaned up your code a little bit, but it’s basically the same. The main addition is that I wrapped the inputs in a
fieldsetelement (you could use adivjust as well, butfieldsetis the semantically correct element for grouping related input fields). Your 4-input section lives in onefieldset, and your 2-input section lives in another; the “Add Person” handler looks for the parentfieldset, clones the first child, and adds it into that fieldset. Conveniently, in your use case the defaults for the firstfieldsetare the same as those for the secondfieldset, but it would be easy enough to set up multiple sets of defaults and pass them into thesetDefaultsfunction.A few other changes to the code:
I split your
setDefaultsfunction into two different functions,setDefaultsandremoveDefaults– you weren’t gaining anything by making them a single function, and splitting them makes the code more legible.I used
.delegateto assign the “Remove” handler – otherwise the “Remove” button wouldn’t work for new input sets. I also created the “Remove” button with jQuery, rather than cloning it, because I assumed that it wouldn’t make sense to include it for the first input set.I used jQuery in a couple of places where you were using raw Javascript (e.g. getting and setting input values). I generally assume that jQuery is more reliable for cross-browser DOM access and manipulation, so if you’re loading the library already there’s rarely any point not using it for all but the simplest DOM functions.
I removed your
.datacalls, since you can get the same information by inspecting the class, and it’s generally better to reduce complexity. It’s possible that.hasClass('test')is slightly slower than.data('test'), but I don’t think it should make any difference here.