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

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

ただいまの
回答率

88.63%

file名を変動しながら、ファイルアップロードしたい。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 581

aushijima

score 53

●現在行っていること・できていること
複数画像をアップロードする機能を作成しています。
添付ファイルを追加するボタンを押すと特定のhtmlが追加される(test.insertAdjacentHTML部分)のhtmlが追加されて、その時に出てきた
削除ボタンを押すと削除される所までは、実装できました。

●実現したいこと
DBに登録するためにinput name=fileの所を上から順番に並べて登録したいです。ただ、追加した時には、上から連番になったfileの名前になるのですが、削除を押した時にうまく並んでくれません。

●html部分

    <!-- 画像は、パスで登録する -->
    <div class="attachedFile">
      <!-- クリックしない時は、attachedFileAddPartsは空ファイル -->
      <div class="attachedFileAddParts" id="ui-id-1"></div>
      <!-- クリックした際は、下記のようになる -->
        <!-- ファイルを追加ボタンを押すと追加できる。削除ボタンを押すと消せる -->
        <!-- <div id="cba_commonAttachedFile0" class="attachedFileParts" data-file-count="0"> -->
          <!-- クリックした数をカウントしている(リロードしたら、再度0からスタートで、押して追加数がカウント、削除で消しても連番になる) -->
          <!-- <input type="hidden" name="attachNumber0" value="0"> -->
          <!-- 削除ボタンを押した時ファイル番号は、リセットされて0からスタートする 複数ある時は、消した分番号が若返る 4つあってfile3のものでもそれより前のfile1などを削除したらfile2になる。-->
          <!-- <input type="file" size="30" name="file0" class="inputFile">
          <span class="guide">(25MBまで)</span>
          <a href="javascript:void(0);" class="attachedFileList__delete attachedFileDeleteiconLink">
            <img src="" alt class="icon">
            <span>削除</span>
          </a>
        </div> -->
      <!-- </div> -->
      <div class="attachedFileAddWrapper">
        <!-- 添付ファイルを追加するをクリックした時に、data-file-countとdata-attach-numberが1になる -->
        <!-- 削除した際にdata-file-countの個数が一つ減る -->
        <div id="attachedFileAdd" class="attachedFileAdd" data-file-count="0" data-attach-number="0" >
          <a href="javascript:void(0);" class="fileadd iconLink" onclick="attachFileClick();">
            <img src="" alt="">
            <span>添付ファイルを追加する</span>
          </a>
        </div>

●js部分

// ##############################################
// 添付画像の処理を記載

// ##############################################
// TODO 番号のリセットなどを実装して、DB上で複数登録させる
//カウンターを設定する
var attachcount = 0;
var deletecount = 0;
//ファイルのカウント数を設定する
var filecount = 0;
//添付ファイルのボタンが押された際と削除した際の画像にファイル名を動的に与える為に必要
var attachbox = document.getElementById('attachedFileAdd');
var data_file_count = attachbox.getAttribute('data-file-count');
var data_attach_number = attachbox.getAttribute('data-attach-number');
//添付ファイルを追加するボタン
function attachFileClick(){
  //添付ファイルを追加するを押した回数をカウントアップする
  attachcount++;
  //ファイルのカウント数を追加する
  filecount++;
  var counter = attachcount;
  var test = document.getElementById('ui-id-1');
  console.log('data_file_count:',data_file_count);
  console.log('data_attach_number:',data_attach_number);
  //削除した時は、一つ減って、通常は、プラス
  data_file_count++;
  attachbox.setAttribute('data-file-count',data_file_count);
  // リロードするまでは、保持される(追加したファイルの履歴数)
  data_attach_number++;
  attachbox.setAttribute('data-attach-number',data_attach_number);

  //要素内の、最後の子要素の後ろ
  test.insertAdjacentHTML('beforeend',
              '<div id="cba_commonAttachedFile'+ counter +'"'+'class="attachedFileParts" data-file-count="'+counter +'">'
              +'<input type="file" size="30" name="file' + filecount +'"' +'class="inputFile">'
              +'<span class="guide">(25MBまで)</span>'
              +'<a href="javascript:void(0);" class="attachedFileList__delete attachedFileDeleteiconLink" onclick="deleteFileClick();">'
              +'<img src="" alt class="icon">'
              +'<span>削除</span>'
              +'</a>'
              +'</div>');
}

