0

I'm having an issue with a form in MVC5 at the moment:

Upon submiting the form, i'm sending an ajax request to the controller which should take care of the CRUD operation then return a view.

If the ModelState is valid, it should return an empty form, otherwise, it should return the form with the validation error messages.

My problem is that when my view is returned, if the ModelState is valid, the form isn't emptied despite returning an empty model.

Here is the actual ajax call part:

    $.ajax({
    url: urlAction,
    type: 'POST',
    data: formData,
    dataType: 'html',
    success: function(code_html) {
        $("#addUserForm").html(code_html);
    }
});

And the controller code:

        [HttpPost]
    public ActionResult CreateUserAndContinue(AjoutUtilisateurViewModel data)
    {
        if (ModelState.IsValid)
        {
            // INSERT In DB.
            return PartialView("AjoutUtilisateurPartial", new AjoutUtilisateurViewModel());
        }
        return PartialView("AjoutUtilisateurPartial", data);
    }

The main view code related:

<div id="addUserForm">
    @Html.Partial("AjoutUtilisateurPartial")
</div>

The partial view:

<div id="AddUserADForm">
    @using (Html.BeginForm("CreateUserAndContinue", "Habilitation", FormMethod.Post, new { @id = "addUserAD" }))
    {
        @Html.EditorForModel()
        <div class="interSmall">
            <div class="ligneOrangeHaut droite">
                <a id="btnSubmitAndContinue" class="button" href="#">Créer & Continuer</a>
                <a id="btnSubmitAndStop" class="button" href="#">Créer & Stop</a>
            </div>
        </div>
    }

</div>

Here is the form code: (Called in by EditorForModel() )

@model AjoutUtilisateurViewModel

<div class="indentBig interSmall">

    <div class="col45 interSmall padding-left-5">
        @*@Html.ValidationMessage("error")*@
        @Html.ValidationMessageFor(model => model.Matricule)
    </div>

    <div class="clear-both"></div>

    <div class="col45 interSmall padding-left-5">
        @Html.LabelFor(x => x.Matricule, new { @class = "label110" })
        @Html.TextBoxFor(x => x.Matricule)
        <a id="TestMatricule" class="button" href="#">Test</a>
    </div>
    <div class="col45 interSmall padding-left-5">
        @Html.LabelFor(x => x.EtatCompte, new { @class = "label110" })
        @Html.DropDownListFor(model => model.EtatCompte, new[] { new SelectListItem { Text = "Actif", Value = "true" }, new SelectListItem { Text = "Inactif", Value = "false" } })
    </div>
</div>

<div class="clear-both"></div>

<div class="indentBig interSmall">

    <div class="col45 interSmall padding-left-5">
        @Html.LabelFor(x => x.Nom, new { @class = "label110" })
        @Html.TextBoxFor(x => x.Nom, new { disabled = "true" })
    </div>

    <div class="col45 interSmall padding-left-5">
        @Html.LabelFor(x => x.Prenom, new { @class = "label110" })
        @Html.TextBoxFor(x => x.Prenom, new { disabled = "true" })
    </div>

    <div class="clear-both"></div>

    <div class="col45 interSmall padding-left-5">
        @Html.LabelFor(x => x.Service, new { @class = "label110" })
        @Html.TextBoxFor(x => x.Service, new { disabled = "true" })
    </div>

    <div class="col45 interSmall padding-left-5">
        @Html.LabelFor(x => x.Bureau, new { @class = "label110" })
        @Html.TextBoxFor(x => x.Bureau, new { disabled = "true" })
    </div>

    <div class="clear-both"></div>

    <div class="col45 interSmall padding-left-5">
        @Html.LabelFor(x => x.Telephone, new { @class = "label110" })
        @Html.TextBoxFor(x => x.Telephone, new { disabled = "true" })
    </div>

    <div class="col45 interSmall padding-left-5">
        @Html.LabelFor(x => x.Courriel, new { @class = "label110" })
        @Html.TextBoxFor(x => x.Courriel, new { disabled = "true" })
    </div>

    <div class="clear-both"></div>

    <div class="col45 interSmall padding-left-5">
        @Html.LabelFor(x => x.Adresse, new { @class = "label110" })
        @Html.TextBoxFor(x => x.Adresse, new { disabled = "true" })
    </div>

    <div class="col45 interSmall padding-left-5">
        @Html.LabelFor(x => x.CodePostal, new { @class = "label110" })
        @Html.TextBoxFor(x => x.CodePostal, new { disabled = "true" })
    </div>

    <div class="clear-both"></div>

    <div class="col45 interSmall padding-left-5">
        @Html.LabelFor(x => x.Ville, new { @class = "label110" })
        @Html.TextBoxFor(x => x.Ville, new { disabled = "true" })
    </div>

    <div class="col45 interSmall padding-left-5">
        @Html.LabelFor(x => x.Departement, new { @class = "label110" })
        @Html.TextBoxFor(x => x.Departement, new { disabled = "true" })
    </div>

    <div class="clear-both"></div>

    <div class="col45 interSmall padding-left-5">
        @Html.LabelFor(x => x.OU, new { @class = "label110" })
        @Html.TextBoxFor(x => x.OU, new { disabled = "true" })
    </div>

    <div class="clear-both"></div>

    <div class="col45 interSmall padding-left-5">
        @Html.LabelFor(x => x.ZoneLibre1, new { @class = "label110" })
        @Html.TextBoxFor(x => x.ZoneLibre1)
    </div>

    <div class="col45 interSmall padding-left-5">
        @Html.LabelFor(x => x.ZoneLibre2, new { @class = "label110" })
        @Html.TextBoxFor(x => x.ZoneLibre2)
    </div>

    <div class="clear-both"></div>

