This is the documentation for concrete5 version 5.6 and earlier. View Current Documentation

Combine Concrete5, HTML text input elements, php array handling and jQuery to handle a form with a variable number of input elements.

Variations of this technique are used throughout Concrete5 and various add-ons to create forms with a variable number of input elements, so the user can add or remove items from a list.

Example list

The example manages a list of names, so first some initial values for the list.

<?php
$all_names = array ('Franz', 'Andrew');
?>

These names will be displayed as a list of text input elements so they can be edited. As we want the list to be dynamic, we first need a couple of icons to we can click on to add and remove inputs.

<?php
$remove_row_icon = '<img src="'.ASSETS_URL_IMAGES.'/icons/remove_minus.png" class="remove_row" height="14" width="14" >';
$add_row_icon  = '<img src="'.ASSETS_URL_IMAGES.'/icons/add_small.png" class="add_row" height="14" width="14" >';
?>

Now we create a list of text input elements as rows of a table. The surrounding form and submit controls have been left out for clarity in the example.

<table>
<tr><td><?php echo 'Name';?></td><td></td></tr>
<?php 
foreach($all_names as $a_name) { ?>
  <tr>
  <td><input type="text" size="10"  name="all_names[]"   value="<?php  echo $a_name ?>" ></td>
  <td><?php echo $add_row_icon; echo (' '); echo $remove_row_icon;?></td>
  </tr> <?php  
}?>
</table>

The list is made dynamic by using jQuery to catch clicks to the add and remove icons. This is done by attaching 'live' click event handlers because these will bind to any new rows the user creates.

jQuery will not necessarily be loaded when viewing a page, so developers may need to use addHeaderItem to load jquery.js,

When the add icon is clicked, the row clicked is cloned, the cloned input element emptied, and the clone then inserted after the clicked row.

When the remove icon is clicked, the row clicked is removed.

<script type="text/javascript">
$(document).ready(function(){
  $('.add_row').live('click',function(){
    var copy_of_row = $(this).closest('tr').clone();
    $(copy_of_row).find('input').val('');
    $(this).closest('tr').after(copy_of_row);
  });

  $('.remove_row').live('click',function(){
    $(this).closest('tr').remove();
  });

});
</script>

As of jQuery 1.7 the jQuery 'live' method is deprecated and scheduled for removal in a subsequent revision. The 'on' method is now the preferred way to do this:

$('table').on('click', '.add_row', function(){....

example list extended

On the server, the controller or tool handling the submitted form can get all the rows as an array from $_POST.

$all_names = $_POST['all_names'];

This is just the raw basic technique. As already noted above, a form and submit button are needed to wrap the table of text input elements. Additional php and jQuery are also needed to handle edge cases such as an empty list, or a list that is emptied by the user. Dynamic lists may also need to be sortable, a related technique not covered in this how-to.

Read more How-tos by JohntheFish

Loading Conversation