0

I am not allowed to post the whole code, so please help with what you can from provided snippets....

I have a View with a modal dialog with few fields and submit button that has a Click event handler attached to it. That click handler looks like this:

Modal Submit/Click Handler

var gosti = [];
$("#modalDodajGosta").on("click","#btnDodajGosta",function(){
    var $modalForm = ($("#modalDodajGosta form"));
    if($modalForm.valid())
    {
        var gost = getFormData2Object($modalForm);
        if(gost != undefined)
        {
            gosti.push({
            Id : parseInt(gost.Id),
            ImePrezime : gost.ImePrezime,
            DrzavaId : parseInt(gost.DrzavaId),
            Email : gost.Email,
            Telefon : gost.Telefon
        });
    }

    $.ajax({
        url:"@Url.Action("GenerisiListuGostiju", "Gosti")",
        data:$.toJSON(gosti),
        contentType: "application/json; charset=utf-8",
        dataType: "html",
        type:"post",
        success: function(data)
        {
            console.log("Success!!!");
            alert(data);
        },
        error:function(){ console.log("Connection Error!!!");}
    });
}

This should send array of objects and return html (partial view). Next is...

Controller Action

[HttpPost]
public ActionResult GenerisiListuGostiju(List<GostiStavka> gosti)
{
    return PartialView("~/Views/Rezervacije/Partials/_GostDisplayTemplate.cshtml", gosti);
}

At this point everything works fine, sent array is recognized as a list of ViewModels(or DTOs whatever you want to call them) but returning a PartialView is returned as nothing with current ajax settings or 0 if "dataType" is set to "json".... so no html - no partial view. Partial View looks like this ...

Partial View

@model IEnumerable<ProjectName.ViewModels.GostiStavka>
<ul id="lista-gostiju" class="list-group">
    @Html.EditoFor(m => m.GostiStavka)
</ul>

Update

Editor Template

@model ProjectName.ViewModels.GostiStavka
<li class="gost-item">
<a href="#" class="btn btn-default btn-sm item-btn-left remove-item"><i class="fa fa-remove"></i></a>
<a href="#" class="btn btn-default btn-sm item-btn-right edit-item"><i class="fa fa-pencil"></i></a>
<div class="col-xs-5">@Model.ImePrezime</div>
<div class="col-xs-7">
    <a href="mailto:@Model.Email" class="">@Model.Email</a>
</div>
<div class="clearfix"></div>

<div class="form-items">
    @Html.HiddenFor(m => m.Id, new { @class="force-val" })
    @Html.HiddenFor(m => m.ImePrezime, new { @class = "force-val" })
    @Html.HiddenFor(m => m.DrzavaId, new { @class = "force-val" })
    @Html.HiddenFor(m => m.Email, new { @class = "force-val" })
    @Html.HiddenFor(m => m.Telefon, new { @class = "force-val" })
</div>
<div class="field-validation-error">
    @Html.ValidationMessageFor(m => m.Id)
    @Html.ValidationMessageFor(m => m.ImePrezime)
    @Html.ValidationMessageFor(m => m.DrzavaId)
    @Html.ValidationMessageFor(m => m.Email)
    @Html.ValidationMessageFor(m => m.Telefon)
</div>

EditorFor is a custom EditorTemplate that is tested by directly invoking it and sending appropriate list of objects and the response was as intended. I need this editor template because I want to use its features of proper binding of input elements to model eg. 'name="GostiStavka[0].Id"'.

I tried to return json too but I need something to convert PartialView to string. Found couple of solutions here on stack overflow but at best they returned a string like "0\r\n\r\n" as if they couldn't parse the editor and returned only row/line escape characters....

My previous solution that worked involves managing these names trough "javascript" but that seemed like inventing the wheel again because MVC5 Editor Templates can do that for you.

Any ideas on making this work are appreciated. Also, new ideas to to dynamically add items to list of a certain type to ViewModel on submit without adding them to DB beforehand is also good.(sorry, not a native English speaker)

Dino
  • 467
  • 1
  • 5
  • 14
  • Check http://stackoverflow.com/questions/4730777/mvc-return-partial-view-as-json – Amit Feb 08 '17 at 13:28
  • Doesn't look like this case warrants converting the view to a string first as you're only interesting in the view's html. You'd convert to a string if you need to manipulate that string or return it *with* something else (eg a success flag json). Returning `PartialView()` *already* returns as a string. – freedomn-m Feb 08 '17 at 13:30
  • What happens if you change your partial view to just something basic, like `

    Success

    ` - does that work? If so, then it'll be an issue with the partial and/or the data passed to it. When your Action is hit, does `gosti` contain populated models? (not just a list of models, but do those models have values assigned correctly?)
    – freedomn-m Feb 08 '17 at 13:32
  • I was just about to suggest the same. The partial looks like it's going to cause a 500. Your model is an `IEnumerable`, which won't have a member named `GostiStavka`. If that member is on your `GostiStavka` class, then you would need to iterate over the model first, before calling `EditorFor`. – Chris Pratt Feb 08 '17 at 13:41
  • Ok, I get what you guys are saying ...let me try it out – Dino Feb 08 '17 at 13:43
  • OK, removed editor call from partial view and added some

    tags and it worked. The returned html was

    tags indeed so there is something wrong with my EditorTemplate. So I tried to iterate over that IEnumerable items but it triggered the default Editor and not my Template which is not what i want. So I will now add example of editor template that I made because clearly the problem is somewhere in there

    – Dino Feb 08 '17 at 14:17

1 Answers1

1

Solved this myself so here is how I did it:

Partial View

Changed incoming model from IEnumerable to ProjectName.ViewModels.RezervacijeKreirajVM because I want to retain correct names for list binding in the main view:

@model ProjectName.ViewModels.RezervacijeKreirajVM
<ul id="lista-gostiju" class="list-group">
    @Html.EditoFor(m => m.GostiStavka)
</ul>

Editor Template Location

This was my biggest mistake!

The MVC is using naming convention so if the requested editor didn't come from the same NamedController that the Views/Named/EditorTemplate is in then it was not accessible by default.

So I put mine inside shared folder just for the sake of testing an it was working without problems.

This didn't occur to me before because when I was testing the editor in the main view everything worked fine because the editor was located inside Main View folder eg. "Views/MainView/Editor Templates".

Thank you all for providing assistance.

Dino
  • 467
  • 1
  • 5
  • 14