3

I have a small project with an EditorTemplate. I show some items which are initially in a List<T> but I want to be able to add Items when the user presses a Button.

normally I add the items to the View like this

@for (int i = 0; i < Model.Models.Count; i++)
{
    @Html.EditorFor(model => model.Models[i], "_AddArticleFullQuantity");
}

When I want to add items dynamically I tried to create a button which uses ajax to call the server

<button id="addButton" type="button" class="btn btn-default btn-block" onclick="m_GUIRequests.AddArtikelToDiv()">add Article</button>

GUIRequests.prototype.AddArtikelToDiv = function ()
{
    this.Request.CallAjax("/NewItemDelivery/GetPartialView_AddArticleFullQuantity", "", GUIRequests.AddToView);
}

GUIRequests.AddToView = function (html) {
    $("#addedItems").append(html);
}

The button makes an ajax call to my controller which will do the following

public ActionResult GetPartialView_AddArticleFullQuantity()
{
    WrongItemsReceivedModel model = new WrongItemsReceivedModel();
    ModelContainer<WrongItemsReceivedModel> container = (ModelContainer<WrongItemsReceivedModel>)TempData["ModelContainer"];
    container.Add(model);

    return PartialView("~/views/Shared/EditorTemplates/_AddArticleFullQuantity.cshtml", container.Models[0]);
}

And in the end I get what I expected it will show me my template BUT the items initially shown from the List are numbered

So normally I have elements like:

<input class="form-control col-md-6 text-box single-line" data-val="true" data-val-required="MESSAGE" id="Models_0__ModelNumberID" name="Models[0].ModelNumberID" onchange="m_GUIRequests.SetWrongItemsReceivedValues()" type="text" value="">

But I get this:

<input class="form-control col-md-6 text-box single-line" data-val="true" data-val-required="MESSAGE" id="ModelNumberID" name="ModelNumberID" onchange="m_GUIRequests.SetWrongItemsReceivedValues()" type="text" value="">

I think its because I add one with the EditorFor "command" but the other one is added as PartialView. Is there any way how I can add an EditorFor element so that my logic won't break ?

2 Answers 2

3

For editing a variable length list in ASP.NET MVC I would recommending reading the following article. It presents a very clean approach to implement this. On the server you will not need any TempData for persistence and also it illustrates the usage of a nice little helper that will allow you to generate the proper input field names.

As far as your question is concerned, you are correct that the reason why you get wrong input names is because when you return the partial view directly from the controller action, it no longer has the parent context of the Editor Template. There are some ways to circumvent this but it's very hacky and I would rather recommend the approach presented in the article.

Sign up to request clarification or add additional context in comments.

7 Comments

The article is nice but without the sources I am not able to use the Html.BeginCollectionItem()
Try the Download the demo project link at the beginning. It should include everything you need.
yeah I thought of that ;) but I receive the all killing error 404
or if you prefer it as a NuGet: nuget.org/packages/BeginCollectionItem
Thanks :) I will give it a try and see what I can achieve
|
0

Normally i would go for steven sanderson's blog post as Darrin mention as it has become as one of the the industry's standard. Yes partial view is a pain in your scenario.

In your scenario where you would want to keep editor template logic and dynamic added elements linked i would go and generate same name as editor for requries as below

This is my code just to give you the example.

   $("#addItemdynamically").click(function () {
    $.ajax({
        url: '@Url.Action("GetNewGuid", "NewWebForms")',
        cache: false,
        success: function (newguid) {
            id = newguid;
            var html = '<tr class="editorRow">' +
              '<td><input type="radio" id="Selected" name="Selected" value=' + id + ' /></td>' +
              '<td><input type="hidden"  name=\OptionsList.Index value=' + id + ' /></td>' +
              '<td><input type="text"  name=\OptionsList[' + id + '].Text /></td>' +
              '<td><input type="hidden"  name=\OptionsList[' + id + '].guid value=' + id + ' /></td>' +
              '<td> <a href="#" class="deleteRow">delete</a></td>' +
              '</tr>'

              $("#editorRows tbody").append(html);
              $("form").removeData("validator");
              $("form").removeData("unobtrusiveValidation");
              $.validator.unobtrusive.parse("form");
        }
    });     
    return false;
});

Basically my new guid is getting newly generated guid from the server side and appending it to the row which is generated by pressing add new item button.

you can generate int digit if you like in here but that also require some other hack.

Comments

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.