web-dev-qa-db-fra.com

MVC DropDownList OnChange pour mettre à jour d'autres champs de formulaire

Je suis nouveau sur MVC (je passe du côté obscur d'ASP.Net traditionnel) et je sais que SO est plus un "pourquoi ça ne marche pas" mais, étant nouveau à MVC, je voulais juste demander comment quelque chose est réalisé - je n'ai pas vraiment de code ou de balisage parce que je ne sais pas comment pour le moment.

Bon, en utilisant un exemple analogue ... J'ai un formulaire qui a une liste déroulante d'une liste de "Widgets" (ça marche, grâce à SO) ... et puis il y a d'autres champs (Longueur/Hauteur/Largeur ) qui ont des valeurs "par défaut".

Lorsque le formulaire s'affiche, la liste déroulante s'affiche, mais les champs de formulaire L/H/W sont vides/désactivés jusqu'à ce que l'utilisateur en sélectionne un dans la DDL.

Maintenant, dans le monde ASP.Net classique, vous feriez un PostBack sur "onselectedindexchange" et qui regarderait l'élément sélectionné, puis mettre à jour les champs L/H/W avec les valeurs de la version "entrée de widget maître".

Comme MVC n'a pas de retour ... comment est-ce possible?

15
Chris Hammond

Dans Asp.Net MVC, il n'y a pas de comportement de publication comme dans les formulaires Web lorsqu'une valeur de contrôle est modifiée. Vous pouvez toujours publier le formulaire et dans la méthode d'action, vous pouvez lire la valeur sélectionnée (valeur (s) publiée (s)) et charger les valeurs de vos zones de texte et rendre la page à nouveau. Ceci est la publication complète du formulaire. Mais il existe de meilleures façons de le faire en utilisant ajax afin que l'utilisateur ne subisse pas le rechargement complet de la page.

Ce que vous faites, lorsque l'utilisateur modifie la liste déroulante, obtenez la valeur de l'élément sélectionné et appelez votre serveur pour obtenir les données que vous souhaitez afficher dans les champs de saisie et les définir.

Créez un modèle d'affichage pour votre page.

public class CreateViewModel
{
    public int Width { set; get; }
    public int Height{ set; get; }

    public List<SelectListItem> Widgets{ set; get; }

    public int? SelectedWidget { set; get; }    
}

Maintenant, dans l'action GET, nous allons en créer un objet, initialiser la propriété Widgets et l'envoyer à la vue

public ActionResult Create()
{
  var vm=new CreateViewModel();
  //Hard coded for demo. You may replace with data form db.
  vm.Widgets = new List<SelectListItem>
            {
                new SelectListItem {Value = "1", Text = "Weather"},
                new SelectListItem {Value = "2", Text = "Messages"}
            };
 return View(vm);
}

Et votre vue de création qui est fortement typée en CreateViewModel

@model ReplaceWithYourNamespaceHere.CreateViewModel
@using(Html.BeginForm())
{
    @Html.DropDownListFor(s => s.SelectedWidget, Model.Widgets, "Select");

    <div id = "editablePane" >
         @Html.TextBoxFor(s =>s. Width,new { @class ="myEditable", disabled="disabled"})
         @Html.TextBoxFor(s =>s. Height,new { @class ="myEditable", disabled="disabled"})
    </div>
}

Le code ci-dessus rendra le balisage html pour l'élément SELECT et 2 champs de texte d'entrée pour la largeur et la hauteur. (Faites une "voir la source" sur la page et voyez)

Nous allons maintenant avoir du code jQuery qui écoute l'événement change de l'élément SELECT et lit la valeur de l'élément sélectionné, effectue un appel ajax au serveur pour obtenir la hauteur et la largeur du widget sélectionné.

<script type="text/javascript">
 $(function(){

      $("#SelectedWidget").change(function() {

            var t = $(this).val();

            if (t !== "") {               
                $.post("@Url.Action("GetDefault", "Home")?val=" + t, function(res) {
                    if (res.Success === "true") {

                      //enable the text boxes and set the value

                        $("#Width").prop('disabled', false).val(res.Data.Width);
                        $("#Height").prop('disabled', false).val(res.Data.Height);

                    } else {
                        alert("Error getting data!");
                    }
                });
            } else {
                //Let's clear the values and disable :)
                $("input.editableItems").val('').prop('disabled', true);
            }

        });
 });

</script>

Nous devons nous assurer d'avoir une méthode d'action appelée GetDetault à l'intérieur de HomeController pour gérer l'appel ajax.

[HttpPost]
public ActionResult GetDefault(int? val)
{
    if (val != null)
    {
        //Values are hard coded for demo. you may replae with values 
       // coming from your db/service based on the passed in value ( val.Value)

        return Json(new { Success="true",Data = new { Width = 234, Height = 345}});
    }
    return Json(new { Success = "false" });
}
17
Shyju
  1. Créez un contrôleur "Action" qui renvoie des données "Json".
  2. Faites appel Ajax "onchange" de la liste déroulante à "Action".
  3. Sur ajax "response" (json) u obtiendra des valeurs puis définira ces valeurs dans les champs de la réponse json.

C'est la façon de mettre à jour les valeurs des champs.

4
Parth Trivedi