I want to bind values to elements from my list in a loop but I cannot find the good solution.
<EditForm Model="@dailyReport" OnValidSubmit="@SubmitDailyReport">
<p>
<label>Count: </label>
<InputNumber min="1" id="numberOfEffects" @bind-Value="numberOfEffects" />
</p>
@{
for (int i = 1; i <= numberOfEffects; i++)
{
if (effects.Count < i)
{
effects.Add("");
}
if (effects.Count > i)
{
effects.RemoveAt(effects.Count - 1);
}
string concatId = "effect" + i.ToString();
<p>
<label for="@concatId">@i</label>
<InputText id="@concatId" @bind-Value="effects.ElementAt(i-1)" />
</p>
}
}
//rest code
</EditForm>
When I am trying to bind-Value to element from a list I am getting an error:
I wonder if there is any possible way to bind data to collection. I need it because my Model has a property of type List. In my input form I want to allow adding as many strings as will be needed by the user.
@code
{
private DailyReport dailyReport = new DailyReport();
private List<string> effects = new List<string>();
}
I also tried to do it in foreach loop but another error is showed: Cannot assign to 'effect' because it is a 'foreach iteration variable
foreach (var effect in effects)
{
index++;
Console.WriteLine(index);
string concatId = "effect" + index.ToString();
<p>
<label for="@concatId">@index</label>
<InputText id="@concatId" @bind-Value="effect" />
</p>
}
The binding cannot work: when the value of an input text changes, you want to modify the list, not the element itself.
Instead, you have to "split" what the binding does in the two directions:
The code below shows how to solve the main problem, then you have to adapt it to your needs.
@foreach (var element in effects.Select((e, i) => new { Effect = e, Index = i}))
{
<p>
<label for="@($"effect{element.Index}")">@element.Index</label>
<input id="@($"effect{element.Index}")" value="@element.Effect"
@onchange="@(e => effects[element.Index] = e.Value.ToString())" />
</p>
}
@code {
private List<string> effects = new List<string>() { "a", "b", "c" };
}
The first line does the trick: it converts the list to an enumerable in which each element is a new object that encapsulates both the index in the effects
list and the value. You need the index mainly because of the @onchange
event, which must know where in the original list the value should be updated.
If you prefer you can use a for loop:
@for (int i = 0; i < effects.Count; i++)
{
// see https://stackoverflow.com/a/56426146/323447
var iCopy = i;
<p>
<label for="@($"effect{i}")">@i</label>
<input id="@($"effect{i}")" value="@effects[i]"
@onchange="@(e => effects[iCopy] = e.Value.ToString())" />
</p>
}
@code {
private List<string> effects = new List<string>() { "a", "b", "c" };
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With