1

I'm looking for a way to add additional rows to a table based on the value selected from a dropdown list or slider..

Taking this as a very basic table :

<html>
<head>
  <title></title>
</head>
<body>
<table border="1">
  <thead><tr>
    <th>Name</th>
    <th>A</th>
    <th>B</th>
    <th>C</th>
    <th>D</th>
    <th>E</th>
    <th>F</th>
  </tr>
  </thead><tbody>
    <tr>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td><input type="checkbox"></td>
    </tr>
  </tbody>
</table>
<br>
</body>
</html>

I'd like to add a dropdown or slider that allows the user to increase or decrease the number of rows visible and that they can complete. Then when the form is submitted all values would be submitted as normal. Any idea how I can do that?

I'd also like to use a check box in the last column to allow the user to duplicate all the values except the name from the first row to any row that they check.. is that possible? Especially if they update row one would the others update?

Pointers or links gratefully received :)

2
  • So that is two questions. Did you try something? Here is a fiddle to start jsfiddle.net/mplungjan/fRdE6 Commented Jul 11, 2013 at 8:16
  • Does the user want to copy from row one, then modify something in that new row and will modifying row one then replace the new values in the row he just updated? Commented Jul 11, 2013 at 8:18

2 Answers 2

7

Here you go. Custom coding just for you

Live Demo

$(function(){
    var $tbody = $("#tb1"),$firstRow=$("#tb1 tr").eq(0);
    $('#defaultSlider').change(function(){
        var val = this.value;
        $('#currentValue').html(val);
        $tbody.find("tr:gt("+val+")").remove();
        for (var i = $("#tb1 tr").length;i<val;i++) {
            $tbody.append('<tr><td></td><td></td><td></td><td></td><td></td><td></td><td><input type="checkbox" class="copy"/></td></tr>');
        }
    }).change(); // Trigger the event on load, so the table is populated:

    $firstRow.find("input[type=text]").each(function(i) {
        $(this).on("blur",function() { // or keyup if useful
          var val = $(this).val();  
          var idx = i;
          var $checked = $("#tb1 tr").find("input[type=checkbox]:checked");
          $checked.each(function(i) {
            if (i>0) {
              // we may want to keep existing input 
              // perhaps even uncheck row if inout changed, but for now overwrite
              $(this).closest("tr").find("input").eq(idx).val(val);
            }
          });
        });
    });
    $tbody.on("change","tr .copy",function() {
        if (this.checked) {
            var $newRow = $firstRow.clone(true);
            $newRow.find("td:first input").val("")
            $(this).closest("tr").replaceWith($newRow);
        } 
    });
});
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks @RichBradshaw - erm what about the solution?
Oh yeah :) That's cool too! I would have used .trigger('change'); after the first }); to trigger a change instantly after binding the change event, and wouldn't have dropped the { and } on the if, but otherwise looks good to me :)
Very well, I moved it around
Sorry I've been away a few days. This is great thanks :) Is there anyway to get it so the rows are editable without having to copy from the first row ?
1

Rather than doing this manually I'd suggest using Knockout or something similar. The benfit of this is no extra id, classes and this separates the concerns, now there is no nasty markup in the JavaScript. Also now the model is updated with the values from the textboxs so you simply need call the values in the model to get anything.

Here is a forked example of the above with Knockout

http://jsfiddle.net/scottreeddev/pZhh7/

var my = {};
var lastValue = 1;

my.Row = function()
{
    var self = this;
    self.Name = ko.observable("");
    self.RowA = ko.observable("");
    self.RowB = ko.observable("");
    self.RowC = ko.observable("");
    self.RowD = ko.observable("");
    self.RowE = ko.observable("");
    self.RowF = ko.observable(false);
};

my.viewmodel = 
    {
        RowCollection: ko.observableArray([new my.Row()]),
        SliderValue: ko.observable(1)
    };

my.viewmodel.SliderValue.subscribe(function () {
    var sliderValue = parseInt(my.viewmodel.SliderValue());
    if(sliderValue > lastValue)
    {
        my.viewmodel.RowCollection.push(new my.Row());
    }
    else
    {
        my.viewmodel.RowCollection.pop();
    }
    lastValue = sliderValue;
}, my.viewmodel);

ko.applyBindings(my.viewmodel);

1 Comment

The bigger difference is that I have no idea what I just read... And how does it copy the first row?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.