機能説明

ストレージサービスへのファイルのアップロードを行います。

  • アップロードするファイルの選択方法は以下の通りです。
    • 「ファイル選択」ボタンをクリックし、ファイル選択ダイアログからファイルを選択する
    • 指定するパラメータ、機種、OSによって、カメラで撮影した画像ファイルを送信することもできます。
  • 提供する機能は以下の通りです。
    • 選択したファイルを個別にアップロード
    • 選択したファイルの一括アップロード
    • アップロードしたファイルの削除
    • 自動アップロード
      • ファイルを選択すると同時に、自動的にファイルをアップロードします。
  • このタグはスマートフォン用の画面向けにデザインされています。
  • ご利用の機器のOS、OSのバージョンによってアップロードできるファイルが制限されます。
    • iOS
      • iOS5以前
        • ファイルをアップロードできません。
      • iOS6
        • ファイルをアップロードすることができます。
        • アップロード可能なファイルは、画像または動画の2種類です。
        • 画像ファイルは、ファイル名が image.jpg に固定されています。
        • multiple属性をtrueにすると、複数ファイルを選択可能です。ただし、上記の通りファイル名はすべて image.jpg になるのでファイル名の扱いに注意してください。
        • Media Captureに対応していないため、capture属性に値を指定しても無視されます。
    • Android
      • Android2.1以前
        • ファイルをアップロードできません。
      • Android2.2以降
        • ファイルをアップロードすることができます。
        • multiple属性をtrueにしても、複数ファイルを選択することはできません。
        • File APIに対応していないため、ファイルサイズやMime-Typeを取得することができません。
        • Media Captureに対応していないため、capture属性に値を指定しても無視されます。
      • Android4以降
        • ファイルをアップロードすることができます。
        • multiple属性をtrueにしても、複数ファイルを選択することはできません。
        • File APIに対応しているため、ファイルサイズやMime-Typeを取得することができます。
        • Media Captureに対応しているため、capture属性に値を指定するとアップロードするファイルを制御できます。
  • このタグは不可視な iframe へデータを送信し、非同期でファイルをアップロードする方法を利用します。
  • このため、formタグのaction属性に指定したURLへ画面遷移しません。
  • 画面遷移したい場合はコールバック関数を定義し、定義した関数の中で画面遷移を行う必要があります。
  • 動作を確認しているのは、iOS6(iPhone4, iPhone4S, iPhone5), Android(Galaxy SII, Galaxy SIII, Galaxy Note)のみです。
  • アプリケーションサーバの設定によって、アップロード可能なファイルサイズが制限されます。
  • このタグや、ほかの方法でアップロードされているHTMLファイルをダウンロードする機能を提供すると、ダウンロードするファイルにテーマが適用され、想定したファイルがダウンロードできない場合があります。

属性一覧

  • ファイルをアップロードするには、ファイルの保存先を指定する必要があります。以下の3つの保存先を示す属性のうちいずれか1つだけを指定してください。
    • storeTo
    • url
    • outerFormId
  • 複数指定してしまった場合、これらの値の優先度は以下のようになります。例えば、outerFormIdとurlを同時に指定した場合、outerFormIdの値が利用され、urlに指定した値は無視されます。
    • 優先度高
      1. outerFormId
      2. url
      3. storeTo
    • 優先度低