//添付ファイルを削除するボタン
function deleteFileClick(){
  //削除ボタンをクリックした回数をカウントアップする
  deletecount++;
  data_file_count--;

  var counter = deletecount;
  var test = document.getElementById('cba_commonAttachedFile'+counter);
  test.parentNode.removeChild(test);
  //削除した時は、一つ減って、通常は、プラス
  attachbox.setAttribute('data-file-count',data_file_count);
}
</script>


お手数ですが教えていただければ幸いです。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • x_x

    2018/10/22 16:52

    multiple属性によって一つのinputで複数のファイルを送信することが可能ですが、そうはしないのでしょうか?

    キャンセル

  • m.ts10806

    2018/10/22 16:54

    DBはなにでどうやって接続する想定でしょうか。

    キャンセル

  • aushijima

    2018/10/22 17:11

    すみません。複数のファイルを順番通りに登録することが実現したいことなので、inputでできればそれが一番いいです。

    キャンセル

  • aushijima

    2018/10/22 17:11

    DBは、MySQLを想定しています。

    キャンセル

回答 1

checkベストアンサー

+1

input name=fileはデフォルト値を設定しても無効で任意にユーザーが選択しないと
ファイルは選択できません
それを前提とした質問ということでよろしいですか?

その上で任意の順番にサーバーにデータを送る場合はクロスドメインでなければ
ajaxで順番に送ってあげる必要があると思います。

ただ順番におくる意味があるかといわれると微妙です。
一緒におくって、サーバー側で順番に処理すればいいような気がします

 単純パターン

  • send.html
<form id="f1" action="recv.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="group_no" value="10005">
<input type="file" name="f[]"><br>
<input type="file" name="f[]"><br>
<input type="file" name="f[]"><br>
<input type="submit" value="go">
</form>
  • recv.php
<?PHP
$group_no=filter_input(INPUT_POST,"group_no");
$uploads_dir = '/uploads';
if(count($_FILES)>0){
  foreach($_FILES["f"]["tmp_name"] as $key=>$tmp_name){
    if($_FILES["f"]["error"][$key]>0) continue;
    $up=$uploads_dir."/".$group_no.($key+1);
    echo "move_uploaded_file('$tmp_name','$up');\n";
   //move_uploaded_file($tmp_name, $up); //実際にはこちらを利用
  }
}
?>

 画面遷移しない

  • send.html
<script>
$(function(){
  $('#f1').on('submit',function(e){
    e.preventDefault();
    var fd=new FormData($(this).get(0));
    $.ajax({
      "url":$(this).attr('action'),
      "type":"post",
      "data":fd,
      "cache":false,
      "processData": false,
      "contentType": false,
    }).done(function(data){
      console.log(data);
    });
  });
});
</script>
<form id="f1" action="recv.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="group_no" value="10005">
<input type="file" name="f[]"><br>
<input type="file" name="f[]"><br>
<input type="file" name="f[]"><br>
<input type="submit" value="go">
</form>

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/23 13:47

    ありがとうございます。参考にしてみます。ちなみにセキュリティ的には、どのような対策をすれば良いのでしょうか?

    キャンセル

  • 2018/10/23 13:58

    >セキュリティ

    今回のケースですと
    <input type="hidden" name="group_no" value="10005">
    のvalueを書き換えられるとアップロード先をぐちゃぐちゃにされるケースがあります。
    $group_noから「..」とか「/」をサニタイズする必要があるでしょう

    またすでにファイルが存在する場合どうするかとか、削除をどうするかなど
    運用面で決めなくてはいけない仕様も多々ありそうです

    キャンセル

  • 2018/10/23 15:38

    色々と教えていただきありがとうございます。検討してみます。

    キャンセル

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

  • ただいまの回答率 88.63%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る