Reputation: 220
I am building a (static) website in Blazor.wasm where the users upload some number of files. My intention is then (after all the files have passed some basic checks) to iteratively present a set of fields which the users are asked to complete. Only after they have submitted all the [Required]
information and press submit will the next form show up.
I have included a minimal example below.
if (valid_files == numFiles)
{
for (int counter = 0; counter < num_files; counter++)
{
paramList.Add(new ParamsForm { });
<EditForm Model="@paramList[counter]" OnValidSubmit="@SingleSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>
Camera type <br>
<InputText id="cameratype" @bind-Value="@paramList[counter].CameraType" />
</p>
<button type="submit">Submit</button>
</EditForm>
}
<button @onclick="HandleValidSubmit">Upload Data </button>
}
The expected behaviour is that on each iteration, a frech instance of the onbject ParamsForm
is added to the list. We then create a form based of that instance and wait for the user to complete the form. Once they press the Submit
button the next stage of the for
loop begins. Once all the data have been submitted and the for
loop is completed, the Upload data
button should appear and the users are invited to submit all their data to the server.
Instead, none of the code inside the EditForm ...
section is being completed. I.e. - I see no popping up of text boxes, and any code that I put in there (for example @Console.WriteLine("This should show up)
does not seem to be executed. The Upload data
button does not appear and instead an error is thrown complaining that the index is out of range
, which is weird because after the code at the top of the for loop there are no longer any elements being accessed by an index.
I am quite new to interacting between c# and HTML, so I think I can appreciate why what I have shouldn't work, but I don't know how I can go about writing something that will work.
Any advice would be gratefully recieved.
Upvotes: 0
Views: 1406
Reputation: 4208
I don't have much information about your class, where you are getting your file list from, and so on. I recommend passing complete objects rather than individual properties. For example, I'd rather have IBrowserFile File {get; set;}
in my ParamsForm
class than say string FileName
. That way, if I decide-- oh, I want to get this or that property-- it's already there.
Anyway, hope something in here might be useful:
@if (CurrentForm is not null)
{
<EditForm Model="CurrentForm" OnValidSubmit="@SingleSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<p>
Camera type <br>
<InputText id="cameratype" @bind-Value="CurrentForm.CameraType" />
</p>
<button type="submit">Submit</button>
</EditForm>
@if (IsComplete) // Don't show upload button until you're done
{
<button @onclick="DoUploads">Upload Data </button>
}
@DisplayMessage
}
@code {
class ParamsForm { public string FileName; public string CameraType; } // Just a placeholder
List<ParamsForm> ParamsList = new List<ParamsForm>();
ParamsForm CurrentForm { get; set; }
int counter = 0;
List<string> FileNames;
bool IsComplete = false;
string DisplayMessage = "";
void InitializeForms()
{
// I don't know your class, so just an example
foreach (var item in FileNames)
{
bool IsValid = false;
// check file validity
if (IsValid) ParamsList.Add(new ParamsForm() { FileName = item });
}
if(ParamsList.Count > 0)
CurrentForm = ParamsList[0];
}
void SingleSubmit()
{
// Do stuff with CurrentForm
if (++counter >= ParamsList.Count) IsComplete = true;
else CurrentForm = ParamsList[counter];
}
async Task DoUploads()
{
// Do stuff with your ParamsList
int UploadCounter = 0;
foreach (ParamsForm item in ParamsList){
DisplayMessage = "Uploading " + UploadCounter + " of " + ParamsList.Count;
StateHasChanged();
// Do the Upload;
}
DisplayMessage = "Finished.";
}
}
Upvotes: 1
Reputation: 4208
The ways of Blazor are a bit mysterious to me, too-- it takes a while to adjust! I do know that Blazor has an OnAfterRender event, which makes me think that it might not like to have user input in a loop like that. Or it may be that it's enumerating if (valid_files == numFiles)
as false because those variables aren't initialized yet when the markup first renders.
I'd try two things:
(1) Throw StateHasChanged()
at the end of your loop or after the code that sets valid_files
and numFiles
and see if that does anything you like.
(2) Probably this anyway: instead of looping in the markup, I'd build the entire List<ParamsForm> paramsList
in the FileInput
's event handler instead, move the counter to the code block, and add counter++
to the end of the SingleSubmit()
method.
It's 5:00 am here, just got up to get a snack and going back to bed. Let me know if things still don't fly, and I'll try a more complete example tomorrow. :D
Upvotes: 3