注釈 属性名 説明 省略時の動作
acceptMimeType string アップロードを許可するMime-Type -
Boolean属性 autoUpload boolean ファイル選択後に自動的にアップロードするかどうかのフラグ false
capture string Media Capture APIのcapture属性 -
containerId string ファイル一覧を追加する対象のid
詳細は ファイル一覧をカスタマイズする を参照してください
-
無害化 converter string ファイル情報を変換する関数名
詳細は ファイル一覧をカスタマイズする を参照してください
-
deleteItemTemplateId string enableDelete が true の場合に利用される、ファイル一覧の項目のテンプレートを示すid
詳細は ファイル一覧をカスタマイズする を参照してください
-
editItemTemplateId string fileNameEditable が true の場合に利用される、ファイル一覧の項目のテンプレートを示すid
詳細は ファイル一覧をカスタマイズする を参照してください
-
Boolean属性 enableDelete boolean アップロード完了したファイルを削除するボタンを表示するかどうかのフラグ false
Boolean属性 fileNameEditable boolean アップロード前にファイル名を編集するかどうかのフラグ(自動アップロード時は設定不可) false
HTML5
Boolean属性
hidden boolean このタグを非表示にします false
id string 生成されるform要素のid 代替idを付与
imagePath string ファイル選択ボタンの代わりに表示する画像のパス -
itemTemplateId string ファイル一覧の項目のテンプレートを示すid
詳細は ファイル一覧をカスタマイズする を参照してください
-
listTemplateId string ファイル一覧のテンプレートを示すid
詳細は ファイル一覧をカスタマイズする を参照してください
-
maxNumberOfFiles number アップロード可能ファイル数(1以上の数値) 無制限
HTML5
Boolean属性
multiple boolean 複数同時にファイルをアップロードするかどうかのフラグ(true=複数同時、false=単一) false
name string 生成されるform要素のname 代替nameを付与
HTML5
Boolean属性
novalidate boolean 入力されたデータの妥当性を確認しない(true:確認しない、false:確認する) false
無害化 onBeforeSend string アップロード直前に呼び出されるCSJSの関数名 -
無害化 onChange string ファイル選択時に呼び出されるCSJSの関数名 -
無害化 onError string アップロード失敗時に呼び出されるCSJSの関数名 -
無害化 onRemove string アップロードしたファイルのDelete実行時に呼び出されるCSJSの関数名 -
無害化 onSuccess string アップロード成功時に呼び出されるCSJSの関数名 -
無害化 outerFormId string このタグの外側にformがある場合のformタグのid -
Boolean属性 showList boolean ファイル選択後に選択したファイルのリストを表示するかどうかのフラグ(true=表示する、false=表示しない) true
無害化 storeTo string 保存先ディレクトリ(SessionScopeStorageをルートとした相対パスを指定する) -
無害化 url string 保存先URL(urlとstoreToが同時に指定された場合、urlを優先する) -
無害化 その他 string ユーザ定義属性(生成されるinput type=“file”タグの属性として出力される) -

サンプル

アップロードするファイルの保存先をstoreToで指定する

アップロードするファイルの保存先をstoreToで指定する
storeToで指定する
  • アップロードしたファイルは、SessionScopeStorageをルートとしたstoreToに指定した相対パスのフォルダに格納されます。
  • Identifier#get を利用した一意の文字列をファイル名として SessionScopeStorage に格納します。
  • 下記の例のように、storeTo=“foo/bar”と指定し、baz.txtをアップロードした場合、SessionScopeStorage(‘foo/bar/xxxxxxxxxxxxxxx’)として扱うことになります。
  • アップロードしたファイルはユーザのセッションが切れる時点で削除されるので、恒久的に保存したい場合はアップロードしたファイルをPublicStorageへ移動する必要があります。
  • コールバック関数にファイル名が引き渡されるので、その値を利用して移動することになるでしょう。
    • クライアントから送信されたファイル名は、name プロパティに格納されます。
    • SessionScopeStorage に格納したファイル名は、physicalName プロパティに格納されます。
ファイル名の取得方法
  • アップロード成功時のコールバック関数でファイルの情報を取得します。
  • コールバック関数内で、ファイル名を data.files[i].name, data.result[i].nameの2通りで取得しています。
  • クライアントサイドだけで処理が完結する場合は data.files[i].nameとしてファイル名を扱っても問題ありません。
  • しかし、取得したファイル名をサーバに送信する場合問題が発生することがあります。
  • クライアントが Mac、サーバが Mac以外のOSの場合が該当します。
  • サーバへ情報を送信する場合data.resultに格納されている、サーバから送信されたファイル名を使用するようにしてください。
