質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

3回答

8753閲覧

[jQuery] clone()で複製したフォームに

xjaPANDA

総合スコア124

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2017/07/26 11:05

ファイルを選択した時点で、そのinputフォームを新たにclone()で複製し、複製した側のidとname、初期の値を変更しています。また、複製したフォームでも同様に処理をおこないたいのですが、ファイルを選択しても、複製されません。どのような解決さくがあるでしょうか?

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title></title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> </head> <body> <form id='form' action="data.php" method="post" enctype="multipart/form-data"> <input type="file" class="files_1" name="files_1" /> <button type="submit">送信</button> </form> <script> var num = 1; $('form').on('change','.files_' + num , function(){ $(this).clone(true).insertAfter(this); $('.files_' + num).eq(1).attr('name', 'files_' + (num + 1 )); $('.files_' + num).eq(1).val(""); $('.files_' + num).eq(1).attr('class', 'files_' + (num + 1 )); //$('.files_' + num).hide(); num = num + 1; }); </script> </body> </html>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

問題発生の原因を考えると、下記の箇所がnumについて動的になるという勘違いがあったのかと思います。

$('form').on('change','.files_' + num , function(){

ってところはnum = 1 の1回のみを実行し、form要素に.files_1が変化したときfunctionを実行するっていう指示を出すっていうような意味になります。
このコードだとfunction中でnumが2に変わったとしてもform要素に新たに.files_2に関する設定を追加することはないです。

javascript

1$(hoge).on('イベント','hogeの子孫要素',function(){ }); 2

っていう式は「hogeの子孫要素」が後で追加になる場合の予約みたいなものですので、「hogeの子孫要素」を追加してあげるような形にしてあげるのが使いやすいやり方になると思います。

なので、「hogeの子孫要素」を流動的にせずに固定化して上げたほうが楽です。

それと、クローンを使う必然性がよくわかりません。そこで結構面倒なことしている気がします。
入れるのがリセットして名前替えただけの要素なので、鋳型を用意してそこから名前だけ替えたものを作成して、前方に突っ込めば良いのではないでしょうか?

下記にそんな感じのコードを書いてみました。

<form id='form' action="data.php" method="post" enctype="multipart/form-data"> <input type="file" class="files" name="files_1" /> <button type="submit">送信</button> </form> <script> $('form').on('change','.files', function(){ var num = $('.files').length + 1; var html = '<input type="file" class="files" name="files_'+num+'" />'; $(this).before(html); }); </script>

投稿2017/07/26 15:14

編集2017/07/26 15:16
oskbt

総合スコア1895

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

xjaPANDA

2017/08/16 05:53

ありがとうございます。とても勉強になります。
guest

0

ベストアンサー

いくつか課題はありますが、こんなところでしょうか。

  1. 1つ目のinput要素ノードを選択 ⇒ nextSibling にinput要素ノードを挿入
  2. 2つ目のinput要素ノードを選択 ⇒ nextSibling にinput要素ノードを挿入
  3. 1つ目のinput要素ノードを選択 ⇒ 何もしない

HTML

1<form id='form' action="data.php" method="post" enctype="multipart/form-data"> 2 <input type="file" class="files" name="files_1" /> 3 <button type="submit">送信</button> 4</form> 5<script> 6'use strict'; 7jQuery('form').on('change','.files', {i:1}, function (event) { 8 var input = event.currentTarget, 9 data = event.data, 10 i = data.i, 11 inputClone; 12 13 if (input.name !== 'files_' + i) { 14 return; 15 } 16 17 inputClone = jQuery(input).clone(false)[0]; 18 inputClone.name = 'files_' + ++i; 19 inputClone.value = null; 20 data.i = i; 21 22 jQuery(inputClone).insertAfter(input); 23}); 24</script>

個人的には、<input type="file" name="files[]"> のように配列で渡す方が面倒がなくて管理しやすいと思います。

Re: xjaPANDA さん

投稿2017/07/26 12:37

編集2017/08/02 08:42
think49

総合スコア18164

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

xjaPANDA

2017/08/16 05:52

ありがとうございます。とても勉強になります。おっしゃるとおり最終的には[]で管理するように変更しました。
guest

0

フォームタグをカスタマイズしたくなったら、フォームタグを捨てるべきときが来たのです。
html5のFormDataは、かなり自由にカスタマイズしたデータを送れますので、これを利用しましょう。

var fd = new FormData(); fd.append('hoge','hage');// hogeっていうキーのデータはhageだよ fd.append('file',files[i]);// Fileを追加してアップロードできます fd.append('str',new Blob(["hoge,moge,mage"]));// なんらかのデータ列ならBlobにしちゃえば、それをファイルってことにして送れます $.ajax({ type : 'POST', url: "data.php", contentType:false,// FormData送信用の設定その1。FileとBlobがサーバのファイルアップロードとして(phpでなら$_FILESとして)処理されます processData: false,// FormData送信用の設定その2。 データの暗黙変換が行われなくなります data : fd, success : function(res){ console.log(res); } });

投稿2017/07/26 11:32

zohnam

総合スコア1441

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

xjaPANDA

2017/07/26 11:53

返信ありがとうござまいす。FormData()では、ajax送信することが前提なのでしょうか? fdに入っているデータをajaxで送信ではなく、フォームからのsubmitボタンクリック時にあわせて、POSTすることは可能でしょうか?
zohnam

2017/07/26 12:35

ajax送信のほうが制限が少なくて便利だと断言できますけど、既存システムとの兼ね合いで可能な限りsubmitっぽい動作をしたいのであれば、こんな感じでどうでしょう。 form.addEventListener('submit',function(e){ e.preventDefault(); // FormDataでなんやかや $.ajax({ // 略 success:function(res){ $(document.body).html(res);// 戻ってきたフォーム送信結果HTMLをぶちこむとか… // location.href = res;// URLが戻ってくるからそこに移動するとかね } }); });
xjaPANDA

2017/07/26 16:39

アドバイスありがとうございます。教えていただいたFormDataというのが、まだ一部しかしらないので、何ができて、何ができないのか調べていますが、用途によって、なかり楽な場合もあるので、どんどん使っていきたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問