Search code examples
c#entity-frameworkasp.net-core-mvc.net-6.0

Submit button not inputting values properly


I have a form in cshtml that is inputting into a model but it keeps skipping some value that has been added inside the for code block, specifically the GroupPerDay values

<form method="post" asp-action="Create" class="row g-3">
    <div class="row g-3 align-items-center">
        <div class="row-cols-auto">
            <input type="text" hidden class="form-control-plaintext" value="@Model.Department.DepartmentId" asp-for="Department.DepartmentId" />
        </div>
    </div>
    <div class="row g-3 align-items-center">
        <div class="col-auto">
            <label for="SubDate" class="col-form-label">NGÀY ĐĂNG KÝ: </label>
        </div>
        <div class="col-auto">
            <input type="date" id="SubDate" asp-for="DayGroup.SubcriptionDate" class="form-control" />
            <span asp-validation-for="DayGroup.SubcriptionDate" class="text-dark"></span>
        </div>
    </div>
    <div class="mb-3 row">
        <div class="col-sm-3">
            <input type="text" readonly class="form-control-plaintext" value="DS HỌ TÊN" />
        </div>
        <div class="col">
            <input type="text" readonly class="form-control-plaintext text-center" value="CA 1" />
        </div>
        <div class="col">
            <input type="text" readonly class="form-control-plaintext text-center" value="CA 2" />
        </div>
        <div class="col">
            <input type="text" readonly class="form-control-plaintext text-center" value="CA 3" />
        </div>
    </div>
    @for (int i = 0; i < Model.Department.Persons.Count; i++)
    {
        int j = Model.Department.Persons[i].GroupPerDay.Count - 1;
        <div class="col-auto">
            <input type="text" hidden readonly asp-for="Department.Persons[i].PersonId" value="@Model.Department.Persons[i].PersonId" />
            <input type="text" hidden readonly asp-for="Department.Persons[i].Name" value="@Model.Department.Persons[i].Name" />
            <input type="text" hidden readonly asp-for="Department.Persons[i].GroupPerDay[j].Id" value="@Model.Department.Persons[i].GroupPerDay[j].Id" />
        </div>
        <div class="row">
            <div class="col">
                <input type="text" readonly class="form-control-plaintext" asp-for="Department.Persons[i].GroupPerDay[j].Person.Name" value="@Model.Department.Persons[i].GroupPerDay[j].Person.Name" />
            </div>
            <div class="col">
                <input type="number" class="form-control" asp-for="Department.Persons[i].GroupPerDay[j].Set1" />
            </div>
            <div class="col">
                <input type="number" class="form-control" asp-for="Department.Persons[i].GroupPerDay[j].Set2" />
            </div>
            <div class="col">
                <input type="number" class="form-control" asp-for="Department.Persons[i].GroupPerDay[j].Set3" />
            </div>
        </div>          
    }
    <div class="row g-3 align-items-center">
        <div class="col-auto">
            <button class="btn btn-primary" type="submit">Submit</button>
        </div>
        <div class="col-auto">
            <a class="btn btn-danger" asp-controller="Home" asp-action="Index">Cancel</a>
        </div>
    </div>
</form>

The models

public class CreateGroupViewModel
{
    public string AppUserId { get; set; }
    public AppUser AppUser { get; set; }
    public Department Department { get; set; }
    public DayGroup DayGroup { get; set; }
}

public class DayGroup
{
    public string Id { get; set; }
    public DateTime SubcriptionDate { get; set; }
    public Group Group { get; set; }
    public List<PersonInGroupPerDay> PersonInGroups { get; set; }
}

public class PersonInGroupPerDay
{
    public string Id { get; set; }
    public DayGroup DayGroup { get; set; }
    public Person Person { get; set; }
    [DefaultValue(0)]
    public int Set1 { get; set; }
    [DefaultValue(0)]
    public int Set2 { get; set; }
    [DefaultValue(0)]
    public int Set3 { get; set; }
}

Input for form enter image description here

The Post action model after input enter image description here

I want it to add the value I input into the List

I tried <input class="btn btn-primary" type="Submit" /> and even javascript with Onclick to a function but it doesn't work

If you need more info, I can add what is needed to a comment.


