3

I am creating an MVC module for DNN and trying to return a form as a partial view to allow entry of a dynamic number of objects from the user, however when I make an AJAX call to my action route which returns the PartialView and append it to the page, I'm receiving the HTML for an entire page wrapped in my DNN skin's layout.

I followed the example for rendering partial views from DNN's official samples repo and this general MVC guide. I've made sure to return a PartialView from my ActionResult and set the Layout to null in my partial view Razor template.

My Action:

 public PartialViewResult BlankEducationForm()
        {
            return PartialView(new Education());
        }

My partial view:

@inherits DotNetNuke.Web.Mvc.Framework.DnnWebViewPage<Chris.Modules.ResumeTest2.Models.Education>

@{
    Layout = null;
}

@using System.Text.RegularExpressions
@using DotNetNuke.Web.Mvc.Helpers

<div class="education-editor">
    <div class="form-row">
        <div class="form-group col-md-6">
            <label for="inputEmail4">School Name:</label>
            @Html.TextBoxFor(m => m.SchoolName, new { @class = "form-control", @placeholder = "Degree" })
        </div>
        <div class="form-group col-md-6">
            <label for="inputPassword4">Degree(s) Earned:</label>
            @Html.TextBoxFor(m => m.Degree, new { @class = "form-control", @placeholder = "Degree" })
        </div>
    </div>
    <div class="form-row">
        <div class="form-group col-md-4">
            <label for="inputEmail4">Start Year:</label>
            @Html.TextBoxFor(m => m.StartYear, new { @class = "form-control", @placeholder = "Start Year" })
        </div>
        <div class="form-group col-md-4">
            <label for="inputPassword4">End Year:</label>
            @Html.TextBoxFor(m => m.EndYear, new { @class = "form-control", @placeholder = "End Year" })
        </div>
        <div class="form-group col-md-4">
            <label for="inputPassword4">Display Order:</label>
            @Html.TextBoxFor(m => m.Order, new { @class = "form-control", @placeholder = "Order" })
        </div>
    </div>


</div> 

The parent view that's calling it with the AJAX call:

@inherits DotNetNuke.Web.Mvc.Framework.DnnWebViewPage<Chris.Modules.ResumeTest2.Models.Resume>

@using System.Text.RegularExpressions
@using DotNetNuke.Web.Mvc.Helpers


<div id="Items-@Dnn.ModuleContext.ModuleId">
    <div id="resume-container">
        <form method="post" action="@Url.Action("Create", "Resume")">
            <h1>General Information</h1>  
            <div class="form-group">
                <label for="exampleInputPassword1">Resumé Name:</label>
                @Html.TextBoxFor(m => m.ResumeName, new { @class = "form-control", @placeholder = "Resume Name" })
            </div>

            <div class="form-row">
                <div class="form-group col-md-4">
                    <label for="inputEmail4">First Name:</label>
                    @Html.TextBoxFor(m => m.FirstName, new { @class = "form-control", @placeholder = "First Name" })
                </div>
                <div class="form-group col-md-4">
                    <label for="inputPassword4">Last Name:</label>
                    @Html.TextBoxFor(m => m.LastName, new { @class = "form-control", @placeholder = "Last Name" })
                </div>
                <div class="form-group col-md-4">
                    <label for="inputPassword4">Middle Name:</label>
                    @Html.TextBoxFor(m => m.MiddleName, new { @class = "form-control", @placeholder = "Middle Name" })
                </div>
            </div>

            <div class="form-row">
                <div class="form-group col-md-6">
                    <label for="inputEmail4">Address 1</label>
                    @Html.TextBoxFor(m => m.Address1, new { @class = "form-control", @placeholder = "Address 1" })
                </div>
                <div class="form-group col-md-6">
                    <label for="inputPassword4">Address 2</label>
                    @Html.TextBoxFor(m => m.Address2, new { @class = "form-control", @placeholder = "Address 2" })
                </div>
            </div>

            <div class="form-row">
                <div class="form-group col-md-4">
                    <label for="inputEmail4">City:</label>
                    @Html.TextBoxFor(m => m.City, new { @class = "form-control", @placeholder = "City" })
                </div>
                <div class="form-group col-md-4">
                    <label for="inputPassword4">State:</label>
                    @Html.TextBoxFor(m => m.State, new { @class = "form-control", @placeholder = "State" })
                </div>
                <div class="form-group col-md-4">
                    <label for="inputPassword4">ZIP:</label>
                    @Html.TextBoxFor(m => m.Zip, new { @class = "form-control", @placeholder = "ZIP" })
                </div>
            </div>

            <div class="form-row">
                <div class="form-group col-md-6">
                    <label for="inputEmail4">Phone Number:</label>
                    @Html.TextBoxFor(m => m.Phone, new { @class = "form-control", @placeholder = "Phone" })
                </div>
                <div class="form-group col-md-6">
                    <label for="inputPassword4">E-Mail:</label>
                    @Html.TextBoxFor(m => m.Email, new { @class = "form-control", @placeholder = "E-mail" })
                </div>
            </div>
            <h1>Education</h1>  
            <div id="education-forms"></div>
            @Html.ActionLink("Add another...", "BlankEducationForm", "Resume", null, new { id = "addItem" })
            @Html.HiddenFor(m => m.ResumeId)
            <button type="submit" class="dnnPrimaryAction">Create</button>
        </form>
    </div>
    <script>
        $('#addItem').click(function () {
            $.ajax({
                url: this.href,
                cache: false,
                success: function (html) {
                    $('#education-forms').append(html);
                }
            });
            return false;
        });
    </script>
</div>

It does insert the HTML from the request, which includes the form, but for some reason it thinks I want the whole page. I'm not sure if there's some kind of issue with DNN recognizing my controllers, but I have no reason to expect one. I'm really stumped.

Chris B.
  • 5,477
  • 1
  • 12
  • 30

2 Answers2

1

In the success function of your ajax call, instead of using:

success: function (html) {
  $('#education-forms').append(html);
}

Try the following instead:

success: function (html) {
  $('#education-forms').html(html);
}

/// Update to follow up comment

What is the .cshtml of your partial view? For example, if it's called _MyPartialView.cshtml try one of the following (Can't remember off the top of my head if .cshtml is needed or not):

public PartialViewResult BlankEducationForm()
{
    return PartialView("_MyPartialView", new Education());
    return PartialView("_MyPartialView.cshtml", new Education());
}
Andrew
  • 238
  • 1
  • 9
  • Doesn't make a difference, the actual HTML being returned is for an entire page. – Chris B. Feb 04 '19 at 21:21
  • The extension should not be required, but I've tried both including the view name and leaving it out. Both ways do return the view as it corresponds to the action name, however in all cases it is wrapped in the entire page layout. My last guess was that it was due to my lack of a RouteConfig, but even after including one to spec from the examples I have the same issue. – Chris B. Feb 04 '19 at 21:31
0

You need to setup your RouteConfig.cs like this

public class RouteConfig : IMvcRouteMapper {
    public void RegisterRoutes(DotNetNuke.Web.Mvc.Routing.IMapRoute mapRouteManager) {
        mapRouteManager.MapRoute("ModuleNameHere", "ControllerNameHere", "{controller}/{action}", new[]
        {"ControllerNamespaceHere.Controllers"});
    }
}

Then you need to use the url like this in your ajax call

'/DesktopModules/MVC/ModuleName/ControllerName/ActionName';

This prevents dnn from injecting the headers and everything else.

mingle
  • 580
  • 2
  • 6
  • 24