How to set asp-for in a for loop
Asked Answered
M

1

5

I have a for loop to generate fields on a form.

How can I set the value of asp-for based on the current index?

<label asp-for=@("Value" + i) class="control-label"></label> does not work.

Madi answered 16/8, 2018 at 13:58 Comment(4)
Eh what? It's unclear what you're asking. In asp-for you pass the models property in. Are you confusing that with the HTML's <label for="someid"> ?! When you loop through an array you already have the reference to the item. i. . foreach(var item in Model) { ...} then you have a reference to item, so you can use it in asp-for like asp-for="item.Value" or asp-for="item.Name" depending on how your properties on the model class are namedScalawag
What do you mean by "does not work" ? What is the output of @("Value" + i) ? what did you expect instead ? Is there an error message ?Misdirection
You can't. The value passed for asp-for must be a ModelExpression. It can't take a generic string value representing a property. FWIW, though, having properties like Value1, Value2, Value3, etc. is pretty much always wrong. Use a collection type, instead: i.e. Values. Then, what you're attempting to do here is trivial, since you're just indexing that collection, which can be expressed as a ModelExpression.Tooth
Tseng>>>My model has several properties Value1...Value31. Based on some condition I need to either provide an input field or a hidden field. So the for loop is more like for(int i = 1; i <= 31; i++) { /* tag helper for each property */ } Wndrr >>> I get an error InvalidOperationException: Templates can be used only with field access, property access, single...Madi
B
8

You can bind the model with an index like so using ether foreach or for:

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
    int i = 0;
}
<form method="post">
    @foreach (var item in Model.Items)
    {

        <input asp-for="Items[i]" />
        i++;
    }

    @for (int j = 0; j < Model.Items.Count; j++)
    {

        <input asp-for="Items[j]" />
    }
    <button type="submit">Submit</button>
</form>

And the code behind:

public class IndexModel : PageModel
{
    [BindProperty]
    public List<string> Items { get; set; }

    public void OnGet()
    {
        Items = new List<string> { "one", "two", "three" };
    }

    public void OnPost(List<string> items)
    {

    }
}

Here is a bit of how it works:

In this controller you have 2 action, one returns a list of strings which will be out model. And the second action will accept a parameter as a list of strings.

[Route("[controller]")]
public class TestController : Controller
{

    [HttpGet("[action]")]
    public IActionResult Test()
    {
        return View(new List<string> { "one", "two", "three" });
    }

    [HttpPost("[action]")]
    public IActionResult Test(List<string> Words)
    {
        return Ok();
    }
}

Now in our Test view Test.cshtml file, we want to display this list of string with their index and when we change these values we want to be able to post them.

@model List<string>

@{
    int i = 0;
}

<form method="post">

    @foreach (var item in Model)
    {
        <label>@item  - @i</label>
        <input name="Words[@i]" value="@item" />

        i++;
    }
    <button type="submit">Submit</button>
</form>

Here is the result:

Result

And after submitting the form, the values in the input fields will appear in the list of strings, because of the html name attribute.

You have to understand that the tag helper asp-for is used by Razor to generate all sorts of html attributes on the field such as name/id/data-* etc... the main thing you need is the name attribute to bind the value.

Broomrape answered 17/8, 2018 at 14:5 Comment(3)
This is the same idea that @ChritPratt was proposing. I was looking for something along the line of: @for(int i = 1; i <= 31; i++) { <label asp-for="Value"+i /> <input type="number" asp-for"Value"+i /> } This way I don't have to write 62 lines for my 31 propertiesMadi
I missed List<> and changed it to '@model List<Model>'. Eventually, it worked well.Persuasion
@Persuasion how did you put asp-for ?Gunning

© 2022 - 2024 — McMap. All rights reserved.