How can I add and remove <fieldsets> dynamically using prototype and scriptaculous?

I am writing a basic recipe organizing application and I would like to be able to dynamically add additional items to an ingredient list using Ajax.

Here's what one of the ingredients looks like <fieldset>

:

<fieldset id="ingredient_item_0">
    Ingredient <input id="ingredient_0" type="text" size="20" />
    <div id="ingredient_list_0" style="" class="autocomplete"></div>

    Amount <input id="amount_0" type="text" size="5" />

    Unit <input id="unit_0" type="text" size="20" />
    <div id="unit_list_0" class="autocomplete"></div>

    Notes <input id="notes_0" type="text" size="20" />

    <script type="text/javascript">
        new Ajax.Autocompleter('ingredient_0','ingredient_list_0','ingredients.php', {'method':'get', 'paramName': 't'});
        new Ajax.Autocompleter('unit_0','unit_list_0','units.php', {'method':'get', 'paramName': 't'});
    </script>
</fieldset>

      

What is the best way (using prototype and script) to add additional copies of this <fieldset>

with accompanying JavaScript to the page, making sure each has a unique ID?

+2


source to share


2 answers


If you already have a good html template, the easiest way is to use regexp to convert template IDs to unique IDs, insert the html template where you want it in the document, and parse the scripts. Prototype Element.insert

does all the html input and script evaluation work for you.

Let's say you have a template in a hidden div called ingredient_template

, and you mark all the places where you need a unique ID with XXX

:

<div id="ingredient_template" style="display:none;">
    <fieldset id="ingredient_item_XXX">
        Ingredient <input id="ingredient_XXX" type="text" size="20" />
        <div id="ingredient_list_XXX" style="" class="autocomplete"></div>
        ...
    </fieldset>
</div>

      

And say you want to add it to the element ingredients_list

:



<div id="ingredients_list"></div>
<button type="button" onclick="addIngredient()">Add Ingredient</button>

      

You can use this javascript function to search for a pattern, replace XXX

with the following ingredient number, and paste it into ingredients_list

:

var ingredientCount = 0;
function addIngredient() {
    var html = $("ingredient_template").innerHTML.replace(/XXX/g, ingredientCount++);
    $("ingredients_list").insert(html);
}

      

+2


source


FYI it is better to use prototype to assign a unique id to an element with no id:

$('element').identify();

      

In the context of what you are doing, I personally would use the Prototype Template function , which converts the code to something like this:



var myTemplate = new Template('<div id="ingredient_template" style="display:none;">'+
                              '<fieldset id="ingredient_item_#{num}">'+
                              'Ingredient <input id="ingredient_#{num}" type="text" size="20" />'+
                              '<div id="ingredient_list_#{num}" style="" class="autocomplete"></div>'+
                              '</fieldset>'+
                              '</div>');


function addIngredient(){
  ingredientCount ++;
  var vals = {num: ingredientCount};
  var htmlstr = myTemplate.evaluate(vals);
  $('ingredients_list').insert(htmlstr)
}

      

Nothing wrong with Justin's code, just to show that theres always many ways to achieve the same. In your case, there is only one variable that can be manipulated, but since patterns allow multiple replacements, they can be a much more elegant solution that replaces multiple regexes.

+1


source







All Articles