0

I have a page that has about 4 different forms nested inside of their own modal pop up windows.

I have only ever done one page per form until this point.

What happens is when I submit to the controller and my modelState is not valid is that it routs back to my partial view.

How can I make the @validationFor messages show up in my modal, just like on my single form pages? Basically the page doesn't change, but if it does, it returns the page with the modal still up.

Will this require that I use some sort of Ajax call instead? are there any examples on here of that? I am pretty sure this is probably a duplicate thread, however I couldn't find any resources for myself.

Travis Tubbs
  • 827
  • 1
  • 14
  • 32

3 Answers3

1

Yes this will require some javascript to make this work.

  1. create partial views to hold a form.

@using (Html.BeginForm("CreateHighSchoolType", "HighSchool", FormMethod.Post, new { id = "CreateHighSchoolTypeForm" }))
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend></legend>
        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>
        <p>
            <input type="submit" value="Create" id="CreateHighSchoolTypeButton" />
        </p>
    </fieldset>
}
  1. create a controller methods to handle the partial view

    public ActionResult CreateHighSchoolTypePartial()
    {
        return PartialView();
    }
    
    [HttpPost]
    public ActionResult CreateHighSchoolTypePartial(LookupEditModel viewModel)
    {
        if (!ModelState.IsValid)
        {
            return PartialView(viewModel);
        }
    
        var hsType = (from t in _highSchoolTypeRepository.FindAll()
                      where t.Name == viewModel.Name
                      select t).FirstOrDefault();
    
        if (hsType != null)
        {
            ModelState.AddModelError("Name", String.Format("This high school type already exists.", viewModel.Name));
            return PartialView(viewModel);
        }
    
        _highSchoolTypeRepository.Save(new HighSchoolType
        {
            Name = viewModel.Name
        });
    
        return PartialView();
    }
    
  2. wire up everything with some jquery

the dialog opening

    $("#AddHighSchoolTypeDialog").dialog({
        position: 'center',
        autoOpen: false,
        modal: true,
        resizable: false,
        draggable: false,
        title: "Add a new high school type",
        open: function (event, ui) {
            //Load the CreateAlbumPartial action which will return 
            // the partial view _CreateAlbumPartial
            $(this).load("/HighSchoolType/CreateHighSchoolTypePartial", function () {
                $("form#CreateHighSchoolTypeForm input:first").focus(); 
            });
        },
        focus: function (event, ui) {

        },
        close: function (event, ui) {
            $.ajax({
                url: "/HighSchoolType/GetAllHighSchoolTypes",
                type: "GET",
                success: function (data) {
                    $("#HighSchoolTypeId option").remove();
                    $.each(data, function (key, value) {
                        $('#HighSchoolTypeId')
                                    .append($("<option></option>")
                                    .attr("value", key)
                                    .text(value));
                    });
                }
            });
            //$("#AddHighSchoolTypeDialog").remove();
        },
        width: 600
    });

and the post

    $("#CreateHighSchoolTypeButton").live('click', function () {
        $.ajax({
            url: "/HighSchoolType/CreateHighSchoolTypePartial",
            type: "POST",
            data: $("#CreateHighSchoolTypeForm").serialize(),
            error: function (data) {
                var errorMessage = $.parseJSON(data.responseText);
            },
            success: function (data) {
                if (data) {
                    $('#AddHighSchoolTypeDialog').html(data);
                }
                else {
                    $('#AddHighSchoolTypeDialog').html('no data');
                }
            }
        });

        return false;
    });

Note how on success your need to replace the html of the modal with what was returned from the post call.

Fran
  • 6,440
  • 1
  • 23
  • 35
0

As per my understanding, what you are doing is trying to have multiple forms in one page. You can try something like this -

     @using (Html.BeginForm("Login", "Member", FormMethod.Post, new {})) {

        @Html.LabelFor(m => m.LoginUsername)
        @Html.TextBoxFor(m => m.LoginUsername)

        @Html.LabelFor(m => m.LoginPassword)
        @Html.TextBoxFor(m => m.LoginPassword)

        <input type='Submit' value='Login' />

    }

    @using (Html.BeginForm("Register", "Member", FormMethod.Post, new {})) {

        @Html.LabelFor(m => m.RegisterFirstName)
        @Html.TextBoxFor(m => m.RegisterFirstName)

        @Html.LabelFor(m => m.RegisterLastName)
        @Html.TextBoxFor(m => m.RegisterLastName)

        @Html.LabelFor(m => m.RegisterUsername)
        @Html.TextBoxFor(m => m.RegisterUsername)

        @Html.LabelFor(m => m.RegisterPassword)
        @Html.TextBoxFor(m => m.RegisterPassword)

        <input type='Submit' value='Register' />
}

inside a single page.

You can check answers on this link - asp.net MVC 4 multiple post via different forms

Community
  • 1
  • 1
Dhanashree
  • 235
  • 1
  • 3
  • 20
0

The unobtrusive validation will only work on forms that exist on page load. if you are loading the pages dynamical in the modals you need to register them after they load

$.validator.unobtrusive.parse("#formid")

or you can just hide the views on load and show when needed

KevDevMan
  • 808
  • 11
  • 23