#1
  1. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2016
    Location
    Lakewood, WA
    Posts
    192
    Rep Power
    17

    Adding field rows to form "on the fly"


    I have a form input where the data input is a set of related values that go into a record of a database.

    The form should allow the user to put in multiple "rows" with one form.

    Example: 4 rows equal 4 records.

    The form can start out with a "default" number of input rows as a convenience, but the user doesn't have to use all of them, and can add more if needed.

    Two ideas for adding more input rows:

    A) When all the existing rows are filled (or at any time...), the user can request more rows from a dropdown or some other selector, and the form can be refreshed with a traditional POST method to have PHP build the additional empty rows.

    B) Use JavaScript (jQuery or pure JS...) to dynamically create the new rows.

    Which method is most commonly used to manipulate the UI for this sort of thing? Are there any tradeoffs such as stability verses the subjective "user friendly elegant UI"? And of course which presents the least possible issues with the form processing?

    I'm leaning in the direction of the JS option.

    Any opinions?
  2. #2
  3. Forgotten Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    16,212
    Rep Power
    9644
    (b) is more common now.

    While there are no doubt plugins and libraries, I've always done it manually with jQuery.
    Code:
    <table class="templated">
    	<thead>
    		<tr>
    			<th>First</th>
    			<th>Last</th>
    			<th></th>
    		</tr>
    	</thead>
    	<tbody>
    		<tr class="template">
    			<td><input type="text" name="row[$id][first]"></td>
    			<td><input type="text" name="row[$id][last]"></td>
    			<td><button class="template-remove" type="button">Remove</button></td>
    		</tr>
    	</tbody>
    	<tfoot>
    		<tr>
    			<td colspan="2"></td>
    			<td><button class="template-add" type="button">Add</button></td>
    		</tr>
    	</tfoot>
    </table>
    javascript Code:
    $(function() {
    	$(".templated").each(function() {
    		var $templated = $(this);
    		var $template = $templated.find(".template");
    		var $container = $template.parent();
     
    		$template.remove();
     
    		var fnadd, fnremove;
    		$templated.on("click", ".template-add", fnadd = function() {
    			$container.append($template.html().replace("$id", "x" + new Date().getTime() + Math.floor(Math.random() * 1e9)));
    		});
    		$templated.on("click", ".template-remove", fnremove = function() {
    			$(this).closest(".template").remove();
    		});
     
    		fnadd();
    	});
    });
  4. #3
  5. Banned (not really)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Dec 1999
    Location
    Caro, Michigan
    Posts
    14,748
    Rep Power
    4536
    So in testing that code and not knowing what I'm doing at all, it adds three new <td> elements for the first name, last name and remove button. Only the first name is changed to a row[x1234123412341234][first] format. Last name remains as $id.

    How would I modify this to add an additional row instead of <td> elements?

    The remove button does not seem to have any effect, either.

    -John
    -- Cigars, whiskey and wild, wild women. --
  6. #4
  7. Banned (not really)
    Devshed Supreme Being (6500+ posts)

    Join Date
    Dec 1999
    Location
    Caro, Michigan
    Posts
    14,748
    Rep Power
    4536
    Nevermind, I figured it out. Had to move class="template" up to the <tbody> element.

    In the script, the replace() was changed to use a regular expression so that all instances were replaced. Then the closest() was made to remove the closest "tr" element.

    Code:
    $(function() {
        $(".templated").each(function() {
          var $templated = $(this);
          var $template = $templated.find(".template");
          var $container = $template.parent();
    
          $template.remove();
    
          var fnadd, fnremove;
          $templated.on("click", ".template-add", fnadd = function() {
            label = "x" + new Date().getTime() + Math.floor(Math.random() * 1e9);
            $container.append($template.html().replace(/\$id/g, label ));
          });
          $templated.on("click", ".template-remove", fnremove = function() {
            $(this).closest("tr").remove();
          });
    
          fnadd();
        });
      });
    -- Cigars, whiskey and wild, wild women. --
  8. #5
  9. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2016
    Location
    Lakewood, WA
    Posts
    192
    Rep Power
    17
    I think the best thing for this sort of thing is for me to start working with jQuery, which seems to have all this (and more) handled. I'm especially liking the AJAX functions (Sep was asking about AJAX vs. WebSockets for something he was working on). Actually, the jQuery UI stuff is amazing, I'm going to have to control myself not to go overboard!

IMN logo majestic logo threadwatch logo seochat tools logo