2015-12-02 16 views
9

Sono nuovo a MVC (mi sto spostando dal lato oscuro del tradizionale ASP.Net) e so che SO è più di un "perché non funziona" ma, Essendo nuovo a MVC, volevo solo chiedere come si ottiene qualcosa - non ho alcun codice o markup perché non so come al momento.MVC DropDownList OnChange per aggiornare altri campi modulo

Esatto, utilizzando un esempio analogo ... Ho un modulo che ha un menu a discesa di un elenco di "Widget" (funziona così, grazie a SO) ... e poi ci sono altri campi (Lunghezza/Altezza/Larghezza) che hanno valori "predefiniti".

Quando viene visualizzato il modulo, viene visualizzato il menu a discesa, ma i campi modulo di L/H/W sono vuoti/disabilitati finché l'utente non ne seleziona uno dal DDL.

Ora, nel mondo classico di ASP.Net, si eseguirebbe un PostBack su "onselectedindexchange" e si guarderebbe l'elemento selezionato, quindi aggiornare i campi L/H/W con i valori della "voce del widget principale" versione.

Poiché MVC non ha postback ... come è stato ottenuto?

+1

effettua un'azione Controller che restituisce i dati Json e effettua una chiamata ajax onchange del menu a discesa a tale azione. Su una risposta ajax (json) si otterranno i valori, quindi si imposteranno quei valori nei campi che formano la risposta JSON. –

+1

Puoi POSTARE su un metodo di azione per ottenere gli stessi risultati, ma [ecco un esempio] (http://stackoverflow.com/questions/5497524/easiest-way-to-create-a-cascade-dropdown-in-asp -net-mvc-3-with-c-sharp) di come fare con javascript – markpsmith

+0

Depends lo vuoi fare sulla vista stessa, o dovresti effettivamente interrogare qualcosa dal back-end? – Theunis

risposta

10

In Asp.Net MVC, non esiste un comportamento di postback come nei moduli Web quando si modifica un valore di controllo. È ancora possibile caricare il modulo e nel metodo di azione, è possibile leggere il valore selezionato (valori inseriti) e caricare i valori per le caselle di testo e visualizzare nuovamente la pagina. Questo è il modulo di registrazione completo. Ma ci sono modi migliori per farlo usando ajax così l'utente non sperimenterà la ricarica completa della pagina.

Quello che fai è, quando l'utente cambia il menu a discesa, ottenere il valore dell'elemento selezionato e fare una chiamata al server per ottenere i dati che si desidera mostrare nei campi di input e impostarli.

Creare un viewmodel per la pagina.

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

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

    public int? SelectedWidget { set; get; }  
} 

Ora nell'azione GET, creeremo un oggetto di questo, inizializzare il Widget di proprietà e inviare alla vista

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); 
} 

E il vostro creare vista che è fortemente tipizzato per 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> 
} 

Il codice sopra renderizza il markup html per l'elemento SELECT e 2 campi di testo di input per Larghezza e Altezza. (Fai una "vista sorgente" sulla pagina e vedi)

Ora avremo del codice jQuery che ascolta l'evento change dell'elemento SELECT e legge il valore dell'elemento selezionato, Effettua una chiamata ajax al server per ottenere il Altezza e larghezza per il widget selezionato.

<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> 

Abbiamo bisogno di fare in modo che abbiamo un metodo di azione chiamato GetDetault all'interno del HomeController per gestire la chiamata 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" }); 
} 
+0

Molto ben scritto ... Grazie ... –

+0

spiegato brillantemente. Grazie! –

2
  1. Fai un controller "azione" dati che ritorno "JSON".
  2. Chiamare Ajax "onchange" del menu a discesa "Azione".
  3. Su unjax "risposta" (json) otterrà i valori quindi imposta tali valori nei campi dalla risposta JSON.

Questo è il modo per aggiornare i valori dei campi.

+0

Grazie Parth ... Complimenti a te come hai fornito la risposta per prima (nei commenti) ma Shyju ha pubblicato un esempio completo e completo, quindi uno è stato contrassegnato come risposta. –