0

I'm creating an ASP.NET MVC 5 SQL Server (Entity Framework, database-first) application where there is an order record and a set of line item records attached to it. I am using viewmodels to display the data. The user can add new line item records to the viewmodel through an "Add" button, but the line items are not committed to the database until the user clicks the "Save" button. (I've previously written about the application regarding a different issue: ASP.NET MVC - passing modified viewmodel from AJAX to view)

I have the "Add" button working fine... except for one very important use case. If the user changes some data in the web page then presses the "Add" button, none of the changes to the web page data are sent when the @Html.Raw(Json.Encode(Model)) line is called:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script>
    $(document).ready(function () {
        $("#mybutton").click(function () {
            $.ajax({
                url: "../AddNewLineItem/",
                cache: false,
                type: "POST",
                data: {
                    'viewModel': @Html.Raw(Json.Encode(Model)),
                },
                success: function (data) {
                    $('#divPartial').append(data);
                },
                error: function (reponse) {
                    alert("Error: " + reponse);
                }
            });
        });
    });
</script>

Obviously, the reason why this is happening is because the model has not been updated with the latest data from the web page. However, how do I force the model to be updated before shipping it off via JSON? (Alternately, is there some way to always keep the viewmodel in sync with what the user has typed in the form?)

Dharman
  • 30,962
  • 25
  • 85
  • 135
dev5000
  • 99
  • 2
  • 10
  • `@Html.Raw(Json.Encode(Model))` is razor code which is parsed on the server before its sent to the client. The value of `viewmodel` is the value of the original model so your just sending back exactly what you initially sent to the client (a bit pointless). You need to post back the form values. –  Jul 30 '15 at 22:50

1 Answers1

1

the Model object is a server-side entity that doesn't exist on the client. instead, you need to send the client data. try using jQuery's serialize method. this will take all elements in the form and turn it into an object that can be sent via the AJAX method:

data: {
    'viewModel': $("form").serialize(),
    },
Dave Thieben
  • 5,388
  • 2
  • 28
  • 38
  • I'm not clear on how this works. When I pass this back to the controller as a FormCollection object and I iterate through that object, I see all of the items that are part of the model with the original values. I see no newly-entered values from the inputs on the form. Do I need to set up the serializable inputs on the form in some way or do I need to mark my form in some way? – dev5000 Jul 31 '15 at 15:05
  • (FWIW, I am using @Html.EditorFor for many of the textboxes. Not sure if there's some sort of indicator I need to set up so they will be recognized by the .serialize() call.) – dev5000 Jul 31 '15 at 15:32
  • Never mind, I got it. This answer pointed me in the right direction. My Html.BeginForm used to look like this: `@using (Html.BeginForm())` It needed to look like this -- specifically to have an id: `@using (Html.BeginForm("Edit", "Controller", FormMethod.Post, new { id = "myFormID" }))` Now I get back the model as well as the form data in the FormCollection. I needed to deserialize the form data, and modified the Deserialize() function on this page to get it back in a collection: http://stackoverflow.com/questions/9004546/jquery-post-form-in-asp-net-mvc-3-0-formcollection – dev5000 Jul 31 '15 at 16:22
  • (Continuation)...Obviously, the id is used when serializing the data (code excerpt as a modification from my original post in this thread): `data: { 'viewModel': @Html.Raw(Json.Encode(Model)), 'form2' : $("#myFormID").serialize(), }, ` – dev5000 Jul 31 '15 at 16:28
  • @dev5000, Your form does NOT need an `id` attribute. And the fact your using `FormCollection` instead of binding to your model, and posting back the original unchanged model using `@Html.Raw(Json.Encode(Model))`suggests you have far more problems than just this. –  Aug 03 '15 at 23:25
  • @StephenMuecke -- is it possible to bind the model without posting and making the screen refresh itself? (I do that when the user saves the changes to the form.) The goal is to add line item rows while keeping the screen in the same spot. While I have this working at the moment, any suggestions or tips that you could offer to point me in the right direction would be greatly appreciated. Like I said, I'm new to ASP.NET MVC, so it's entirely possible I'm going about this in the wrong way. – dev5000 Aug 04 '15 at 12:38
  • 1
    Yes of course you can. But without seeing more code its not possible to guide you. It not clear exactly what your wanting to do so you will need to ask a new question with some more details. My best guess if you want the sort of functionality in [this fiddle](http://jsfiddle.net/9madrh7g/2/), where you add or edit existing items (and save the form using ajax)? Or perhaps you want to dynamically add new items and post back everything in one go as per [this answer](http://stackoverflow.com/questions/29161481/post-a-form-array-without-successful/29161796#29161796)? –  Aug 04 '15 at 12:45