不知道大家有沒有遇過Form裡面還有Form的狀況,並且裡面的Form和外面的Form並沒有關係,所以不能用Rails的 Nested Model Forms。
這裡也有很多種解法,最簡單的解法就是打ajax取回想要的結果⬇️,但當時因為對Ajax的寫法還不是很熟,最直覺想到的是form裡面寫form的情況。Unfortunately, 一個form tag(<form>…</form>)裡面只能有一個提交,如果裡面有兩個提交的話,都是提交外面的form。
$.ajax({
method: "post",
async: true,
data: { ... },
url: "your_url",
success: function(response){
...
},
});
Every form must be enclosed within a FORM element. There can be several forms in a single document, but the FORM element can’t be nested.” — HTML3 Spec
那時問了前端如果遇到這種問題要怎麼解決,前端跟我說用hidden,對當時的我來說,hidden也懵懵懂懂(後來會用hidden之後,我就更崩壞了),所以當時把值寫進hidden也不是我的選擇之一。
後來我在w3c看到這種用法,讓我知道原來提交是可以被移到外面執行的,只要外面指定的form name 表單ID名稱一樣就好,這讓我開始想到好用的方法。
<form action="/action_page.php" method="get" id="name-form">
<label for="first-name">First name:</label>
<input type="text" id="first-name" name="first_name"><br><br>
<label for="last-name">Last name:</label>
<input type="text" id="last-name" name="last_name">
</form>
<button type="submit" form="name-form" value="Submit">Submit</button>
You can tie a submit button to a form that the button doesn’t live inside of. The trick is to give the form an
id
and then reference thatid
with the button’sform
property. — Today Learned
這樣的話不就等於其實在form裡面寫了多少form都沒有問題了嗎?
# 這樣寫會出問題<form1>
<input (form1的input)/>
<form2>
<input (form2的input)/>
</form2>
</form1>
# 這樣寫就沒問題了<form1>
<input (form1的input)/>
<input (form2的input)/>
</form1>
<form2>
</form2>
以rails來說這樣寫完全沒問題。
<%= simple_form_for method: :post , html: { id: 'a' } do |p| %>
<input ...form="b">
<input ...form="b">
<% end %><%= simple_form_for method: :post , html: { id: 'b' } do |m| %>
<% end %>
對於不熟畫面的後端可以嘗試以下步驟:
- 先寫form包form的格式
- 查看Chrome原始碼,把原始碼複製下來(因為包在id=”a”裡面的表單不能使用block的寫法)
- 對於如果原本f.input為下拉式選單的話會比較棘手,但處理方式只需要多一點小技巧就可以了。假設裡面的form取名為b的話便可以這樣寫。
<%= select_tag(:<欄位>, options_for_select([[nil, nil],*@實體變數].map { |c| [c[1], c[0]] }), { name: "...", form: "b" }) %>
剛開始我同事都很難接受這種寫法,不過到後來我已經沒有寫了(上面的表單後來全部用vue寫),但我的兩位同事遇到這種問題,後來也都用這種解決辦法。所以事實證明,沒有什麼對錯,只有磨合!
下一篇寫rails就是為了打破慣例系列,會跟hidden有關,大家敬請期待。