1
votes

Envoyez une demande de publication et ignorez la réponse

J'ai essayé de mettre en place une fenêtre contextuelle modale en utilisant le modèle MVC dans un Framework ASP.net (4.8)

J'ai une table paginée avec de nombreuses lignes et des filtres fonctionnels (en utilisant datatables.net). Chaque ligne a un bouton qui utilise un appel ajax pour présenter une popup modale via une vue partielle. Je peux apporter des modifications aux données et les renvoyer en utilisant une requête POST.

Mais maintenant, je ne sais pas comment me débarrasser simplement de ma vue partielle tout en conservant la page d'index d'origine. Voici mon code:

Vue d'index

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var x = new Data().GetSampleModelList
        return View(x);
    }

    [HttpGet]
    public ActionResult Edit(int id)
    {
        var x = new Models.TestModel() { Id = id, Age = 0, Name = "" };
        return PartialView("Edit", x);
    }

    [HttpPost]
    public ActionResult Edit(Models.TestModel m)
    {
        SaveTheModelMethod();
        // Now What?
    }
}

Je n'utilise pas le style (je n'utilise PAS d'amorçage mais j'ai les mêmes noms de classe dans mon test), voici la vue partielle qui rend parfaitement

PartialView

<div id="editModal" class="modal">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h1>EDIT</h1>
            </div>
            <div class="modal-body">
                @using (Html.BeginForm("Edit", "Home", Model, FormMethod.Post, null))
                {
                    <p>Id = @Model.Id</p>
                    @Html.EditorFor(m => m.Age)
                    <input type="submit" />
                }
            </div>
            <div class="modal-footer">
                <p>Footer</p>
            </div>
        </div>
    </div>
</div>

Lors de la soumission, je passe actuellement le modèle édité au HomeController:

@model  List<Models.TestModel>

<script>
    $(function() {
        $('#editModal').modal();
    });

    function editProduct(productId) {
        $.ajax({
            url: '/Home/Edit/' + productId,
            success: function (data){
                $('#modalWrapper').html(data);
            }
        });
    }
</script>

<div>
    <table id="JrmTable">
        <thead>
            <tr>
                <th>Id</th>
                <th>Name</th>
                <th>Age</th>
                <th></th>
            </tr>
        </thead>

        <tbody>
            @foreach (var i in Model)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(m => i.Id)
                    </td>
                    <td>
                        @Html.DisplayFor(m => i.Name)
                    </td>
                    <td>
                        @Html.DisplayFor(m => i.Age)
                    </td>
                    <td>
                        <button onclick="editProduct(@i.Id)">ClickMe</button>
                    </td>
                </tr>
            }
        </tbody>
    </table>
</div>

<div id="modalWrapper"></div>

Alors c'est tout - j'envoie la demande de publication à un ActionResult qui attend une sorte de retour View () etc. - mais je ne veux vraiment rien renvoyer, je veux juste fermer la vue partielle (cela laissera le tableau affichant les anciennes données mais c'est une autre question)


0 commentaires

3 Réponses :


1
votes

Je pense que vous devriez alors recharger votre vue de liste en redirigeant vers votre action Index .

[HttpPost]
public ActionResult Edit(Models.TestModel m)
{
    SaveTheModelMethod();
    // Now What?
    return RedirectToAction("Index");
}

Ensuite, vous êtes de retour là où vous avez commencé.


4 commentaires

Je ne voulais pas faire cela car cela annulerait tout filtrage effectué sur la table. En fait, si je suivais cette route, je n'aurais pas pris la peine de faire toute l'idée de modification de la vue partielle de la fenêtre contextuelle modale, je m'en tiendrais simplement aux boutons d'édition redirigeant vers une nouvelle page d'affichage: / probs vient de perdre deux jours: D


alors vous ne devriez pas publier de formulaire pour commencer. au lieu d'un bouton d'envoi, mettez du JavaScript sur ce bouton et faites un appel AJAX à l'action Edit (Models.TestModel m) .


je publierai une deuxième réponse


Ouais, si je n'ai pas à poster le formulaire, tant mieux. Je souhaite conserver l'état général de toute la page d'index tout en 1) en envoyant des données mises à jour en arrière-plan et 2) en utilisant des js pour mettre à jour uniquement la ligne sélectionnée dans le tableau avec les nouvelles données pour refléter les modifications, sans passer par le tout le cycle d'index mvc à nouveau



3
votes

Si vous ne souhaitez pas recharger la page. Vous devez renvoyer un résultat vide.

<input type="button" id="submit_button" />

Source: https://docs.microsoft.com/en-us/dotnet/api/system.web.mvc.emptyresult?view=aspnet-mvc-5.2

À mon avis, vous devriez recharger la page d'index car sinon vos modifications n'apparaîtront pas sur l'interface utilisateur.

<input type="submit" />

Source: https: // docs.microsoft.com/en-us/dotnet/api/system.web.mvc.emptyresult?view=aspnet-mvc-5.2

MODIFIER: Vous obtenez une page vide parce que vous utilisez le type de bouton Soumettre. Vous devez le convertir en bouton de type et utiliser ajax (vous pouvez fournir un succès de votre choix).

<script>
    $("#submit_button").click(function () {
        let form = this.parents("form");

        $.ajax({
            type: "POST",
            url: form.attr("action"),
            data: form.serialize()
        });
    });
</script>

et changer

[HttpPost]
public ActionResult Edit(Models.TestModel m)
{
    SaveTheModelMethod();

    return RedirectToAction(nameof(Index));
}


2 commentaires

Je ne veux pas recharger la page cependant. Idéalement, j'utiliserai quelques js pour refléter les changements dans la ligne de tableau sélectionnée.


J'implémente peut-être une erreur mais EmptyResult () me donne juste une page vide.



1
votes

Si vous souhaitez utiliser AJAX, voici une autre solution:

JavaScript (modifié)

[HttpPost]
public JsonResult Edit(Models.TestModel m)
{
    SaveTheModelMethod();
    // Now What?
    return Json(new { success = true });
}

MVC View Snippet (modifié)

<div class="modal-body">
@using (Html.BeginForm("Edit", "Home", Model, FormMethod.Post, null))
{
    <p>Id = @Model.Id</p>
    @Html.HiddenFor(m => m.Id)
    @Html.EditorFor(m => m.Age)
    <button type="button" id="saveModelButton" onclick="saveProduct()" />
    // This Button changes to have an 'onclick' attribute 
}
 </div>

Action MVC

<script>
    $(function() {
        $('#editModal').modal();
    });

    function editProduct(productId) {
        $.ajax({
            url: '/Home/Edit/' + productId,
            success: function (data){
                $('#modalWrapper').html(data);
            }
        });
    }
    function saveProduct() {
        // get data from the form
        var payload = {
            Id: $("input[name=Id]").val(),
            Age: $("input[name=Age]").val()
        };
        // post to your edit action
        $.ajax({ 
            url: "/Home/Edit", type: "POST", 
            data: JSON.stringify(payload),
            contentType: 'application/json; charset=utf-8',
            success: function (data) {
                $('#editModal').hide();
                // CAVEAT: Hide your window using the appropriate command.
                // Here I am just hiding it with jQuery
            }
        });
    }
</script>


3 commentaires

J'essaierai cette première chose demain matin!


Fonctionne parfaitement. Merci beaucoup!


heureux d'avoir pu aider.