🥥

FilePondを使ったアップロードフォーム実装(基礎の基礎編)

2023/10/27に公開

経緯

EC CUBE4.2からFilePondを使うように変わっていたんですが、使い方がさっぱりわからなくてあれこれ勉強したことについて書こうと思います。

今回は簡単なHTMLとJSだけで実装する基礎の基礎になります。

FilePondとは

以下、公式Docsより。

FilePond is a JavaScript library that brings silky smooth drag n' drop file uploading.

(日本語訳)
FilePondは、スムーズなドラッグ&ドロップによるファイルアップロードを実現するJavaScriptライブラリです。

https://pqina.nl/filepond/docs/

プラグインを導入するだけで、ドラッグ&ドロップによるファイル選択やファイルのプレビューが可能になります。

実際に触ってみる

それでは早速ですが、ファイルアップロードフォームを表示するコードを書いていきます。

完成すると、こんな画面になります。

Drag & Drop your files or Browseと書かれたフィールドをクリックすると、Finderのウィンドウが表示されます。

ファイルを選択すると、フィールド内にファイル名が書かれたボックスが出てきます。

もしくは、ファイルをDrag & Drop your files or Browseにドラッグ&ドロップすることでもアップロード可能です。

以下、上図と同じ画面を表示するサンプルコードです。

sample1.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>FilePond Sample1 Page</title>

        <link 
            href="https://unpkg.com/filepond/dist/filepond.css"
            rel="stylesheet"
        />
    </head>
    <body>
        <form action="">
            <input type="file" />
            <button type="submit">submit</button>
        </form>
        
        <!-- FilePondをCDNでインストール -->
        <script src="https://unpkg.com/filepond/dist/filepond.js"></script>

        <!-- ファイルアップロード時の処理 -->
        <script type="text/javascript">
            const uploadField = document.querySelector('input[type="file"]');

            FilePond.create(uploadField, {
                storeAsFile: true
            });
        </script>
    </body>
</html>

この例でアップロードできるファイルは1つまでです。

では、上から順にコードを詳しく見ていきます。
まずはheadタグ内のコードです。

<meta charset="UTF-8" />
<title>FilePond Sample1 Page</title>

<link 
    href="https://unpkg.com/filepond/dist/filepond.css"
    rel="stylesheet"
/>

metaタグとtitleタグは、何の変哲もない普通の設定です。
お好みで書き換えてください。

linkタグでは、FilepondのCSSが使えるようにしています。
無くても動かないわけではありませんが、CSSが設定されていないと以下のようにメチャクチャなレイアウトになってしまうので、書いておくほうが無難だと思います。


次にbodyダグ内を見ていきます。
こちらは、formとscriptで分けて説明します。

以下、formタグのコードです。

<form action="">
    <input type="file" />
    <button type="submit">submit</button>
</form>

inputタグのtype属性がfileなので、ファイルアップロードフォームを実装しています。

submitのボタンを設置していますが、今回の例では送信先を実装しないのでボタンを押しても特に何も起こりません。

続いて、scriptタグのコードです。

<!-- FilePondをCDNでインストール -->
<script src="https://unpkg.com/filepond/dist/filepond.js"></script>

<!-- ファイルアップロード時の処理 -->
<script type="text/javascript">
    const uploadField = document.querySelector('input[type="file"]');

    FilePond.create(uploadField, {
        storeAsFile: true
    });
</script>

ここが一番重要です。

まず、1つ目のscriptタグで、CDNを使ってFilepondをインストールしています。

CDNって何?

CDN(Contents Delivery Network)とは、数多くのキャッシュサーバーなどで構成されたプラットフォームを用いることにより、Webサイト上のコンテンツを迅速にエンドユーザーに届けるための仕組みです。

