1

I can not figure out how can I pass data from view back to controller. I have a list of ChildViewModels that are shown on screen. User can add data to this list and after everything is done, press 'Submit' and send these items back to controller.

Here are my view models:

public class ParentViewModel
{
    public int Id { get; set; }
    public IList<ChildViewModel> Children { get; set; }
}

public class ChildViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Here is how I display them in main view:

<div id="editorRows">
    @foreach (var item in Model.Children)
    {
    <partial name="_myPartial" model="item" />
    }
</div>
<a id="addItem" asp-action="BlankSentence" asp-controller="Home">Add Row...</a> <br />
<input type="submit" id="submit" value="Finished" onclick="SaveUser()" />

Here is partial view definition:

<div class="editorRow">
@using (Html.BeginCollectionItem("Children"))
{
    @Html.HiddenFor(m => m.Id)
    <span>Name: </span> @Html.EditorFor(m => m.Name);
}
<a href="#" class="deleteRow">delete</a>

Then I have such script which adds new row:

$("#addItem").click(function () {
    $.ajax({
        url:'@Url.Action("BlankSentence", "Home")',
        cache: false,
        success: function (html) {
            $("#editorRows").append(html);            
        }
    });
    return false;
});

User can add rows, all this works fine. Then I would like to have a button that sends info back to controller. I would create object that holds necessary data, including information that is 'inside' added objects (partialViews?) and send it back with help of ajax. This would be done with function like this:

 function SaveUser() {

    var products = [];
    $("#editorRows").each(function(index, value) {
        pr.push(value);
    });

    var model = 
    {
        Name: "SomeDataFromTextBox",
        Products : pr,         
    };


    $.ajax({
    type: "POST",
    data: JSON.stringify(model),
    url: "/Home/Save",
    contentType: "application/json"
    }).done(function(res) {       
    console.log('res', res);
    });
    }

Here is receiver:

public JsonResult Save([FromBody] SomeViewModel model)
{
   return Json(model);
}

My question is this - how do I populate this collection to be sent back to controller?

var products = [];
$("#editorRows").each(function(index, value) {
    pr.push(value);
});

I have tried many things, it either sends null or does not even call the Save method. Sorry for the lengthy post, I am totally new to ASP.NET Core and did not know which parts of code could be omitted without losing general idea.

Also, if my approach is flawed in some other way, I would like to hear your comments.

1 Answer 1

1

jQuery .each() function gives you the index as first parameter and the whole html Element as second parameter. You need to use this element to select the inner input element and get its value. Also $("#editorRows") gives you the wrapper div element, you can use $(".editorRow") to get the collection of <div class="editorRow"> elements.

var products = [];

$(".editorRow").each(function(index, element) {
    // select the element that was created with @Html.EditorFor(m => m.Name)
    let inputEl = element.querySelector("input[name='Name']");
    // get the input element value
    products.push(inputEl.value);
});

jQuery .each() documentation

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

4 Comments

Hi, thank you for the answer, but still nothing gets added to products array.
Do you mean the JavaScript array or an array in your viewmodel?
Yes, but I finally managed to populate array using such code: products.push({ Name: inputEl.value }); Having said that I now run into new problem - it loops through too many times. If editorRows contains 2 items, products array gets 3 items, first one is doubled.
I solved my problem, it was a stupid mistake on my side. Thank you for your help!

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.