cloneを使い、特定の要素を除いてformをsubmitする

2015/08/21

formをsubmitすると、formに属する全要素のデータがサーバに送られる。
特定の要素を除外してformをsubmitすることは通常はできないため、このような目的には、本来であればformを複数に分割して、各処理ボタンを押した時に必要な要素のみサーバに送られるようにすべきである。

特定の要素を除いてsubmitしたいという目的が無くても、通信データ量の観点からみると、やはり適切に分割された複数のformがある方がいい。

とはいっても何らかの事情で、全部入りのform一個だけしかない場合などでも、一部のデータを送らないようにするためにはどうすればいいか考えてみた。

解決方法としてまず考えられるのが、ajax通信でpostする方法。
jquery#serialize, serializeArrayでformを文字列にシリアライズするときに、特定のnameを除く方法 で書いたように、postするデータを作成するときに、特定の要素を省いてあげればいい。

しかし、アプリのつくり上、ajax通信ではなく通常のsubmitでpostしなければならないとなった場合、通常のJavaScript、HTMLの仕組みでは対応できない。

jQueryでformを作成してPOST(submit)する という記事で、動的にformを作成すればいいのかとヒントを得たので、作成してみる。
使用したメインのJavaScript関数は cloneNode(include_child) で、同じ機能が .clone( [withDataAndEvents ] ) という関数でjQueryにあったので、jQuery無と有で両方を試した。
jQuery無のバージョン
jQuery有のバージョン

jQuery無のバージョン

参考/引用

removeElement(node)の出典元:http://stackoverflow.com/questions/13763/how-do-i-remove-a-child-node-in-html-using-javascript
cloneNodeで選択状態をうまくコピーできない問題の参考元:http://www.programming-magic.com/20071205185601/

jQuery有のバージョン

参考/引用

cloneの拡張コード出典元:https://github.com/spencertipping/jquery.fix.clone
cloneの拡張コード参考元:http://stackoverflow.com/questions/742810/clone-isnt-cloning-select-values

jQuery版も処理の流れは、jQuery無のバージョンと同じだが、clone特有の選択状態をうまくコピーできないバグを修正したコード(jquery.fix.clone)があったので、それを利用した。
ただ jquery.fix.clone は、select要素にmultiple属性が指定されている場合(multiselect)を考慮していないようだったので、一部修正を加えた。
multiselectの場合の具体的な影響は以下の通り。(IE8で検証)

jQuery版をここからさらに改良するとすれば、submit(excludeIds)の引数部分がポイントとなる。
今回作成した関数のinterfaceを、jQuery無のバージョンと有のバージョンで合わせるため(引数がidの文字列の配列)に、jQuery版のコードで find("#" + excludeId) と汚いコードになったが、別にinterfaceを合わせる必要はない。
submit(excludeSelectors)としてあげれば、jQuery的な汎用性のある関数になる。

-JavaScript