Solution

  • You are just adding inputs fields for the last Persons[i].GroupPerDay item.

    int j = Model.Department.Persons[i].GroupPerDay.Count - 1;

    We also need to add hidden inputs for the remaining Persons[i].GroupPerDay items.

    Try this code:

    <form method="post" asp-action="Create" class="row g-3">
    <div class="row g-3 align-items-center">
        <div class="row-cols-auto">
            <input type="text" hidden class="form-control-plaintext" value="@Model.Department.DepartmentId" asp-for="Department.DepartmentId" />
        </div>
    </div>
    <div class="row g-3 align-items-center">
        <div class="col-auto">
            <label for="SubDate" class="col-form-label">NGÀY ĐĂNG KÝ: </label>
        </div>
        <div class="col-auto">
            <input type="date" id="SubDate" asp-for="DayGroup.SubcriptionDate" class="form-control" />
            <span asp-validation-for="DayGroup.SubcriptionDate" class="text-dark"></span>
        </div>
    </div>
    <div class="mb-3 row">
        <div class="col-sm-3">
            <input type="text" readonly class="form-control-plaintext" value="DS HỌ TÊN" />
        </div>
        <div class="col">
            <input type="text" readonly class="form-control-plaintext text-center" value="CA 1" />
        </div>
        <div class="col">
            <input type="text" readonly class="form-control-plaintext text-center" value="CA 2" />
        </div>
        <div class="col">
            <input type="text" readonly class="form-control-plaintext text-center" value="CA 3" />
        </div>
    </div>
    @{
        int i = 0;
        foreach (Person person in Model.Department.Persons)
        {
            int j = 0;
            foreach (var group in person.GroupPerDay)
            {
                <div class="col-auto">
                    <input type="text" hidden readonly asp-for="Department.Persons[i].PersonId" value="@Model.Department.Persons[i].PersonId" />
                    <input type="text" hidden readonly asp-for="Department.Persons[i].Name" value="@Model.Department.Persons[i].Name" />
                    <input type="text" hidden readonly asp-for="Department.Persons[i].GroupPerDay[j].Id" value="@Model.Department.Persons[i].GroupPerDay[j].Id" />
                </div>
                if (j == person.GroupPerDay.Count - 1)
                {
                    <div class="row">
                        <div class="col">
                            <input type="text" readonly class="form-control-plaintext" asp-for="Department.Persons[i].GroupPerDay[j].Person.Name" value="@Model.Department.Persons[i].GroupPerDay[j].Person.Name" />
                        </div>
                        <div class="col">
                            <input type="number" class="form-control" asp-for="Department.Persons[i].GroupPerDay[j].Set1" />
                        </div>
                        <div class="col">
                            <input type="number" class="form-control" asp-for="Department.Persons[i].GroupPerDay[j].Set2" />
                        </div>
                        <div class="col">
                            <input type="number" class="form-control" asp-for="Department.Persons[i].GroupPerDay[j].Set3" />
                        </div>
                    </div>
                }
                else
                {
                    <div class="col-auto">
                        <input type="hidden" asp-for="Department.Persons[i].GroupPerDay[j].Set1" />
                        <input type="hidden" asp-for="Department.Persons[i].GroupPerDay[j].Set2" />
                        <input type="hidden" asp-for="Department.Persons[i].GroupPerDay[j].Set3" />
                        <input type="hidden" asp-for="Department.Persons[i].GroupPerDay[j].Person.Name" />
                    </div>
                }
                j++;
            }
            i++;
        }
    }
    <div class="row g-3 align-items-center">
        <div class="col-auto">
            <button class="btn btn-primary" type="submit">Submit</button>
        </div>
        <div class="col-auto">
            <a class="btn btn-danger" asp-controller="Home" asp-action="Index">Cancel</a>
        </div>
    </div>
    

    If you only want the last Persons[i].GroupPerDay item to fetch in your post action, then you should try this.

    <form method="post" asp-action="Create" class="row g-3">
    <div class="row g-3 align-items-center">
        <div class="row-cols-auto">
            <input type="text" hidden class="form-control-plaintext" value="@Model.Department.DepartmentId" asp-for="Department.DepartmentId" />
        </div>
    </div>
    <div class="row g-3 align-items-center">
        <div class="col-auto">
            <label for="SubDate" class="col-form-label">NGÀY ĐĂNG KÝ: </label>
        </div>
        <div class="col-auto">
            <input type="date" id="SubDate" asp-for="DayGroup.SubcriptionDate" class="form-control" />
            <span asp-validation-for="DayGroup.SubcriptionDate" class="text-dark"></span>
        </div>
    </div>
    <div class="mb-3 row">
        <div class="col-sm-3">
            <input type="text" readonly class="form-control-plaintext" value="DS HỌ TÊN" />
        </div>
        <div class="col">
            <input type="text" readonly class="form-control-plaintext text-center" value="CA 1" />
        </div>
        <div class="col">
            <input type="text" readonly class="form-control-plaintext text-center" value="CA 2" />
        </div>
        <div class="col">
            <input type="text" readonly class="form-control-plaintext text-center" value="CA 3" />
        </div>
    </div>
    @for (int i = 0; i < Model.Department.Persons.Count; i++)
    {
        int j = Model.Department.Persons[i].GroupPerDay.Count - 1;
        int firstIndex = 0;
        <div class="col-auto">
            <input type="text" hidden readonly asp-for="Department.Persons[i].PersonId" value="@Model.Department.Persons[i].PersonId" />
            <input type="text" hidden readonly asp-for="Department.Persons[i].Name" value="@Model.Department.Persons[i].Name" />
            <input type="text" hidden readonly asp-for="Department.Persons[i].GroupPerDay[firstIndex].Id" value="@Model.Department.Persons[i].GroupPerDay[j].Id" />
        </div>
        <div class="row">
            <div class="col">
                <input type="text" readonly class="form-control-plaintext" asp-for="Department.Persons[i].GroupPerDay[firstIndex].Person.Name" value="@Model.Department.Persons[i].GroupPerDay[j].Person.Name" />
            </div>
            <div class="col">
                <input type="number" class="form-control" asp-for="Department.Persons[i].GroupPerDay[firstIndex].Set1" value="@Model.Department.Persons[i].GroupPerDay[j].Set1" />
            </div>
            <div class="col">
                <input type="number" class="form-control" asp-for="Department.Persons[i].GroupPerDay[firstIndex].Set2" value="@Model.Department.Persons[i].GroupPerDay[j].Set2" />
            </div>
            <div class="col">
                <input type="number" class="form-control" asp-for="Department.Persons[i].GroupPerDay[firstIndex].Set3" value="@Model.Department.Persons[i].GroupPerDay[j].Set3" />
            </div>
        </div>
    }
    <div class="row g-3 align-items-center">
        <div class="col-auto">
            <button class="btn btn-primary" type="submit">Submit</button>
        </div>
        <div class="col-auto">
            <a class="btn btn-danger" asp-controller="Home" asp-action="Index">Cancel</a>
        </div>
    </div>