0

I am trying to the find, and add, the value of indexed fields in each row of a table.

 <tr>
   <td><input name="Model[0].Name" type="hidden" value="0" /></td>
   <td><input name="Model[0].Sched" type="hidden" value="0" /></td>
   <td><input name="Model[0].Comp" type="hidden" value="0" /></td>
   <td><input name="Model[0].NoShow" type="hidden" value="0" /></td>                    
   <td><input name="Model[0].TotalHours" type="hidden" value="0" /></td>
 </tr>
 <tr>
   <td><input name="Model[1].Name" type="hidden" value="0" /></td>
   <td><input name="Model[1].Sched" type="hidden" value="0" /></td>
   <td><input name="Model[1].Comp" type="hidden" value="0" /></td>
   <td><input name="Model[1].NoShow" type="hidden" value="0" /></td>                    
   <td><input name="Model[1].TotalHours" type="hidden" value="0" /></td>
 </tr>

I would like to add Model[n].Sched + Model[n].Comp + Model[n].NoShow = Model[n].TotalHours for each row.

I think there must be a simple solution to this, but I must be searching for a solution using in the incorrect keywords.

TIA!

Leo
  • 665
  • 2
  • 9
  • 25
Daniela
  • 657
  • 1
  • 10
  • 25
  • Iterate over all rows, for each row, find all `input` elements and sum the values of the first 3? – Felix Kling Sep 20 '16 at 19:04
  • There are other fields in the row. I left them out because I thought they were irrelevant. So the first 3 wouldn't work. There must be a way to find the fields by name. – Daniela Sep 20 '16 at 19:08
  • Sure there is: https://api.jquery.com/attribute-contains-selector/. – Felix Kling Sep 20 '16 at 19:09
  • This seems like a very strange naming scheme. I don't know how the server code will interpret `POST` fields with names like this. – Barmar Sep 20 '16 at 19:50
  • 1
    I simplified the names down for readability. The post will iterate over each row and update (C#). The C# I have down, it is jQuery that I am unfamiliar with. – Daniela Sep 20 '16 at 19:53
  • 1
    @Barmar, this is what she is trying to do: http://stackoverflow.com/questions/15375800/model-binding-to-a-list-mvc-4 – Leo Sep 22 '16 at 12:17

3 Answers3

3

As I mentioned in my commend, iterate over each row and search for all inputs in each row. If you have to only get the inputs with the specific name, you can use the attribute contains selector:

$('tr').each(function() {
  // Find the the input we want to set the value of
  $(this).find('input[name*="TotalHours"]').val(
    // Find the inputs we want to sum
    $(this).find('[name*="Sched"], [name*="Comp"], [name*="NoShow"]')
      // Get their values and convert them to numbers
      .map(function() { return Number(this.value); })
      .get()
      // sum the values
      .reduce(function(sum, v) { return sum + v; })
  );
});

$('tr').each(function() {
  // Find the the input we want to set the value of
  $(this).find('input[name*="TotalHours"]').val(
    // Find the inputs we want to sum
    $(this).find('[name*="Sched"], [name*="Comp"], [name*="NoShow"]')
    // Get theirs values and convert them to numbers
    .map(function() {
      return Number(this.value);
    })
    .get()
    // sum the values
    .reduce(function(sum, v) {
      return sum + v;
    })
  );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr>
    <td>
      <input name="[0].Sched" value="1" />
    </td>
    <td>
      <input name="[0].Comp" value="2" />
    </td>
    <td>
      <input name="[0].NoShow" value="3" />
    </td>
    <td>
      <input name="[0].TotalHours" value="0" />
    </td>
  </tr>
  <tr>
    <td>
      <input name="[1].Sched" value="4" />
    </td>
    <td>
      <input name="[1].Comp" value="5" />
    </td>
    <td>
      <input name="[1].NoShow" value="6" />
    </td>
    <td>
      <input name="[1].TotalHours" value="0" />
    </td>
  </tr>
</table>
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
0

Iterate over each row and then inside iterate over each column. If the name doesn't contain TotalHours add it's value to the sum. If it does contain TotalHours then set the value equal to the sum. Here is an example with values not 0 and not hidden.

$('tr').each(function(index) {
  var sum=0;
  $('td input',this).each(function(){
    if($(this).attr('name').indexOf('TotalHours')==-1){
      sum+=parseInt($(this).val());
    }else{
      $(this).val(sum);
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
  <tr>
    <td>
      <input name="[0].Sched" value="10" />
    </td>
    <td>
      <input name="[0].Comp" value="20" />
    </td>
    <td>
      <input name="[0].NoShow" value="30" />
    </td>
    <td>
      <input name="[0].TotalHours" value="0" />
    </td>
  </tr>
  <tr>
    <td>
      <input name="[1].Sched" value="5" />
    </td>
    <td>
      <input name="[1].Comp" value="2" />
    </td>
    <td>
      <input name="[1].NoShow" value="3" />
    </td>
    <td>
      <input name="[1].TotalHours" value="0" />
    </td>
  </tr>
</table>
depperm
  • 10,606
  • 4
  • 43
  • 67
0

You can use JavaScript String search() Method to match the input name.

Searches a string for a specified value, and returns the position of the match. The value can be string or a regular expression. If no match is found the method returns -1.

Below, an iteration occurs through each tr then each input, which searches for a specific name, if not equal -1, the variable totalHours receives the value:

$('tr').each(function() {
    var totalHours = 0;

    $(this).find('input').each(function() {
        if ($(this).attr("name").search("Sched") != -1 
                || $(this).attr("name").search("Comp") != -1 
                || $(this).attr("name").search("NoShow") != -1) {
            totalHours += Number($(this).val());
        } 
    });

    $(this).find('input[name*="TotalHours"]').val(totalHours);
});

Check it out:

JSFiddle

Leo
  • 665
  • 2
  • 9
  • 25