HTML
<div data-role="page" data-theme="a">
    <script>
        function callbackChange(data) {
            //選択した情報
            var files = data.files;
            for (var i = 0; i < files.length; i++) {
                var file = data.files[i];
                var fileName = file.name;
                var fileSize = file.size;
                var fileType = file.type;
            }
            //doSomething
        }
        function callbackSuccess(data) {
            //送信した情報
            for (var i = 0; i < data.files.length; i++) {
                var file = data.files[i];
                var fileName = file.name;
                var fileSize = file.size;
                var fileType = file.type;
            }
            //受信した情報
            var storeTo = [];
            var name = [];
            var physicalName = [];
            for (var i = 0; i < data.result.length; i++) {
                var receiveFile = data.result[i];
                var receiveFileName = receiveFile.name;
                var receivePhysicalFileName = receiveFile.physicalName;
                var receiveFileSize = receiveFile.size;
                //var fileType = receiveFile.type; //受信した情報には含まれません。

                storeTo.push('foo/bar');
                name.push(receiveFileName);
                physicalName.push(receivePhysicalFileName);
            }
            //ファイルコピーのためのリクエストを送信する
            $.ajax({
                url: 'sample/copyfile',
                data: {
                    storeTo: storeTo,
                    name: name,
                    physicalName: physicalName
                },
                method: 'POST',
                traditional: true
            });
        }
        function callbackError(data) {
            for (var i = 0; i < data.files.length; i++) {
                var file = data.files[i];
                var fileName = file.name;
                var fileSize = file.size;
                var fileType = file.type;
            }
            //doSomething
        }
    </script>
    <imart type="spFileUpload" id="storeTo" storeTo="foo/bar" onChange="callbackChange" onSuccess="callbackSuccess" onError="callbackError"/>
</div>
routing-jssp-config/sample.xml
<?xml version="1.0" encoding="UTF-8"?>
<routing-jssp-config xmlns="http://www.intra-mart.jp/router/routing-jssp-config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.intra-mart.jp/router/routing-jssp-config routing-jssp-config.xsd ">

  <!-- サンプル向けの設定です。アクセス権の設定を行ってください。 -->
  <authz-default mapper="welcome-all" />

  <!-- コピー処理 -->
  <file-mapping path="sample/copyfile" page="sample/copyfile" />

</routing-jssp-config>
サーバサイド JavaScript(sample/copyfile.js)
function init(request) {
    var response = Web.getHTTPResponse();
    response.setContentType('application/json; charset=utf-8');
    try {
        var dir = request.storeTo;
        var physicalNames = request.getParameters('physicalName');
        var logicalNames = request.getParameters('name');

        // 保存先の作成
        var storedDirectory = new PublicStorage(dir);
        storedDirectory.makeDirectories();

        // ファイルデータの移動
        for (var i = 0, len = physicalNames.length; i < len; i++) {
            var physicalName = physicalNames[i].getValue();
            var logicalName = logicalNames[i].getValue();

            var sessionScopeFile = new SessionScopeStorage(dir, physicalName);
            sessionScopeFile.openAsBinary(function(reader) {
                var storage = new PublicStorage(dir, logicalName);
                storage.createAsBinary(function(writer, err) {
                    if (err) {
                        response.sendMessageBodyString(ImJson.toJSONString([{
                            "error":err.message
                        }]));
                    }
                    reader.transferTo(writer);
                });
            });
        };
        // 正常値の返却
        response.sendMessageBodyString(ImJson.toJSONString([{
            error: false
        }]));
    } catch(e) {
        Debug.console(e);
        // エラー情報の返却
        response.sendMessageBodyString(ImJson.toJSONString([{
            "error":e.message
        }]));
    }
}

アップロードするファイルの保存先をurlで指定する

アップロードするファイルの保存先をurlで指定する
urlで指定する
  • urlにデータ送信先のURLを指定します。
  • 送信するファイルデータの名前は、local_fileです。request.getParameter(‘local_file’)とすると取得できます。
  • データ送信先のプログラムではこのタグが正常に動作するようなレスポンスを返す必要があります。
  • レスポンスのContent-Typeは‘application/json’を指定してください。
  • レスポンスはJSONとして返します。
  • 返すのは、ファイル名、ファイルサイズをプロパティとしたオブジェクトです。
HTML
<div data-role="page" data-theme="a">
    <imart type="spFileUpload" url="sample/filereceiver"/>
