HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Dynamically adding rows to an accessible HTML form

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
rowsdynamicallyaccessibleaddingformhtml

Problem

Given the following HTML form (fragment):


    Add Entries

    
      Project
      
        
      

      Department
      
        
      

      Task: 
      
        
      

      Hours: 
      

      Comment: 
      
    

    

  


I have implemented the following jQuery (fragment) to clone each 'timesheet row' ` along with the tags, which are not caught by $(':input')`:

$(document).ready(function() {

  var current_id = 0;
  $('#add-row').click(function(){
    next_element($('#timesheetrow-0'));
  })

  function next_element(element){
    var new_element = element.clone(),
        id = current_id + 1;
    current_id = id;
    new_element.attr("id",element.attr("id").split("-")[0]+"-"+id);

    // Ajuster les `id` et `name` dans les s et s
    $(':input', new_element).each(function(){
      var field_id = $(this).attr("id"),
          field_name = $(this).attr("name");
      $(this).attr("id", field_id.split("-")[0]+"-"+id );
      $(this).attr("name", field_name.split("-")[0]+"-"+id );
    });

    // Ajuster le for="" dans les s
    $('label', new_element).each(function(){
      field_for = $(this).attr("for");
      $(this).attr("for", field_for.split("-")[0]+"-"+id );
    });
    new_element.appendTo($("#timesheet-rows"));
  };
});


(Above jQuery was inspired by http://jsfiddle.net/32RgL/ ).

Is there a more elegant or complete way of doing this?

Solution

Most of this code is due to the fact that you're increasing the numbers in your attributes. I think that's a mistake. Your rows should all have identical name attributes, stored in an array (e.g. name="task[]").

The only problem would then be the identical IDs. Frankly, you shouldn't be using IDs in the first place. The only advantage of using IDs in this case is to associate the labels to the form fields (so that clicking the label focuses on the form field). This could easily be accomplished by wrapping the label around the form element.

So, to summarize, here are some points to consider:

  • Get rid of the IDs



  • Wrap the labels around the form elements to associate them with one another



  • Get rid of the numbers from the names



  • Use array like notation (e.g. name="task[]") for your names



Once you've incorporated all this, you can simply clone the row when needed.

HTML:


    Add Entries

    

        Project:
            
                
            
        

        Department:
            
                
            
        

        Task: 
            
                
            
        

        Hours:
            
        

        Comment:
            
        

    

    
​


Javascript:

jQuery(function($) {
var $button = $('#add-row'),
$row = $('.timesheet-row').clone();

$button.click(function() {
$row.clone().insertBefore( $button );
});
});​


Here's the fiddle: http://jsfiddle.net/wd5y9/

Code Snippets

<fieldset id="timesheet-rows">
    <legend>Add Entries</legend>

    <div class="timesheet-row">

        <label>Project:
            <select name="project[]" required>
                <option value=""></option>
            </select>
        </label>

        <label>Department:
            <select name="department[]" required>
                <option value=""></option>
            </select>
        </label>

        <label>Task: 
            <select name="task[]" required>
                <option value=""></option>
            </select>
        </label>

        <label>Hours:
            <input type="number" step="0.25" name="hours[]" width="1" placeholder="2.0" required />
        </label>

        <label>Comment:
            <input type="text" name="comment[]" width="50" />
        </label>

    </div>

    <input type="button" id="add-row" name="add-row" value="Add row" />
</fieldset>​

Context

StackExchange Code Review Q#13794, answer score: 2

Revisions (0)

No revisions yet.