2009-11-11 15 views
108

mam dwa przyciski na moim formularzu MVC:MVC który przedkłada przycisk został naciśnięty

<input name="submit" type="submit" id="submit" value="Save" /> 
<input name="process" type="submit" id="process" value="Process" /> 

Z mojego działania kontrolera Skąd mam wiedzieć, który z nich został naciśnięty?

+0

Dlaczego nie wystarczy dodać onclick zdarzenia do tych przycisków, które udają się do własnej wywołania AJAX, która trafi do ich odpowiednich metod? tj: ''? – ragerory

Odpowiedz

141

Name obie twoje przyciski przesyłania samo

<input name="submit" type="submit" id="submit" value="Save" /> 
<input name="submit" type="submit" id="process" value="Process" /> 

Następnie w kontroler uzyskać wartość przedstawienia. Tylko kliknięty przycisk przejdzie jego wartość.

public ActionResult Index(string submit) 
{ 
    Response.Write(submit); 
    return View(); 
} 

Można oczywiście ocenić tę wartość, aby wykonać różne operacje za pomocą bloku przełącznika.

public ActionResult Index(string submit) 
{ 
    switch (submit) 
    { 
     case "Save": 
      // Do something 
      break; 
     case "Process": 
      // Do something 
      break; 
     default: 
      throw new Exception(); 
      break; 
    } 

    return View(); 
} 
+12

Strzeż się problemów, które lokalizacja może przynieść temu rozwiązaniu, na które Darin nie jest podatny. –

+0

Dwa wejścia o tej samej nazwie powodują wysłanie tablicy z jednym elementem dla każdej wartości, a nie pojedynczą wartością domniemaną. Więc chciałbym móc powiedzieć inaczej, ponieważ miałem nadzieję/próbowałem to wykorzystać, ale to nie działa. –

43
<input name="submit" type="submit" id="submit" value="Save" /> 
<input name="process" type="submit" id="process" value="Process" /> 

I w swoim działaniu kontrolera:

public ActionResult SomeAction(string submit) 
{ 
    if (!string.IsNullOrEmpty(submit)) 
    { 
     // Save was pressed 
    } 
    else 
    { 
     // Process was pressed 
    } 
} 
+1

Wyobrażam sobie, że można dodać więcej przycisków, dodając je do listy parametrów i nadając im właściwą nazwę. Ładne rozwiązanie! – GONeale

0

Nie możesz dowiedzieć się za pomocą Request.Form Collection? Jeśli proces kliknięciu [ „proces”] Request.Form nie będzie pusta

26

jest to lepsze rozwiązanie, więc możemy mieć zarówno tekst jak i wartość dla przycisku:

http://weblogs.asp.net/dfindley/archive/2009/05/31/asp-net-mvc-multiple-buttons-in-the-same-form.aspx

</p> 
<button name="button" value="register">Register</button> 
<button name="button" value="cancel">Cancel</button> 
</p> 

i kontroler:

public ActionResult Register(string button, string userName, string email, string password, string confirmPassword) 
{ 
if (button == "cancel") 
    return RedirectToAction("Index", "Home"); 
... 

w skrócie jest to przycisk SUBMIT, ale wybierasz nazwę, używając atrybutu name, jeszcze mocniej, ponieważ nie jesteś zobowiązany do podania nazwy lub przycisku w parametrach metody kontrolera, możesz to nazwać tak jak lubisz ...

+0

Dzięki, Sir, to jest dokładnie to, czego potrzebuję. – oHoodie

5

Oto naprawdę ładny i prosty sposób na wykonanie z bardzo łatwymi do przestrzegania instrukcjami za pomocą niestandardowej metody MultiButtonAttribute:

http://blog.maartenballiauw.be/post/2009/11/26/Supporting-multiple-submit-buttons-on-an-ASPNET-MVC-view.aspx

Podsumowując, dokonaj przyciski przesyłania tak:

<input type="submit" value="Cancel" name="action" /> 
<input type="submit" value="Create" name="action" /> 

swoje działania tak:

[HttpPost] 
[MultiButton(MatchFormKey="action", MatchFormValue="Cancel")] 
public ActionResult Cancel() 
{ 
    return Content("Cancel clicked"); 
} 

[HttpPost] 
[MultiButton(MatchFormKey = "action", MatchFormValue = "Create")] 
public ActionResult Create(Person person) 
{ 
    return Content("Create clicked"); 
} 

I utworzyć tę klasę:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 
public class MultiButtonAttribute : ActionNameSelectorAttribute 
{ 
    public string MatchFormKey { get; set; } 
    public string MatchFormValue { get; set; } 

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo) 
    { 
     return controllerContext.HttpContext.Request[MatchFormKey] != null && 
      controllerContext.HttpContext.Request[MatchFormKey] == MatchFormValue; 
    } 
} 
+1