</div>
routing-jssp-config/sample.xml
<?xml version="1.0" encoding="UTF-8"?>
<routing-jssp-config xmlns="http://www.intra-mart.jp/router/routing-jssp-config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.intra-mart.jp/router/routing-jssp-config routing-jssp-config.xsd ">

  <!-- サンプル向けの設定です。アクセス権の設定を行ってください。 -->
  <authz-default mapper="welcome-all" />

  <!-- アップロード処理 -->
  <file-mapping path="sample/filereceiver" page="sample/filereceiver" />

</routing-jssp-config>
サーバサイド JavaScript(sample/filereceiver.js)
function init(request) {
    var cryption = new Packages.jp.co.intra_mart.system.imtag.SecureParameterCryption();
    var response = Web.getHTTPResponse();
    response.setContentType('application/json; charset=utf-8');

    try {
        // 保存先の作成
        var dir = 'upload';
        var storedDirectory = new PublicStorage(dir);
        storedDirectory.makeDirectories();
        // ファイルデータの保存
        var upfile = request.getParameter("local_file");
        upfile.openValueAsBinary(function(reader) {
            var storage = new PublicStorage(dir, upfile.getFileName());
            storage.createAsBinary(function(writer, err) {
                if (err) {
                    response.sendMessageBodyString(ImJson.toJSONString([{
                        "error":err.message
                    }]));
                }
                reader.transferTo(writer);
            });
        });
        // 保存したファイルデータの取得
        var storedFile = new PublicStorage(dir, upfile.getFileName());
        var storedFileSize = storedFile.length();
        if (storedFileSize == null) {
            response.sendMessageBodyString(ImJson.toJSONString([{
                "error":'Failed to get stored file size.'
            }]));
        }
        // 正常値の返却
        response.sendMessageBodyString(ImJson.toJSONString([{
            "name":upfile.getFileName(),
            "size":storedFileSize
        }]));
    } catch(e) {
        Debug.console(e);
        // エラー情報の返却
        response.sendMessageBodyString(ImJson.toJSONString([{
            "error":e.message
        }]));
    }
}

アップロードするファイルの保存先をouterFormIdで指定する

アップロードするファイルの保存先をouterFormIdで指定する
outerFormIdで指定する
  • ファイルだけでなく、他の項目も同時にサーバに送信したい場合、この属性を指定します。
  • このとき、imartタグを囲むようにformタグを記述します。formタグにはidとencTypeを指定する必要があります。
  • <imart type=“spFileUpload”>を囲むformタグのidを、<imart type=“spFileUpload”>タグのouterFormId属性に指定します。
  • また、formタグのenctype属性にmultipart/form-dataを、data-ajax属性にfalseを、method属性にPOSTを指定します。
HTML
<div data-role="page" data-theme="a">
    <form id="outerform" name="outerForm" action="sample/filereceiver" method="POST" enctype="multipart/form-data" data-ajax="false">
        <imart type="spFileUpload" outerFormId="outerform"/>
        <input type="hidden" name="param1" value="value1"/>
        <input type="hidden" name="param2" value="value2"/>
        <input type="hidden" name="param3" value="value3"/>
    </form>
</div>

アップロードしたファイルを削除する

アップロードしたファイルを削除する
  • アップロードしたファイルを削除するボタンを表示します。
    • 削除機能は、アップロードしたファイルを対象にした機能です。
    • ×アイコンが表示されているファイル一覧の項目をクリックすると、対象のファイルを削除します。
  • ファイルのアップロード成功時に削除用のURLをレスポンスに指定します。
  • アップロードしたファイルごとに設置されているゴミ箱アイコンを押下すると設定したURLにリクエストを送信します。
  • 送信先のプログラムで削除処理を行います。
HTML
<div data-role="page" data-theme="a">
    <imart type="spFileUpload" enableDelete url="sample/filereceiver" />
</div>
routing-jssp-config/sample.xml
<?xml version="1.0" encoding="UTF-8"?>
<routing-jssp-config xmlns="http://www.intra-mart.jp/router/routing-jssp-config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.intra-mart.jp/router/routing-jssp-config routing-jssp-config.xsd ">

  <!-- サンプル向けの設定です。アクセス権の設定を行ってください。 -->
  <authz-default mapper="welcome-all" />

  <!-- アップロード処理 -->
  <file-mapping path="sample/filereceiver" page="sample/filereceiver" />
  <!-- 削除処理 -->
  <file-mapping path="sample/fileremover/{delete}" page="sample/fileremover" />

