Limiting the number of text fields created
Bored, so I made a few improvements as I mentioned (in the comments that have vanished when this was moved to Code Review):

Use the jQuery shortcut DOM-ready handler

A handy short-cut for your DOM ready, with locally scoped $ is just jQuery(function($){...});

Store templates in HTML, not JavaScript strings:

&lt;script id="template" type="text/template"&gt;
    &lt;p class="text-box"&gt;
       &lt;label for="box{n}"&gt;Name &lt;span class="box-number"&gt;{n}&lt;/span&gt;&lt;/label&gt; &lt;input type="text" name="on{-1}" value="" id="box{n}" /&gt; &lt;a href="#" class="remove-box"&gt;Remove&lt;/a&gt;
    &lt;/p&gt;
&lt;/script&gt;


and access like this:

var box_html = $('#template').html().replace(/{n}/g, n).replace(/{-1}/g, n-1);
var $box = $(box_html);


Count the current items when you need them

var n = $('.text-box').length + 1;
if (n &lt;= max_fields) {


Restrict to the current "group" of inputs:

var $form = $(this).closest('.my-form');
$('p.text-box:last', $form).after($box);


This also means it can now handle multiple sets of inputs, each with different name/id prefixes.

Combine operations when you can:

$box.hide().fadeIn('slow');


Putting it all together:

JSFiddle: http://jsfiddle.net/TrueBlueAussie/q2emvzdd/4/

Notes:


A prefix was needs to be supplied by the parent form (e.g. a data attribute) so that each set of inputs has unique IDs and names. This is not applied to the first entry yet, but I have to go now, so something for you to finish :)