Как создать несколько кнопок отправки для одной и той же формы в Rails?
Мне нужно иметь несколько кнопок.
У меня есть форма, которая создает экземпляр Contact_Call.
одна кнопка создает его как нормальный.
другая кнопка создает его, но должен иметь другое :значение атрибута от значения по умолчанию, и он также должен установить атрибут на другой, но связанной модели, используемой в контроллере.
Как мне это сделать? Я не могу изменить маршрут, так что есть способ отправить другую переменную, которая подхватит [:параметры]?
и если я это сделаю, что мне делать в контроллере, настроить оператор case?
7 ответов:
вы можете создать несколько кнопок отправки и предоставить разные значения для каждого:
<% form_for(something) do |f| %> .. <%= f.submit 'A' %> <%= f.submit 'B' %> .. <% end %>
это выведет:
<input type="submit" value="A" id=".." name="commit" /> <input type="submit" value="B" id=".." name="commit" />
внутри вашего контроллера значение отправленной кнопки будет определено параметром
commit
. Проверьте значение для выполнения необходимой обработки:def <controller action> if params[:commit] == 'A' # A was pressed elsif params[:commit] == 'B' # B was pressed end end
однако помните, что это плотно связывает ваш взгляд с контроллером, который может быть не очень желательным.
есть и другой подход, используя атрибут formaction на кнопке submit:
<% form_for(something) do |f| %> ... <%= f.submit "Create" %> <%= f.submit "Special Action", formaction: special_action_path %> <% end %>
код остается чистым, так как стандартная кнопка create не требует никаких изменений, вы только вставляете путь маршрутизации для специальной кнопки:
formaction:
URI программы, которая обрабатывает информацию, представленную элементом ввода, если это кнопка отправки или изображение. Если указано, то это переопределяет атрибут действия элемента владелец формы. Источник:MDN
вы также можете распознать, какая кнопка была нажата, изменив ее имя атрибута.
<% form_for(something) do |f| %> .. <%= f.submit 'A', name: 'a_button' %> <%= f.submit 'B', name: 'b_button' %> .. <% end %>
это немного неудобно, потому что вы должны проверить наличие ключей params вместо того, чтобы просто проверить
params[:commit]
значение: вы получитеparams[:a_button]
илиparams[:b_button]
в зависимости от того, какая была нажата.
аналогичное решение, предложенное @vss123 без использования каких-либо драгоценных камней:
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
обратите внимание, что я избегаю использования значения и вместо этого использую имя ввода, так как значение кнопки отправки часто интернационализируется / переводится. Кроме того, я бы избегал использовать это слишком много, так как это быстро загромождает ваш файл маршрутов.
мы решили с помощью дополнительные ограничения в рельсы.
идея состоит в том, чтобы иметь один и тот же путь (и, следовательно, одно и то же имя route & action), но с ограничениями маршрутизации на разные действия.
resources :plan do post :save, constraints: CommitParamRouting.new("Propose"), action: :propose post :save, constraints: CommitParamRouting.new("Finalize"), action: :finalize end
CommitParamRouting
- Это простой класс, который имеет методmatches?
который возвращает true, если параметр commit соответствует данному экземпляру attr. значение.Это доступно как драгоценный камень commit_param_matching.
старый вопрос, но так как я имел дело с той же ситуацией, я думал, что опубликую свое решение. Я использую константы контроллера, чтобы избежать введения несоответствия между логикой контроллера и кнопкой просмотра.
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
и затем в представлении:
<% form_for(something) do |f| %> [...] <%= f.submit SearchController::SEARCH_TYPES[:searchABC] %> <%= f.submit SearchController::SEARCH_TYPES[:search123] %> [...] <% end %>
У меня есть переменное количество кнопок отправки на моей форме благодаря nested_form_fields, так что просто используя имя не было достаточно для меня. Я закончил тем, что включил скрытое поле ввода в форму и использовал Javascript для его заполнения, когда была нажата одна из кнопок отправки формы.