C
C#11mo ago
Gax

Generating input fields for each element in an array in Blazor WASM

I'm trying to generate an input field for each element in an array, and have the input field bind that element to the array, however, no matter how i do it, it either throws an exception or doesn't bind at all. This is basically what I have right now
<div style="display: grid; grid-template-columns: repeat(3, 50px); gap: 10px;">
@for (int i = 0; i < a.Length; i++)
{
<input type="text" style="width: 50px" placeholder="@i" @bind-value="a[i]" @key="i"/>
}
</div>

@code {
private string[] a = new string[9];
}
<div style="display: grid; grid-template-columns: repeat(3, 50px); gap: 10px;">
@for (int i = 0; i < a.Length; i++)
{
<input type="text" style="width: 50px" placeholder="@i" @bind-value="a[i]" @key="i"/>
}
</div>

@code {
private string[] a = new string[9];
}
Currently, it generates the input fields, but when attempting to change values, it throws an IndexOutOfRangeException
4 Replies
Joschi
Joschi11mo ago
I don't think you can bind to the index/array of a collection at all. What you would need to do is directly use @onchange. And to that you provide a lambda expression that modifies your original array.
mindhardt
mindhardt11mo ago
I've done this with
foreach(var row in items.Select((item, i) => (item, i))
{
@row.i @row.item
}
foreach(var row in items.Select((item, i) => (item, i))
{
@row.i @row.item
}
And it works
Joschi
Joschi11mo ago
Ok but you are missing the input field and binding to a local.
c#
@for (var i = 0; i < _chars.Length; i++)
{
var localCapture = i;
<input type="text" value="@_chars[i]" maxlength="1" @onchange="@((args) => _chars[localCapture] = ((string)args.Value)[0])"/>
}

@string.Join("|", _chars)

@code
{
private char[] _chars = ['A', 'A','A','A','A'];
}
c#
@for (var i = 0; i < _chars.Length; i++)
{
var localCapture = i;
<input type="text" value="@_chars[i]" maxlength="1" @onchange="@((args) => _chars[localCapture] = ((string)args.Value)[0])"/>
}

@string.Join("|", _chars)

@code
{
private char[] _chars = ['A', 'A','A','A','A'];
}
This would be a solution. That lambda casting needs some cleaning up if you wanna use it in any real capacity thought.
Gax
GaxOP11mo ago
I've solved it by just making a class purely to serve as a "reference type array" and using it instead of just the default array, not the best solution but for my use case is good enough I guess. All it has is a private array field to store the values and an indexer which is all I need I also made an input field component that has parameters to store the reference to that object and an index representing which value to change
Want results from more Discord servers?
Add your server