6

I have a @foreach loop in my Blazor page which iterates through a list of type UserInput (var userInput in UserInput).

If userInput.IsInput is false, then I will display a

with contents userInput.Text.

If userInput.IsInput is true, I will display an field and store its contents in userInputBind[index].

Below is the code I have tried:

@foreach (var userInput in myList)
{
    if (userInput.IsInput)
    {
        <input @bind="userInputBind[index]"/>
        if (index < 6) index++;
    }
    else
    {
        <p>@item.Text</p>
    }
}

@code {
    public List<UserInput> myList = new List<UserInput>
    {
        new UserInput { IsInput = false, Text = "One" },
        new UserInput { IsInput = false, Text = "Two" },
        new UserInput { IsInput = true, Text = "" },
        new UserInput { IsInput = false, Text = "Four" },
        new UserInput { IsInput = true, Text = "" },
        new UserInput { IsInput = false, Text = "Six" }
    };
    public List<string> userInputBind = new List<string> { "", "" };
    public int index;

    public class UserInput
    {
        public bool IsInput { get; set; }
        public string Text { get; set; }
    }
}

When I input "string1" into the first input field and "string2" into the second field, I expect the list to contain { "string1", "string2" }. Instead, both of the strings are "string2". How can I fix this issue? Any help is appreciated!

3
  • 1
    I suspect the global index field is the problem, and all bindings resolve to userInputBind[6]. Could you try with a for instead of foreach, and with a local variable instead of instance? Commented Apr 9, 2022 at 11:45
  • 1
    I recommend looking at @enet 's answer. It's one thing to figure how to do this, but the other issue is SHOULD you do it? I use this technique constantly in Blazor-- making a class with some data and a bool for Selected status. Commented Apr 9, 2022 at 22:16
  • Note: question edited to better fit my issue. Commented Apr 11, 2022 at 13:41

1 Answer 1

6

Revised Answer

I think what you're trying to do is this:

@page "/"

@{index = 0;}
@foreach (var userInput in myList)
{
    int loopindex = index;

    if (userInput.IsInput)
    {
        <input @bind="myList[loopindex].Text"/>
    }
    else
    {
        <p>@userInput.Text</p>
    }
    index++;
}

@foreach (var userInput in myList)
{
    <div class="m-2 p-2">
        Value: @userInput.Text
    </div>
}

@code {
    public List<UserInput> myList = new List<UserInput>
    {
        new UserInput { IsInput = false, Text = "One" },
        new UserInput { IsInput = false, Text = "Two" },
        new UserInput { IsInput = true, Text = "" },
        new UserInput { IsInput = false, Text = "Four" },
        new UserInput { IsInput = true, Text = "" },
        new UserInput { IsInput = false, Text = "Six" }
    };
    public int index;

    public class UserInput
    {
        public bool IsInput { get; set; }
        public string Text { get; set; }
    }
}

I don't get the purpose of:

public List<string> userInputBind = new List<string> { "", "" };

Original Answer

This works. It uses a local loop variable to capture the "index" for each loop iteration, and resets index for each render.

It may not be the solution to your problem, but it answers the question posed.

@page "/"

@{index = 0;}
@foreach (bool item in myList)
{
    if (item)
    {
        int loopindex = index;
        <div>
        <input @bind="userInputBind[loopindex]"/>
        </div>
        index++;
    }
}

@foreach(var value in userInputBind)
{
    <div class="p-2">
        Value = @value
    </div>
}

@code {
    public List<bool> myList = new List<bool> { false, false, true, false, true, false };
    public List<string> userInputBind = new List<string> { "One", "Two" };
    public int index;
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your reply. My issue with this code is that the Input and Text are not always separately shown (e.g. Input Input Input Text Text Text). They may be interlaced (e.g. Input Text Text Input Text Input). It seems like your code does not do that.
Hello, I have edited my question again, thanks!
See revised answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.