複数ファイルアップロード

単一ファイルアップロードと複数ファイルアップロードをひとつの自作クラス<fileControl>に。ゆくゆくはダウンロードやas3対応も仕込みたいところ。

下記サンプルでは、上が単一アップロードで、下が複数アップロードです。複数アップロードするには、選択ポップアップ画面でSHIFTキー(or CTRLキー)押しながらファイルをクリックしていくと複数ファイル選べます。

この内容を表示するためには Adobe Flash Plugin が必要です。
(OpenLaszlo4.6.1/swf8)

アップロードお試し用画像
90x68_a.jpg 90x68_b.jpg 90x68_c.jpg 90x68_d.jpg 90x68_e.jpg 90x68_f.jpg

■クラスの仕様

属性名意味デフォルト
isMultiアップロードファイルが単一か複数か。true(複数)/false(単一)false
uploadURLサーバサイドのアップロードプログラムURLなし
fileTypeファイル選択ポップアップで選択できる「ファイル名+拡張子」ファイル名.拡張子*.*
maxsizeアップロード可能な上限サイズ。単位はバイト。数値。200000
maxfiles複数同時にアップロード可能なファイル数。数値。6

アップロードが終わるとonfinishイベントが飛びます。

<?xml version="1.0" encoding="UTF-8"?>
<canvas proxied="false" bgcolor="0xeeeeee">
 
  <class name="fileControl" extends="hbox">
 
    <!--アップロードファイルが単一か複数か-->
    <attribute name="isMulti" type="boolean" value="false"/>
 
    <!--サーバサイドのアップロードプログラム-->
    <attribute name="uploadURL" type="string"/>
 
    <!--ファイル選択ポップアップで選択できる「ファイル名+拡張子」-->
    <attribute name="fileType" type="string" value="*.*"/>
 
    <!--アップロード可能上限サイズ(バイト) -->
    <attribute name="maxSize" value="200000" type="number"/>
 
    <!--複数同時にアップロード可能なファイル数-->
    <attribute name="maxFiles" value="6" type="number"/>
 
    <!--アップロード終了を知らせるイベント-->
    <event name="onfinish"/>
 
 
    <!--内部コード-->
    <attribute name="fr" /><!--単一ファイル-->
    <attribute name="frl" /><!--複数ファイル-->
    <attribute name="FR" /><!--複数ファイル一時-->
    <attribute name="sum" type="number" value="0"/>
    <handler name="oninit" args="listener"><![CDATA[
      if(this.isMulti){
        this.setAttribute('frl',new flash.net.FileReferenceList());
        this.frl.addListener(listener);
      }
      this.setAttribute('fr',new flash.net.FileReference());
      this.fr.addListener(listener);
 
      listener.onComplete = function(file) {
        this.progressBar.setValue(100);
        this.clear();
        if(this.isMulti){
          if(this.sum==1 ){
            this.onfinish.sendEvent();
          }else{
            this.setAttribute('sum',this.sum-1);
          }
        }else{
          this.onfinish.sendEvent();
        }
      }
 
      listener.onProgress = function(file, bytesLoaded, bytesTotal) {
        this.progressBar.setValue(bytesLoaded * 100 / bytesTotal);
      }
 
      listener.onSelect = function(file) {
        this.setAttribute('FR',file);
        this.filenames.setAttribute('value',"");
        var isOK = "true"; //ファイルサイズ・ファイル数チェックの合否フラグ
        if(this.isMulti){
          isAllComplete = false;
          var list = file.fileList;
          var filenames = "";
 
          //ファイル数のチェック
          if(list.length > this.maxFiles){
            this.filenames.setAttribute('text',"上限は"+this.maxFiles+"ファイルです");
            this.clear();
            isOK="false";
          }
 
          if(isOK=="true"){
            var item = new flash.net.FileReference();
            this.setAttribute('sum',list.length);
            for(var i=0;i<list.length;i++){
              isOK="true";
              item = list[i];
              Debug.write("name: " + item.name,item.addListener(this));  //★この行がないとonComplete発生しない
 
              //ファイルサイズのチェック
              if(item.size > this.maxSize){
                filenames = filenames + "上限は"+this.maxSize+"バイトです\n";
                this.clear();
                isOK="false";
                list[i]="";
              }
 
              if(isOK=="true")filenames = filenames + item.name + "\n";
            }
            this.filenames.setAttribute('text',filenames);
          }
        }else{
          this.filename.setAttribute('text',this.fr.name);
 
          //ファイルサイズのチェック
          if(this.fr.size>this.maxSize){
            this.filename.setAttribute('text',"上限は"+this.maxSize+"バイトです");
            this.clear();
            isOK="false";
          }
        }
        if(isOK=="true"){
          this.upload.setAttribute('enabled',true);
          this.cancel.setAttribute('enabled',true);
          this.progressBar.reset();
        }
      }
    ]]></handler>
 
    <!--ブラウズメソッド-->
    <method name="browse">
      var a = new Array(); //決まり文句
      var f = new Object(); //決まり文句
      f.description = this.fileType; // 表示文字列:動作に影響ない
      f.extension = this.fileType; // 拡張子。ここで指定した拡張子しか選べなくなる
      a.push(f);  //決まり文句
      if(!isMulti){
        this.fr.browse(a); //決まり文句
      }else{
        this.frl.browse(a); //決まり文句
      }
    </method>
 
    <!--ボタンディセーブルメソッド-->
    <method name="clear">
      this.upload.setAttribute('enabled',false);
      this.cancel.setAttribute('enabled',false);
    </method>
 
    <!--ファイル名表示欄(単一)-->
    <edittext name="filename" width="150" enabled="false" visible="${!parent.isMulti}"/>
 
    <!--ファイル名表示欄(複数)-->
    <edittext name="filenames" width="150" height="90" enabled="false" visible="${parent.isMulti}" multiline="true"/>
 
    <!--プログレスバー(単一専用)-->
    <view name="progressBar" opacity="0.1" options="ignorelayout" x="2" y="2" width="${parent.filename.width}" height="22" >
      <view name="status" height="22" bgcolor="#0000FF"/>
      <method name="setValue" args="v">
        this.status.setAttribute('width', v * (parent.filename.width-4) / 100);
        if(v!=0){
          if(v==100){
            parent.upload.setAttribute('text',"100%完了");
          }else{
            parent.upload.setAttribute('text',Math.round(v) + "%完了");
          }
        }else{
          parent.upload.setAttribute('text',"アップロード");
        }
      </method>
      <method name="reset">
        this.setValue(0);
      </method>
    </view>
 
    <!--参照ボタン-->
    <button text="参照" >
      <handler name="onclick">
        parent.browse();
      </handler>
    </button>
 
    <!--取消ボタン-->
    <button name="cancel" text="取消" enabled="false">
      <handler name="onclick">
        parent.filename.setAttribute('text',"");
        parent.filename.setAttribute('value',"");
        parent.filenames.setAttribute('text',"");
        parent.filenames.setAttribute('value',"");
        parent.clear();
      </handler>
    </button>
 
    <!--アップロード(進捗表示)ボタン-->
    <button name="upload" text="アップロード" enabled="false">
      <handler name="onclick"><![CDATA[
        if(parent.isMulti){
          var list = parent.FR.fileList;
          var item = new flash.net.FileReference();
          for(var i=0;i<list.length;i++){
            item = list[i];
            item.upload(parent.uploadURL,"Filedata" + i);
          }
        }else{
          parent.fr.upload(parent.uploadURL);
        }
        parent.clear();
      ]]></handler>
    </button>
  </class>
 
  <simplelayout spacing="30"/>
 
  <!--インスタンス1-->
  <vbox height="150">
    <fileControl uploadURL="./uploadJPG.php" fileType="*.jpg">
      <handler name="onfinish">
          var t = new Date().getTime().toString();
          showimg1.setAttribute('src',"http:upload/uploadfile.jpg?t=" + t);
      </handler>
    </fileControl>
    <image id="showimg1" src="http:upload/uploadfile.jpg" width="150" height="100" stretches="both"/>
  </vbox>
 
  <!--インスタンス2-->
  <vbox>
    <fileControl uploadURL="./uploadFILES.php" fileType="*.jpg" isMulti="true">
      <handler name="onfinish">
        Debug.write("onfinish");
        var t = new Date().getTime().toString();
        showimg2a.setAttribute('src',"http:upload/uploadfile_a.jpg?t=" + t);
        showimg2b.setAttribute('src',"http:upload/uploadfile_b.jpg?t=" + t);
        showimg2c.setAttribute('src',"http:upload/uploadfile_c.jpg?t=" + t);
        showimg2d.setAttribute('src',"http:upload/uploadfile_d.jpg?t=" + t);
        showimg2e.setAttribute('src',"http:upload/uploadfile_e.jpg?t=" + t);
        showimg2f.setAttribute('src',"http:upload/uploadfile_f.jpg?t=" + t);
      </handler>
    </fileControl>
    <hbox spacing="1">
      <image id="showimg2a" src="http:upload/uploadfile_a.jpg" width="90" height="60" stretches="both"/>
      <image id="showimg2b" src="http:upload/uploadfile_b.jpg" width="90" height="60" stretches="both"/>
      <image id="showimg2c" src="http:upload/uploadfile_c.jpg" width="90" height="60" stretches="both"/>
      <image id="showimg2d" src="http:upload/uploadfile_d.jpg" width="90" height="60" stretches="both"/>
      <image id="showimg2e" src="http:upload/uploadfile_e.jpg" width="90" height="60" stretches="both"/>
      <image id="showimg2f" src="http:upload/uploadfile_f.jpg" width="90" height="60" stretches="both"/>
    </hbox>
  </vbox>