</routing-jssp-config>

サーバサイド JavaScript(アップロード処理 : sample/filereceiver)
function init(request) {
    var cryption = new Packages.jp.co.intra_mart.system.imtag.SecureParameterCryption();
    var response = Web.getHTTPResponse();
    response.setContentType('application/json; charset=utf-8');

    try {

        // 保存処理・・・

        // 正常値の返却(deleteUrl に削除先のURLを設定する)
        response.sendMessageBodyString(ImJson.toJSONString([{
            "name":upfile.getFileName(),
            "size":storedFileSize,
            "deleteUrl":'sample/fileremover/' + URL.encode(cryption.encrypt(storedFile.getCanonicalPath()),"UTF-8"),
            "deleteType":'POST'
        }]));
    } catch(e) {
        // エラー情報の返却
        response.sendMessageBodyString(ImJson.toJSONString([{
            "error":e.message
        }]));
    }
}
サーバサイド JavaScript(削除処理 : sample/fileremover)
function init(request) {
    var cryption = new Packages.jp.co.intra_mart.system.imtag.SecureParameterCryption();
    var response = Web.getHTTPResponse();
    response.setContentType('application/json; charset=utf-8');

    try {
        //削除ファイルの決定
        var deleteFileParam = request.getParameter("delete");
        if (deleteFileParam == undefined) {
            response.sendMessageBodyString(ImJson.toJSONString([{
                "error":'delete file is not defined.'
            }]));
        }
        //ファイルの削除
        var deleteFile = new PublicStorage(URL.decode(cryption.decrypt(deleteFileParam.getValue()), "UTF-8"));
        if (deleteFile.exists()) {
            deleteFile.remove();
        }else {
            response.sendMessageBodyString(ImJson.toJSONString([{
                "error":'delete file does not exist.',
                "filePath":deleteFile.getCanonicalPath()
            }]));
        }
        //正常値の返却
        response.sendMessageBodyString(ImJson.toJSONString([{
            "name":deleteFile.getName()
        }]));
    } catch(e) {
        //エラー情報の返却
        response.sendMessageBodyString(ImJson.toJSONString([{
            "error":e.message
        }]));
    }
}