Zawsze najlepiej podsumować odnośnik do linku (na dzień, w którym blog zniknie). Podsumowując, blog opowiada się za posiadaniem niestandardowego atrybutu "MultiButtonAttribute", aby umożliwić rozróżnianie przycisków przesyłania. Właściwie to niezły pomysł. –

+1

A jeśli "Arnis L." zastosował się do tej samej rady, być może zauważyłeś, że podał dokładnie ten sam link 4 lata wcześniej:> –

+0

Bardzo dobry punkt @ TrueBlueAussie, dodałem podsumowanie kodu – Owen

3

Ten post nie zamierza odpowiedzieć na Coppermill, bo zostały wysłuchane dawno temu. Mój post będzie pomocny dla tych, którzy będą szukać takiego rozwiązania. Przede wszystkim muszę powiedzieć, że "rozwiązanie WDuffy jest całkowicie poprawne" i działa dobrze, ale moje rozwiązanie (w rzeczywistości nie moje) będzie używane w innych elementach i sprawi, że warstwa prezentacji będzie bardziej niezależna od kontrolera (ponieważ kontroler zależy od "wartość", która służy do wyświetlania etykiety przycisku, funkcja ta jest ważna w przypadku innych języków.).
Oto moje rozwiązanie, dać im różne nazwy, jak:
</p> <input type="submit" name="buttonSave" value="Save"/> <input type="submit" name="buttonProcess" value="Process"/> <input type="submit" name="buttonCancel" value="Process"/> </p>
I trzeba podać nazwy przycisków jako argumenty w akcji jak poniżej:

public ActionResult Register(string buttonSave, string buttonProcess, string buttonCancel){if (buttonSave!= null) 
{//save is pressed 
} 
if (buttonProcess!= null) 
{//Process is pressed 
} 
if (buttonCancel!= null) 
{//Cancel is pressed 
} 


gdy użytkownik wysyła stronę używając jednego z przycisków, tylko jeden z argumentów będzie miał wartość. Myślę, że będzie to pomocne dla innych.

2

Aby ułatwić powiem możesz zmienić przyciski na następujące kwestie:

<input name="btnSubmit" type="submit" value="Save" /> 
<input name="btnProcess" type="submit" value="Process" /> 

Kontroler:

public ActionResult Create(string btnSubmit, string btnProcess) 
{ 
    if(btnSubmit != null) 
     // do something for the Button btnSubmit 
    else 
     // do something for the Button btnProcess 
} 
2
// Buttons 
<input name="submit" type="submit" id="submit" value="Save" /> 
<input name="process" type="submit" id="process" value="Process" /> 

// Controller 
[HttpPost] 
public ActionResult index(FormCollection collection) 
{ 
    string submitType = "unknown"; 

    if(collection["submit"] != null) 
    { 
     submitType = "submit"; 
    } 
    else if (collection["process"] != null) 
    { 
     submitType = "process"; 
    } 

} // End of the index method 
+0

To jest doskonałe rozwiązanie do wszystkich pozostałych wpisów, ponieważ pozwala to na przekazywanie bardzo złożonych danych formularzy w sposób ciągły, bez niestandardowych zestawów parametrów w każdym działaniu, dzięki czemu logika sterownika może być wysoce dostosowana do złożonych formularzy. Kudos Fredrik :) Zakładam, że FormCollection przejdzie w wielu formach? – Stokely

+0

Dziękuję Stokely. Możesz wywołać tę metodę z wielu formularzy, jeśli wykonasz wywołanie ajax, możesz dołączyć wiele formularzy do tego samego FormCollection. –

15

można zidentyfikować przycisk stąd plakietka jak poniżej, Musisz sprawdzić tak jak w tobie kontroler

if (Request.Form["submit"] != null) 
{ 
//Write your code here 
} 
else if (Request.Form["process"] != null) 
{ 
//Write your code here 
} 
+0

ta sztuczka była bardzo przydatna dla mnie, dzięki –

+0

jest to bardzo pomocne w sytuacjach, gdy nie chcesz przekazywać nazwy przycisku do wyników akcji post. – yogihosting

+0

w tym scenariuszu może być bardziej skomplikowane pozorowanie klasy Żądanie w teście jednostkowym. – Muflix

1

Podaj nazwę obu przyciskom i Sprawdź wartość z formularza.

<div> 
    <input name="submitButton" type="submit" value="Register" /> 
</div> 

<div> 
    <input name="cancelButton" type="submit" value="Cancel" /> 
</div> 

Na stronie kontrolera:

public ActionResult Save(FormCollection form) 
{ 
if (this.httpContext.Request.Form["cancelButton"] !=null) 
{ 
    // return to the action; 
} 

if (this.httpContext.Request.Form["submitButton"] !=null) 
{ 
    // save the oprtation and retrun to the action; 
} 
} 
Powiązane problemy