</div>

Which is an editor template.

This problem confuses me because i've a really similar function that fills the form and returns a PartialView with a Model pre-set which works great. But being new to MVC i'm probably missing out on something big.

Any help is apreciated :)

MagiKruiser
  • 431
  • 1
  • 6
  • 19
  • Where is addUserForm defined in your HTML? I don't see it, so it's unclear if jQuery is replacing it. Or is the HTML you provided defining addUserForm (essentially your partial view)? – Ellesedil Oct 20 '14 at 21:30
  • I'm not at work anymore so i'm trying to answer from what I remember: #addUserForm is the parent of the PartialView
    @Html.Partial etc..
    The partialview itself only consist of the form + button. (Pretty much a div containing @Html.BeginForm + @Html.EditorFor) I can only clear that up better tomorrow if it's not enough x:
    – MagiKruiser Oct 20 '14 at 21:48
  • So, the HTML that's in the question is just the partial view? And the HTML here lives inside the addUserForm div of the parent view, off-screen? – Ellesedil Oct 20 '14 at 21:50
  • The HTML in the question is taken from the EditorTemplate which is included in the PartialView. The partialview itself is prettymuch <@Html.BeginForm(blabla)> @Html.EditorFor (which display the HTML pasted in the question) [Once again i'm inaccurate since i dont have the code in front of me anymore atm, sorry about that :/) – MagiKruiser Oct 20 '14 at 21:54
  • I edited, also realised that in case of invalid ModelState, the program was actually behaving properly (error message being displayed), it doesn't though if the form is filled properly despite returning the intended empty model. – MagiKruiser Oct 21 '14 at 07:42

2 Answers2

0

I think you should put all inputs to the @using(Html.BeginForm()) { ... }

Daniil T.
  • 1,145
  • 2
  • 13
  • 33
  • Hey, they actually are. As I stated, the form is taken from the EditorTemplate made for my viewmodel. The actual partial view has something such as this :P (Followed by @Html.EditorFor()) – MagiKruiser Oct 20 '14 at 18:50
  • I think Each partial should have their own form tag. Or maybe I didn't understand what you trying to achieve – Daniil T. Oct 20 '14 at 19:04
  • Hum think you misunderstood. I have a single form. If it's filled properly, the Controller should return a view with an empty form (for this im returning the PartialView with an empty model instance associated to this form). In case of error, it should return the partialview with the same model instance that had been used to submit and display errors, but none of those behaviour actually happen. (Despite breakpoint showing it goes to "return PartialView(new Model())" or "return PartialView(oldmodel)" accordingly to the ModelState. – MagiKruiser Oct 20 '14 at 21:19
  • Could you post main view code, please? Because I am not sure it is possible to have partial inside form. You should have separate form for each partial view and then after failure it will populate your inputs with model. One way or another it would be easier to help you if could provide View code where you trying to insert a partial view – Daniil T. Oct 20 '14 at 22:29
  • As I stated i was away from work so i can't post more code until tomorrow; but will do. The form is inside the partialview though, not the other way around D: – MagiKruiser Oct 20 '14 at 23:12
  • I edited, also realised that in case of invalid ModelState, the program was actually behaving properly (error message being displayed) - was too tired yesterday for sure..., it doesn't though if the form is filled properly despite returning the intended empty model. – MagiKruiser Oct 21 '14 at 07:41
  • Will do, I need to wait 24 hours though before accepting my own reply as answer :P – MagiKruiser Oct 21 '14 at 09:29
0

Well to a new day, new ideas, it ended up being pretty much a duplicate of this thread:

Reset the value of textarea after form submission

Thanks to the original answer author which solved the problem. =p

Pretty much upon returning POST request, the view return read data from the ModelState instead of the model itself, hence why returning an empty model would not change anything.

Community
  • 1
  • 1
MagiKruiser
  • 431
  • 1
  • 6
  • 19