アップロード可能なファイルを制限する

  • アップロードを許可するMIME-Typeを指定します。
  • OS、機種によって、認識するMIME-Typeが異なります。
    • iOSではimage/*, video/* を認識します。
    • Android 2.3 では何を指定しても有効になりません。
    • Android 4.0 では image/*, video/* などを認識します。
HTML
<div data-role="page" data-theme="a">
    <imart type="spFileUpload" acceptMimeType="image/*" storeTo="/upload" />
</div>

ファイル選択と同時にファイルをアップロードする

ファイル選択と同時にファイルをアップロードする
  • ファイル選択後に自動的にアップロードします。
  • 「開始」ボタンが表示されません。
HTML
<div data-role="page" data-theme="a">
    <imart type="spFileUpload" storeTo="/upload" autoUpload />
</div>

アップロード前にファイル名を変更する

アップロード前にファイル名を変更する
  • アップロード前にファイル名を編集可能にします。
  • autoUploadがtrueの場合は無効になります。
HTML
<imart type="spFileUpload" storeTo="/upload" fileNameEditable />

ファイル一覧をカスタマイズする

ファイル一覧をカスタマイズする
ファイル一覧をカスタマイズすることができます。
ファイル一覧は
  • container
    • list
      • item
のように構成されています。それぞれを指定することで任意の位置に任意のマークアップで一覧を表示することができます。このサンプルでは、以下のようなカスタマイズを行います。
  • ファイルアップロードボタンの下に配置した div にファイル一覧を表示する
    • container=“container” を指定する
  • ファイル一覧の data-theme を b とする
    • listTemplateId=“listTemplate” を指定する
  • ファイル一覧の項目に、ファイルサイズと更新日を表示する
    • itemTemplateId=“itemTemplate” を指定する
  • ファイルサイズ、更新日は生データではなく、適切に変換した値を表示する
    • converter=“converter” を指定する
テンプレートの変換はjQuery Template pluginを利用しています。テンプレートの書き方についてはリンク先を参照してください。パラメータとして渡される値は
param = {
name: [string]ファイル名,
size: [number]ファイルサイズ,
type: [string]mime-type,
index: [number]アップロードするファイルのインデックス,
lastModifiedDate: [Date]更新日付,
}
です。
HTML
<div data-role="page" data-theme="a">
    <!--list のテンプレート-->
    <script id="listTemplate" type="text/x-jquery-tmpl">
        <ul data-role="listview" data-theme="b" data-inset="true"></ul>
    </script>
    <!--item のテンプレート-->
    <script id="itemTemplate" type="text/x-jquery-tmpl">
        <li>
        <a href="#">
            <h3 class="ui-li-heading">${name}</h3>
            <div class="ui-li-aside ui-li-desc">
                <div>${size}bytes</div>
                <div>${lastModifiedDate}</div>
            </div>
        </a>
        </li>
    </script>
    <!--item に表示するファイル情報を変換する関数-->
    <script>
        /*
         * file = {
         *     name: [string]'ファイル名',
         *     size: [number]'ファイルサイズ',
         *     type: [string]'mime-type',
         *     lastModifiedDate: [Date]'変更日'
         * }
         */
        function converter(file) {
            var getDateString = function(date) {
                if (date) {
                    var arr = [];
                    arr.push(date.getFullYear());
                    arr.push(date.getMonth() + 1);
                    arr.push(date.getDate());
                    return arr.join('/');
                } else {
                    return '';
                }
            }
            return result = {
                name: 'Name: ' + file.name,
                size: file.size ? parseInt(file.size / 1024) : '-',
                type: file.type ? file.type : '',
                lastModifiedDate: getDateString(file.lastModifiedDate)
            };
        }
    </script>
    <imart type="spFileUpload" storeTo="/upload" showList="true" containerId="container" listTemplateId="listTemplate" itemTemplateId="itemTemplate" converter="converter"/>

    <!-- container -->
    <div>
        <div id="container"></div>
    </div>
</div>


リセットする

ファイル一覧、form をリセットします。DOM ツリーがキャッシュされている場合、画面遷移をしても、このコンポーネントの情報が残ったままになります。
リセット関数を呼び出すことで、キャッシュされた情報をリセットすることができます。
HTML
<section id="page1" data-role="page" data-theme="a">
    <div class="content" data-role="content">
        <p><a href="#page2">Next</a></p>
    </div>
</section>

<section id="page2" data-role="page" data-theme="a" data-dom-cache="true">
    <div class="content" data-role="content">
        <imart type="spFileUpload" id="file" storeTo="upload"/>
        <a href="#page1">Back</a>
    </div>
</section>

<script>
    (function($) {
        // 呼び出すタイミングは実装の仕方によって検討してください。
        $('#page2').live('pagebeforeshow',function(event){
            // リセットする
            $('#file').imspFileUpload('reset');
        });
    })(jQuery);
</script>

onBeforeSend

onBeforeSend
  • onBeforeSend 属性を用いて、ファイルをアップロードする直前に実行される関数を指定します。
  • 関数が false を返すと、ファイルはアップロードされません。
  • fileNameEditable = true の場合、編集済のファイル名は以下のように取得します。
    • data.files[i].uploadFileName(アップロード時に指定したファイル名)
HTML
<script>
    function callbackBeforeSend(e, data) {
        var file = data.files[0];
        var fileName = file.name;
        var fileSize = file.size;
        var fileType = file.type;
        // fileNameEditable = true の場合、編集済のファイル名を以下のように取得します。
        var uploadFileName = file.uploadFileName;

        if (!/\.jpe?g$/.test(uploadFileName)) {
            // アップロード処理を中止する
            imspShowErrorMessage('アップロードできるのは jpg ファイルだけです。');
            return false;
        }
        // アップロード処理を継続する
        return true;
    }
</script>
<imart type="spFileUpload" storeTo="foo/bar" onBeforeSend="callbackBeforeSend"/>