wake-up-neo.com

Wie erstelle ich in Rails mehrere Submit-Buttons für dasselbe Formular?

Ich muss mehrere Senden-Schaltflächen haben.

Ich habe ein Formular, das eine Instanz von Contact_Call erstellt.

Eine Schaltfläche erstellt es wie gewohnt.

Die andere Schaltfläche erstellt es, muss jedoch einen vom Standardwert abweichenden Attributwert haben und das Attribut muss für ein anderes, aber in Beziehung stehendes Modell festgelegt werden, das im Controller verwendet wird.

Wie mache ich das? Ich kann die Route nicht ändern. Gibt es also eine Möglichkeit, eine andere Variable zu senden, die von [: params] abgerufen wird?

Und wenn ich das tue, was mache ich dann in der Steuerung, um eine case-Anweisung einzurichten?

91
Timothy T.

Sie können mehrere Senden-Schaltflächen erstellen und jedem einen anderen Wert zuweisen:

<% form_for(something) do |f| %>
    ..
    <%= f.submit 'A' %>
    <%= f.submit 'B' %>
    ..
<% end %>

Dies wird Folgendes ausgeben:

<input type="submit" value="A" id=".." name="commit" />
<input type="submit" value="B" id=".." name="commit" />

In Ihrem Controller wird der Wert der übergebenen Schaltfläche durch den Parameter commit identifiziert. Überprüfen Sie den Wert, um die erforderliche Verarbeitung durchzuführen:

def <controller action>
    if params[:commit] == 'A'
        # A was pressed 
    elsif params[:commit] == 'B'
        # B was pressed
    end
end

Denken Sie jedoch daran, dass dies Ihre Sicht eng mit der Steuerung verbindet, was möglicherweise nicht sehr wünschenswert ist.

125
Anurag

Es gibt auch einen anderen Ansatz, bei dem das Attribut formaction auf der Schaltfläche submit verwendet wird:

<% form_for(something) do |f| %>
    ...
    <%= f.submit "Create" %>
    <%= f.submit "Special Action", formaction: special_action_path %>
<% end %>

Der Code bleibt sauber, da für die Standard-Schaltfläche zum Erstellen keine Änderungen erforderlich sind. Sie fügen lediglich einen Routing-Pfad für die Spezialschaltfläche ein:

formaction:
Die URI eines Programms, das die vom Eingabeelement gesendeten Informationen verarbeitet, sofern es sich um eine Schaltfläche oder ein Bild zum Senden handelt. Wenn angegeben, überschreibt es das Aktionsattribut des Formulareigners des Elements . Quelle: MDN

60
patpir

Alternativ können Sie erkennen, welche Schaltfläche gedrückt wurde, indem Sie ihren Attributnamen ändern.

<% form_for(something) do |f| %>
    ..
    <%= f.submit 'A', name: 'a_button' %>
    <%= f.submit 'B', name: 'b_button' %>
    ..
<% end %>

Es ist ein bisschen unangenehm, weil Sie die Anwesenheit der Parametertasten überprüfen müssen, anstatt einfach den Wert params[:commit] Zu überprüfen: Sie erhalten params[:a_button] Oder params[:b_button], Je nachdem, welcher gedrückt wurde.

29
masciugo

Ähnliche Lösung zu einer von @ vss123 vorgeschlagenen Lösung ohne Verwendung von Edelsteinen:

resources :plan do
  post :save, constraints: lambda {|req| req.params.key?(:propose)}, action: :propose
  post :save, constraints: lambda {|req| req.params.key?(:finalize)}, action: :finalize
end

Beachten Sie, dass ich die Verwendung von Wert vermeide und stattdessen den Eingabenamen verwende, da der Wert der Schaltfläche "Senden" häufig internationalisiert/übersetzt wird. Außerdem würde ich vermeiden, dies zu viel zu verwenden, da es Ihre Routendatei schnell überladen wird.

12

Wir haben erweiterte Einschränkungen in Rails verwendet.

Die Idee ist, den gleichen Pfad (und damit die gleiche benannte Route und Aktion) zu haben, aber mit Einschränkungen, die das Routing auf verschiedene Aktionen beschränken.

resources :plan do
  post :save, constraints: CommitParamRouting.new("Propose"), action: :propose
  post :save, constraints: CommitParamRouting.new("Finalize"), action: :finalize
end

CommitParamRouting ist eine einfache Klasse mit einer Methode matches?, das true zurückgibt, wenn der Festschreibungsparameter mit der angegebenen Instanzattr übereinstimmt. Wert.

Dies ist als Juwel verfügbar commit_param_matching .

9
siliconsenthil

Eine alte Frage, aber da ich mich mit der gleichen Situation befasst habe, dachte ich, ich würde meine Lösung posten. Ich verwende Steuerungskonstanten, um eine Diskrepanz zwischen der Steuerungslogik und der Ansichtsschaltfläche zu vermeiden.

class SearchController < ApplicationController
  SEARCH_TYPES = {
    :searchABC => "Search ABCs",
    :search123 => "Search 123s"
  }

  def search
    [...]
    if params[:commit] == SEARCH_TYPES[:searchABC]
      [...]
    elsif params[:commit] == SEARCH_TYPES[:search123]
      [...]
    else
      flash[:error] = "Search type not found!"]
      [...]
    end
  end
  [...]          
end

Und dann in der Ansicht:

<% form_for(something) do |f| %>
    [...]
    <%= f.submit SearchController::SEARCH_TYPES[:searchABC] %>
    <%= f.submit SearchController::SEARCH_TYPES[:search123] %>
    [...]
<% end %>

Auf diese Weise lebt der Text nur an einer Stelle - als Konstante im Controller. Ich habe jedoch noch nicht versucht, herauszufinden, wie ich das anstellen soll.

3
Draknor

Ich habe dank nested_form_fields eine variable Anzahl von Submit-Schaltflächen in meinem Formular, daher reichte es mir nicht, nur den Namen zu verwenden. Am Ende habe ich ein verstecktes Eingabefeld in das Formular eingefügt und es mithilfe von Javascript ausgefüllt, als eine der Schaltflächen zum Senden des Formulars gedrückt wurde.

1
Shawn Walton