-1

My model:

public class AdminPageModel
{
    public int? JobID { get; set; }

    [DisplayName("Description")]
    public string Description { get; set; }

    [DisplayName("Weight")]
    public decimal Weight { get; set; }

    public int ID { get; set; }        
}

Form 1:

using (Html.BeginForm("EditTemplate", "Config", FormMethod.Post, new { @class = "form-horizontal" }))
{
    for (var i = 0; i < Model.Count; i++)
    {
        <div class="form-group">
        @if (Model[i].JobID != null)
        {
            @Html.LabelFor(m => m[i].Description)
            @Html.TextBoxFor(m => m[i].Description)

            @Html.LabelFor(m => m[i].Weight)
            @Html.TextBoxFor(m => m[i].Weight)

            @Html.HiddenFor(m => m[i].ID)
            @Html.HiddenFor(m => m[i].JobID)
            <br />@Html.ActionLink("Delete", "DeleteTemplate", new { id = @Model[i].ID, jobID = selectedJobID })
        }

        </div>
    }
    <input type="submit" value="Update" class="btn btn-success" id="editSubmit" />
}

Form 2:

using (Html.BeginForm("EditCompetency", "Config", FormMethod.Post, new { @class = "form-horizontal" }))
{
    for (var i = 0; i < Model.Count; i++)
    {
        <div class="form-group">
            @if (Model[i].JobID == null)
            {
                @Html.LabelFor(m => m[i].Description)
                @Html.TextBoxFor(m => m[i].Description)

                @Html.LabelFor(m => m[i].Weight)
                @Html.TextBoxFor(m => m[i].Weight)

                @Html.HiddenFor(m => m[i].ID)
                @Html.HiddenFor(m => m[i].JobID)
                <br />@Html.ActionLink("Delete", "DeleteCompentency", new { id = @Model[i].ID})
            }

        </div>
    }
    <input type="submit" value="Update" class="btn btn-success" id="editSubmit" />

}

Controllers:

[HttpPost]
public ActionResult EditCompetency(List<AdminPageModel> modelList)
{
    // stuff
}

[HttpPost]
public ActionResult EditTemplate(List<AdminPageModel> modelList)
{
    // stuff
}

Here's the issue. I have templates and competencies. I can add/delete all day long. Running into an issue when attempting to edit.

No issue at all with the templates, only with the competencies. If I add a competency and no template exists, the edit works just fine. But if a template exists when I try to edit a competency, the List<AdminPageModel> modelList (the type that my view is strongly typed to) comes in as null. If I delete the template, I can edit the competency to my hearts content. I've spent a chunk of this morning spinning my gears on this.

Craig W.
  • 17,838
  • 6
  • 49
  • 82
Tony D.
  • 551
  • 1
  • 10
  • 26
  • Are both of these forms on the same page? If they are then you will have controls with the same names and IDs, which can cause problems in several different ways. – sam2929 Oct 19 '16 at 18:44
  • They are indeed on the same page. – Tony D. Oct 19 '16 at 18:47
  • 1
    Can you try putting them on separate pages? Or alternatively make your viewmodel for the page include two lists: one for Templates and one for Compentencies. Then bind those two lists to the appropriate forms. Right now you are essentially binding the same data to two forms. If that doesn't make sense to you I can write out some code in an answer. – sam2929 Oct 19 '16 at 18:49
  • an example would be helpful if you wouldn't mind. – Tony D. Oct 19 '16 at 18:57
  • I just added an example for you. Let me know if that is helpful. – sam2929 Oct 19 '16 at 19:12
  • working it right now. thanks. i'll be back to you. – Tony D. Oct 19 '16 at 19:24
  • By default, collection indexers must start at zero and be consecutive. Your `@if (Model[i].JobID == null)` line of code in each form which means that they wont be. You can make this bind by adding a hidden input for the collection indexer - `` (refer [this answer](http://stackoverflow.com/questions/24026374/adding-another-pet-to-a-model-form/24027152#24027152) for more detail). But the correct approach is to use a view model containing 2 collection properties. –  Oct 19 '16 at 22:18
  • @sam2929 I gave your example a shot and it didn't work out for me all that well. I went to my fall back of tying into `FormCollection` on the post. A little hacky but it was the only way I could get what I needed. Thanks. – Tony D. Oct 19 '16 at 22:26

1 Answers1

0

Here is an example of how to combine your Competency data and Template data into a single viewmodel so that you don't have overlapping control names.

ConfigController.cs

[HttpGet]
public ActionResult Index()
{
    AdminViewModel viewModel = // Get Data Somehow
    return View(viewModel);
}

[HttpPost]
public ActionResult EditCompetency(AdminViewModel viewModel)
{
    // access competency data with viewModel.Competencies
}

[HttpPost]
public ActionResult EditTemplate(AdminViewModel viewModel)
{
    // access template data with viewModel.Templates
}

AdminViewModel.cs (new class)

public class AdminViewModel
{
    public List<AdminPageModel> Templates { get; set; }
    public List<AdminPageModel> Competencies { get; set; }
}

AdminPage.cshtml

@model AdminViewModel

using (Html.BeginForm("EditTemplate", "Config", FormMethod.Post, new { @class = "form-horizontal" }))
{
    for (var i = 0; i < Model.Templates.Count; i++)
    {
        <div class="form-group">
        @if (Model.Templates[i].JobID != null)
        {
            @Html.LabelFor(m => m.Templates[i].Description)
            @Html.TextBoxFor(m => m.Templates[i].Description)

            @Html.LabelFor(m => m.Templates[i].Weight)
            @Html.TextBoxFor(m => m.Templates[i].Weight)

            @Html.HiddenFor(m => m.Templates[i].ID)
            @Html.HiddenFor(m => m.Templates[i].JobID)
            <br />@Html.ActionLink("Delete", "DeleteTemplate", new { id = @Model.Templates[i].ID, jobID = selectedJobID })
        }

        </div>
    }
    <input type="submit" value="Update" class="btn btn-success" id="editSubmit" />
}

using (Html.BeginForm("EditCompetency", "Config", FormMethod.Post, new { @class = "form-horizontal" }))
{
    for (var i = 0; i < Model.Competencies.Count; i++)
    {
        <div class="form-group">
            @if (Model.Competencies[i].JobID == null)
            {
                @Html.LabelFor(m => m.Competencies[i].Description)
                @Html.TextBoxFor(m => m.Competencies[i].Description)

                @Html.LabelFor(m => m.Competencies[i].Weight)
                @Html.TextBoxFor(m => m.Competencies[i].Weight)

                @Html.HiddenFor(m => m.Competencies[i].ID)
                @Html.HiddenFor(m => m.Competencies[i].JobID)
                <br />@Html.ActionLink("Delete", "DeleteCompentency", new { id = @Model.Competencies[i].ID})
            }

        </div>
    }
    <input type="submit" value="Update" class="btn btn-success" id="editSubmit" />

}
sam2929
  • 479
  • 7
  • 14