.NET Core 6: Use jQuery to update a dynamic list generated from view model

Viewed 29

So I have a razor view that uses a model as follows:

public class UserDTO
{
   public string UserName
   public int UserId
   public List<UserHobbiesPOCO> UserHobbies
}
public class UserHobbiesPOCO
{
   public int HobbyID
   public string HobbyDescription
   public int HobbyCategoryId
   public bool IsChecked
}

In the razor form, I have the following code used to generate a list of checkboxes to allow a user to select their hobbies:

<div id="hobbies">
   @for (int i = 0; i < this.Model.UserHobbies.Count(); i++)
   {
      <div class="hobby-item col-md-6">
         <input type="checkbox" asp-for="@Model.UserHobbies[i].IsChecked" />
         <label class="attrChk" asp-for="@Model.UserHobbies[i].IsChecked">@Model.UserHobbies[i].HobbyDescription</label>
         <input type="hidden" asp-for="@Model.UserHobbies[i].HobbyID" />
         <input type="hidden" asp-for="@Model.UserHobbies[i].HobbyDescription" />
         <input type="hidden" asp-for="@Model.UserHobbies[i].HobbyCategoryId" />
      </div>
   }
</div>

Currently, this works as I designed it originally. When the form submits, it has a list of all the hobbies in the database and whether or not the hobbies have been checked. The hobby category is a semi-hidden field used for data analysis. The idea behind using a model to reflect the checkboxes was to ensure data integrity.

However, adding a new hobby requires a page refresh that resets all your data. So I thought I would create an ajax call that would append a hobby to the list and allow users to add hobbies without having to leave the form.

I have tried appending HTML using jQuery that mimics the HTML generated by the Razor code, but appending a checkbox item to the list that way does not update the model that goes to the controller on form submission. The new hobby generated by ajax just isn't there when I look at the model in the controller using debug mode.

It appears my efforts to ensure data integrity have come back to bite me. Is there a way to update the Razor model via ajax so that is will be present on form submission? Is there something I am missing?

1 Answers

Updating the HTML with Javascript is possible. But it is tricky with lists or array. Look into the generated HTML inputs for your for-loop. It should look roughly like this

<div class="hobby-item col-md-6">
   ...
   <input type="hidden" name="UserHobbies[0].HobbyID" id="UserHobbies_0__HobbyID" />
   <input type="hidden" name="UserHobbies[0].HobbyDescription" id="UserHobbies_0__HobbyDescription" />
   <input type="hidden" name="UserHobbies[0].HobbyCategoryId" id="UserHobbies_0__HobbyCategoryId" />
</div>
<div class="hobby-item col-md-6">
   ...
   <input type="hidden" name="UserHobbies[1].HobbyID" id="UserHobbies_1__HobbyID" />
   <input type="hidden" name="UserHobbies[1].HobbyDescription" id="UserHobbies_1__HobbyDescription" />
   <input type="hidden" name="UserHobbies[1].HobbyCategoryId" id="UserHobbies_1__HobbyCategoryId" />
</div>
<div class="hobby-item col-md-6">
   ...
   <input type="hidden" name="UserHobbies[2].HobbyID" id="UserHobbies_2__HobbyID" />
   <input type="hidden" name="UserHobbies[2].HobbyDescription" id="UserHobbies_2__HobbyDescription" />
   <input type="hidden" name="UserHobbies[2].HobbyCategoryId" id="UserHobbies_2__HobbyCategoryId" />
</div>
...

Do you see the names of the input and the index? Be sure to insert them with your js-code. If the names and the index is right, the model should be posted as usual.

Related