-1

How can I make a repeater type in the page. In the page I have a quantity field:

<td>
    @Html.DisplayNameFor(x => x.Quantity)
    @Html.ValidationMessageFor(x => x.Quantity)
</td>
<td>
    @Html.TextBoxFor(x => x.Quantity, new { @id = "txtQty" })
</td>

When I want to add the item, which there could be several of the same item, just different serial numbers, I need to pop open a div with repeated fields for entering serial numbers:

for (int I = 0; I < *****; I++)
{
    <td>Serial Number:</td>
    <td>@Html.TextboxFor(x=>x.Quantity, new { @id = "txtQty" + 1})
}

In the JS:

function AddItem() {
    Qtys = parseINT($("#txtQty").val());
    $("#divSerials").show();
}

How can I do this? Is there a better way?

Is this the way to do it? I try this but 'i' in the HTML model statement is not recognized.

 if (parseInt($("#txtQuantity").val()) > 0) {
            $("#divSerialNumbers").show();
            var html = "<table>";
            for (i = 1; i <= serialquantity; i++) {
                html += "<tr><td>Serial Number:" + @Html.TextAreaFor(x => x.SerialNumber, new { id = "sns" + i }) + "</td></tr>";
            }
            html += "</table>";
            $("#divSerialNumbers").html(html);
        }
Dean.DePue
  • 1,013
  • 1
  • 21
  • 45
  • It is not so clear what you are trying to do... You want several text boxes? You can use array, and make TextBoxFor(x=>x.yourArray[i]) – Ziv Weissman Apr 22 '15 at 12:32
  • If I understand you correctly and you want to set the number of loops dynamically, there's no way to do that with Razor. You could use javascript and clone / duplicate the DOM section that contains the label and textbox, then set the new 'id' property. – valentin Apr 22 '15 at 13:03

1 Answers1

0

Razor code is parsed on the server before it is sent to the view. Javascript is client side code and is not executed until the browser receives the view. This line of code

@Html.TextAreaFor(x => x.SerialNumber, new { id = "sns" + i })

means that on the server you are trying to generate a textarea and set the id attribute to a value that includes a javascript variable which does not yet exist.

Its unclear even what the point of this would be. id attributes serve as selectors in javascript. Whats important is the name and value attributes when it comes to posting your data, and even if it could work, your generating duplicate name attributes which could not bind to you models collection property on post back.

For dynamically generating the html for collections, your name attributes need an indexer, for example <input type="text" name="[0].SerialNumber" />. Options for dynamically creating the html include using the BeginCollectionitem() helper, or a pure client side approach is shown in this answer

If all you are doing is post back an array of strings (the serial numbers) then you could use

var div = $("#divSerialNumbers"); // cache it
$('#Quantity').change(function() { // assumes you remove the pointless 'new { @id = "txtQty" }'
  var quantity = parseInt($(this).val()); // use $(this) - don't traverse the DOM all over again
  if (!isNan(quantity) && quantity > 0) { // must check for NAN
    // note it does not seem necessary to use a table, as opposed to simply adding 4 inputs to the div, but
    div.empty(); // clear existing contents
    var table = $('</table>');
    for (i = 1; i <= quantity; i++) {
      var input = $('<input>').attr('name', 'SerialNumber');
      var cell = $('</td>').append(input);
      var row = $('</tr>').append(cell);
      table.append(row);
    }
    div.append(table).show(); // add the table and display it
  }
})

and your controller would need a parameter string[] SerialNumber, for example

public ActionResult Edit(string[] SerialNumber)
Community
  • 1
  • 1