Search code examples
javascriptjqueryhtmlzend-form

How can I dynamically remove HTML form elements generated by Zend Form API, using JavaScript?


I am using PHP Zend Form API library, which generates HTML form code for multiple elements and provides a mechanism to add field elements dynamically via JavaScript.

The Add works great, but how can I remove an element?

Also, if you look at the code, when new elements are added, the index count is updated. Thus, if I do remove an element, and later add one, my index number will be incorrect. I think it will be a bit of a pain to actually renumber the indices. Thus, I think it's best to remove the code that adds the index and just not put one in. I believe that way they will be numbered properly anyway on form submit

Still though, how can I remove individual element rows? The ones that are wrapped by <fieldset> tags? I am looking for a good direction on how to do it.

function add_row() {
  var currentCount = $('form > fieldset > fieldset').length;
  var template = $('form > fieldset > span').data('template');
  template = template.replace(/__index__/g, currentCount);

  $('form > fieldset').append(template);

  return false;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button onclick="return add_row()">Add a new form row</button>

<form action="" id="selection" method="post" name="selection">
  <fieldset>
    <fieldset>
      <label><span>Flow:</span><input name="points[0][flow]" type="number" value="3"></label><label><span>Pressure:</span><input name="points[0][pressure]" type="number" value="3"></label>
    </fieldset>
    <fieldset>
      <label><span>Flow:</span><input name="points[1][flow]" type="number" value="3"></label><label><span>Pressure:</span><input name="points[1][pressure]" type="number" value="3"></label>
    </fieldset><span data-template="&lt;fieldset&gt;&lt;label&gt;&lt;span&gt;Flow:&lt;/span&gt;&lt;input type=&quot;number&quot; name=&quot;points&amp;#x5B;__index__&amp;#x5D;&amp;#x5B;flow&amp;#x5D;&quot; value=&quot;&quot;&gt;&lt;/label&gt;&lt;label&gt;&lt;span&gt;Pressure:&lt;/span&gt;&lt;input type=&quot;number&quot; name=&quot;points&amp;#x5B;__index__&amp;#x5D;&amp;#x5B;pressure&amp;#x5D;&quot; value=&quot;&quot;&gt;&lt;/label&gt;&lt;/fieldset&gt;"></span>
  </fieldset>
</form>

I rewrote add_row() method to have a strictly increasing index, instead of using fieldset count, since removing a row removes index at that row, and does not keep track of last index. Adding rows must add index that is larger than the last index.

After deleting/adding rows indices may be sparse, i.e. 0, 2, 6, 16. They transparently get populated into the object I have on PHP side, with ordered indices starting from 0.

add_row() is now this:

<div id="newRowIndex" style="display:none">1</div>

<script>
function add_row()
{
    var newRowIndex = $('#newRowIndex').text();
    $('#newRowIndex').text(++newRowIndex);
    var template = $('form > fieldset > span').data('template');
    template = template.replace(/__index__/g, newRowIndex);

    $('form > fieldset').append(template);

    return false;
}
</script>

Solution

  • Add a button to each row

    <fieldset>
         <label><span>Flow:</span><input name="points[0][flow]" type="number"    value="3"></label>
         <label><span>Pressure:</span><input name="points[0][pressure]" type="number" value="3"></label>
         <button class="removeLine">Delete Row</button>
    </fieldset>
    

    and a little jquery

    $(function(){
        $("#selection").on("click",".removeLine",function(){
            $(this).closest("fieldset").remove();
            return false;
        });
    });
    

    You can add the remove button dynamically. just put addRemove() before the return false in the add_row function and include the below

    function addRemove(){
      $("form fieldset fieldset").last().append("<button class='removeLine'>Delete Row</button>");
    }