</canvas>

■uploadFILES.php

<?php
$uploaddir = './upload/';
move_uploaded_file($_FILES['Filedata0']['tmp_name'], $uploaddir."uploadfile_a.jpg");
move_uploaded_file($_FILES['Filedata1']['tmp_name'], $uploaddir."uploadfile_b.jpg");
move_uploaded_file($_FILES['Filedata2']['tmp_name'], $uploaddir."uploadfile_c.jpg");
move_uploaded_file($_FILES['Filedata3']['tmp_name'], $uploaddir."uploadfile_d.jpg");
move_uploaded_file($_FILES['Filedata4']['tmp_name'], $uploaddir."uploadfile_e.jpg");
move_uploaded_file($_FILES['Filedata5']['tmp_name'], $uploaddir."uploadfile_f.jpg");
?>

■uploadJPG.php

<?php
$uploaddir = './upload/';
move_uploaded_file($_FILES['Filedata']['tmp_name'], $uploaddir."uploadfile.jpg");
?>
uploadfiles.txt · 最終更新: 2010/04/06 13:24 by ason
Copyright © 2008~ずっと ason(minamotonoason@gmail.com)

chuumap 中小企業ツイッターマップ 製造、加工、卸などB2B主体の個人事業者、中小企業のツイッターを、グーグルマップの住所の位置に正確に表示。
tentwi 店舗でツイート 飲食店、販売店など、一般消費者向けの店舗を構えるお店ツイッターを、グーグルマップの住所の位置に正確に表示。
廃句ったー あなたのツイッターの最近のツイートから廃句もとい俳句を生成。
みかけったー 超人気!あなたのツイッターの最近のツイートからみかけの年齢と性別を診断。
キキキーったー 最近のツイートからキーの使用回数をしらべます。
SLOTTER(すろったー) あなたのツイッターのタイムラインのアイコンでスロット。FLASHゲーム。
MultiLangTweet 一度に48ヶ国語に翻訳してツイート。
英訳ったー 英訳または日本語訳してツイート。
バンドメンバー募集サイト シンプルなバンドメンバー募集サイト。
CMS総合デモサイト 有名オープンソースCMS、EC、SNS、Wikiを一度に全部体験できる総合デモサイト
ビズロック BizRock(ビズロック)~音楽ライブでプレゼン!情熱型ビジネス交流会