(参照:CDNとは?意味・定義

次に、2つ目のscriptタグの中で、ファイルアップロード時に行うJSでの処理を書いています。

以下のコードで、type属性がfileのinputタグ要素を取得しています。

const uploadField = document.querySelector('input[type="file"]');

その次のコードでFilePond.createという関数が使われています。

FilePond.create(uploadField, { storeAsFile: true });

この関数は、FilePondオブジェクトのインスタンスを作成するものです。
先ほど取得したinputタグ要素が第一引数に渡されています。

第二引数は、FilePondに設定したい項目をオプションで追加する際に利用します。
今回の例では、storeAsFileがtrueに設定されています。

  • storeAsFile
    trueにしておくと、ファイルを隠し、入力要素を保存し、通常のフォームと一緒に投稿可能になる。

FilePond.createの詳細な解説は公式ドキュメントを確認してみてください。

https://pqina.nl/filepond/docs/api/exports/#create

このようにFilePondオブジェクトのインスタンスを作成することで、
フォームがFilePond仕様になります。

このコードをコメントアウトしてみると、以下のように
普通のファイルアップロードフォームが表示されるようになります。


これでコードの解説は以上です。

設定項目を増やしてみる

ここからは、sample1.htmlのコードを改良したものをいくつか紹介していきます。

まずは、複数のファイルをアップロードできるように改良してみましょう。

コードはこんな感じになります。

sample2.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>FilePond Sample2 Page</title>

        <link 
            href="https://unpkg.com/filepond/dist/filepond.css"
            rel="stylesheet"
        />
    </head>
    <body>
        <form action="">
            <input type="file" />
            <button type="submit">submit</button>
        </form>
        
        <script src="https://unpkg.com/filepond/dist/filepond.js"></script>
        <script type="text/javascript">
            const uploadField = document.querySelector('input[type="file"]');

            // 第二引数のオプションを追加
            var pond = FilePond.create(uploadField, {
                storeAsFile: true,
                allowMultiple: true,
                maxFiles: 2,
            });
        </script>
    </body>
</html>

ほとんど同じですが、1箇所だけ変更があります。

// 第二引数のオプションを追加
var pond = FilePond.create(uploadField, {
    storeAsFile: true,
    allowMultiple: true,
    maxFiles: 2,
});

ここですね。

FilePondのインスタンスを作るメソッドの、第二引数のオプションが2つほど増えています。

  • allowMultiple
    複数ファイルの追加を有効または無効にする。trueなら有効、falseなら無効。

  • maxFiles
    アップロード可能なファイルの最大数。nullの場合は無制限。

詳細は以下の公式ドキュメントのページを参照してください。

https://pqina.nl/filepond/docs/api/instance/properties/

ちなみに、allowMultipleをfalseに変更すると、maxFilesにどんな数字が入っていようと複数アップロードは不可能になります。

初期値はfalseなので、もしmaxFilesが2以上なのに複数アップロードが出来ない、といった場合はallowMultipleを設定し忘れていないか確認してください。

プラグインで更に設定項目を増やしてみる

続いて、プラグインを使った改良を行なってみましょう。

以下の2つの機能を追加していきます。

  • アップロードできるファイルタイプの制限
  • アップロード後のファイル名の変更

コードはこんな感じです。

sample3.html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>FilePond Sample3 Page</title>

        <link 
            href="https://unpkg.com/filepond/dist/filepond.css"
            rel="stylesheet"
        />
    </head>
    <body>
        <form action="">
            <input type="file" />
            <button type="submit">submit</button>
        </form>
        
        <!-- プラグインを追加 -->
        <script src="https://unpkg.com/filepond-plugin-file-validate-type/dist/filepond-plugin-file-validate-type.js"></script>
        <script src="https://unpkg.com/filepond-plugin-file-rename/dist/filepond-plugin-file-rename.js"></script>

        <script src="https://unpkg.com/filepond/dist/filepond.js"></script>
        <script type="text/javascript">
            // プラグインを登録
            FilePond.registerPlugin(FilePondPluginFileValidateType);
            FilePond.registerPlugin(FilePondPluginFileRename);

            const uploadField = document.querySelector('input[type="file"]');

            // オプションを設定する
            FilePond.setOptions({
                fileRenameFunction: (file) => {
                    return `my_new_name${file.extension}`;
                },
            });

            // 第二引数のオプションをさらに追加
            var pond = FilePond.create(uploadField, {
                storeAsFile: true,
                allowMultiple: true,
                maxFiles: 2,
                allowRemove: false,
                acceptedFileTypes: [
                    'image/gif',
                    'image/png',
                    'image/jpeg'
                ],
            });
        </script>
    </body>
</html>

まずはプラグイン追加のコードから見ていきます。

<!-- プラグインを追加 -->
<script src="https://unpkg.com/filepond-plugin-file-validate-type/dist/filepond-plugin-file-validate-type.js"></script>
<script src="https://unpkg.com/filepond-plugin-file-rename/dist/filepond-plugin-file-rename.js"></script>

上はFile Type Validationプラグインで、誤ったタイプのファイルをブロックする機能です。

例えば、.pngしかアップロードできないフォームに.htmlのファイルをアップロードしようとしたら、そのファイルをブロックしてアップロードさせません。

下はFile Renameプラグインで、アップロードされたファイルをFilePondに追加する前にファイル名の変更ができるようになります。

例えば、sample1.htmlがアップロードされた時、プログラムでsample1_20231025.htmlのように任意の名前に変更することができます。

インストールしたプラグインは、以下のコードでFilePondオブジェクトに登録されます。

// プラグインを登録
FilePond.registerPlugin(FilePondPluginFileValidateType);
FilePond.registerPlugin(FilePondPluginFileRename);


次に、これらのプラグインを実際に使ってる部分を説明していきます。

まずは、アップロード時のファイル名の変更を設定していきます。

以下のコードでは、FilePondのsetOptionsメソッドでオプションの設定を行っています。

// オプションを設定する
FilePond.setOptions({
    fileRenameFunction: (file) => {
        return `my_new_name${file.extension}`;
    },
});

fileRenameFunctionは、File Renameプラグインのインストールによって利用可能になるプロパティです。

このプロパティの値として作成された関数では、引数fileに、アップロードされたファイル情報が渡されます。

このfileのプロパティであるextensionは、ファイルの拡張子が格納されており、任意の文字列と繋げることで新しいファイル名を生成しています。

これで、ファイルアップロード時に勝手にmy_new_nameという名前に変更してくれるようになりました。


続いてアップロード可能なファイルタイプの制限を設定していきます。

以下は、FilePondのインスタンスを生成している部分です。

// 第二引数のオプションをさらに追加
var pond = FilePond.create(uploadField, {
    storeAsFile: true,
    allowMultiple: true,
    maxFiles: 2,
    acceptedFileTypes: [
        'image/gif',
        'image/png',
        'image/jpeg'
    ],
});

sample2.htmlのコードから、さらに1つほどオプションが増えています。

  • acceptedFileTypes
    使用可能なファイルタイプの配列。MIMEタイプかワイルドカードを指定する。
    File Type Validationプラグインによって追加できるようになる。

詳細は以下の公式ドキュメントのページを参照してください。

https://pqina.nl/filepond/docs/api/plugins/file-validate-type/#properties

MIMEタイプ・ワイルドカードって?
  • MIMEタイプの例
    ['image/png']:pngのみを受け付ける

  • ワイルドカードの例
    ['image/*']:すべての画像を受け付ける

今回の例だと、git, png, jpegだけを受け付けるように設定している、ということです。

上記以外のファイルをアップロードしようとしても、失敗するはずです。

最後に

FilePond、初めてみた時は「なんじゃこいつ・・」って感じだったんですが、ちゃんと勉強したら意外と難しくなかったです。

次回はphpも組み合わせたより実践的なサンプルコードを使って記事にまとめていこうと思います。(サンプルコードまだできてないですが・・)

Discussion