html5のFileReaderでドラッグ&ドロップなファイルのアップロード - end0tknrのkipple - web写経開発
以前、html5のFileReaderを使ったファイルアップロードのエントリを書いていますが、iframeを使ってajax風の画面遷移なしファイルアップロードを実現できるようなので、書いてみた。
Ajax的に画像などのファイルをアップロードする方法 ::ハブろぐ
で、触ってみたが、案外、いい感じ。
HTML
<nmw-args args="$pg,$view"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Sing XXXXX</title> <link rel="stylesheet" type="text/css" href="bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="css/default_2.css"> <script type="text/javascript" src="js/jquery.js"></script> </head> <body> <nmw-include template="Common/Head.html" args="$pg,$view"> <div class="container-fluid"> <h3>XXXXX</h3> <div id="sys_alert" class="alert" style="display:none;"></div> 発注データをダウンロードし、以下のフォームからアップロードして下さい <form method="POST" id="file_form" enctype="multipart/form-data" target="dummy_elm"> <input type="hidden" name="ac" value="chk_pre_juchuu_file"> <table class="table table-bordered table-condensed"> <tbody> <tr> <th>見出ファイル</th> <td> <input type="file" id="midashi_file" name="midashi_file" size="20"> </td> <th>明細ファイル</th> <td> <input type="file" id="meisai_file" name="meisai_file" size="20"> </td> <td> <input type="button" class="btn btn-primary" value="CSV内容確認" onClick="pre_j.chk_pre_juchuu_file()"> </td> </tr> </tbody> </table> </form> <iframe src="" id="dummy_elm" name="dummy_elm" style="display:none;"></iframe> <input type="button" class="btn btn-primary" value="以下の内容で、ハイム新着受注へ登録実行"> <form method="POST" id="common_form"> <div id="checked_juchuu"> </div> </form> <!--#common_form--> </div><!--.container-fluid--> <div style="display:none"> <!--jquery template-->w <script id="tmpl_midashi_tbl" type="text/x-jquery-tmpl"> <table class="table table-bordered table-condensed"> <thead> <tr> <th>発注NO</th> <th>邸名</th> <th>邸コード</th> <th>納入日<br>納入先(希望)</th> <th>発注日<br>(指定/実行)</th> <th>担当<br>(受注/発注)</th> <th>備考<br>メモ</th> </tr> </thead> <tbody> </tbody> </table> </script><!--#tmpl_midashi_tbl--> <script id="tmpl_midashi_tr" type="text/x-jquery-tmpl"> <tr> <td>${official_id_org}</td> <td>${tei_name_kana}<br>${tei_name}</td> <td>${xxxx_teicode}</td> <td>${delivery_date}<br>${delivery_to}</td> <td>${hachuu_date}<br>${admit_hachuu_time}</td> <td>${admit_juchuu_user}<br>${admit_hachuu_user}</td> <td>${note}<br>${memo}</td> </tr> </script><!--#tmpl_midashi_tr--> <script id="tmpl_anken_tbl" type="text/x-jquery-tmpl"> <table class="table table-bordered table-condensed"> <thead> <tr> <th>インポート先<br>案件</th> <th>邸名</th> <th>邸コード<br>商品タイプ</th> <th>住所<br>(建築先/現住所)</th> <th>据付予定<br>引渡予定</th> <th>工事部署/担当<br>展示場/担当</th> <th>更新情報</th> </tr> </thead> <tbody> </tbody> </table> </script><!--tmpl_anken_tbl--> <script id="tmpl_anken_tr_exist" type="text/x-jquery-tmpl"> <tr> <td> <label><input type="radio" value="new">既存案件</label> </td> <td>${tei_name_kana}<br>${tei_name}</td> <td>${xxxx_teicode}<br>${xxxx_shouhin_type}</td> <td>${build_address}<br>${now_address}</td> <td>${xxxx_suetsuke_date}<br>${hikiwatashi_date}</td> <td>${kouji_busho} ${kouji_busho_tantou}<br> ${xxxx_tenjijou} ${xxxx_tenjijou_tantou}</td> <td>${update_time}<br>${update_user}</td> </tr> </script><!--#tmpl_anken_tr_exist--> <script id="tmpl_anken_tr_new" type="text/x-jquery-tmpl"> <tr> <td> <label><input type="radio" value="new">新規作成</label> </td> <td><input type="text" style="width:160px;"></td> <td colspan="5"></td> </tr> </script><!--#tmpl_midashi_tr--> </div><!--jquery template--> <script type="text/javascript" src="js/common.js"></script> <script type="text/javascript" src="js/jquery.tmpl.js"></script> <script type="text/javascript" src="js/PreJuchuu.js"></script> <script> $(document).ready(function(){ }); </script> </body> </html>
javascript
(function() { var PreJuchuu = function() {}; PreJuchuu.prototype = { chk_pre_juchuu_file:function(){ if($('#midashi_file').val() == undefined || $('#meisai_file').val() == undefined){ toast_alert('見出と明細両方のCSVファイルを指定して下さい'); return; } //SUMIT完了後の処理 var this_obj = this; $('#file_form').submit(function(){ var dummy_elm = $('#dummy_elm'); //非表示iframe dummy_elm .unbind() .bind('load', function(){ //iframeの内容取得 var json_txt = dummy_elm.contents().find('pre').html(); this_obj.disp_checked_pre_juchuu(json_txt); }); }); $('#file_form').submit(); //SUBMIT return; }, disp_checked_pre_juchuu:function(json_txt){ var res = eval('('+json_txt+')'); //json to obj if (res.result != 'success'){ toast_alert(res.msg); return; } $("#checked_juchuu").empty(); var midashi_tbl = $("#tmpl_midashi_tbl").tmpl().appendTo("#checked_juchuu"); for(var i=0; i<res.midashis.length; i++){ var midashi = res.midashis[i]; $("#tmpl_midashi_tr").tmpl(midashi ).appendTo(midashi_tbl); } var anken_tbl = $("#tmpl_anken_tbl").tmpl().appendTo("#checked_juchuu"); $("#tmpl_anken_tr_new").tmpl().appendTo(anken_tbl); } }; window.pre_j = new PreJuchuu(); })();
server side View Class(perl)
package XXXX::View::Juchuu::PreJuchuu; use strict; use utf8; use base qw(XXXX::View); use Encode; use Text::CSV_XS; use Data::Dumper; my @PRE_MIDASHI_COLS = qw/official_id_org tei_name tei_name_kana hachuu_date admit_hachuu_time admit_hachuu_user admit_juchuu_user delivery_houhou delivery_date delivery_date_note delivery_to note memo teicode bukken_busho/; my @PRE_MEISAI_COLS = qw/official_id_org page_id row_id room_name maker maker_id shouhin_code hinmei hinmei_code hinban color size juchuu_quantity unit juchuu_tanka hachuu_tanka kakeritsu juchuu_price hachuu_price note memo curtain_size_name curtain_size_rail curtain_cloth curtain_kan/; sub new { my ($class, $dbh, $user) = @_; my $self = {dbh=>$dbh, user=>$user}; $self = bless $self, $class; return $self; } sub load_pre_midashi { my ($self, $q) = @_; my $ret = {}; #upload時に /usr/tmp/にCGItemp63817のような形式で #一時uploadされ、処理が完了したら、CGI.pmが消すみたい my $temp_fh = $q->upload('midashi_file'); return undef unless $temp_fh; my $file_path = $q->tmpFileName($temp_fh); my $csv = Text::CSV_XS->new ({binary =>1}); open(my $fh,"<:encoding(cp932)",$file_path) or die "can't open pre_juchuu_midashi ($file_path)"; my $i = 0; my @ret; while (my $row = $csv->getline($fh)) { next if $i++ == 0; #先頭行は見出なので、読飛し my $j=0; my $midashi = {}; for my $atri_key ( @PRE_MIDASHI_COLS ){ $midashi->{$atri_key} = $self->trim($row->[$j++]); } push(@ret,$midashi); } close($fh) or die "can't close pre_juchuu_midashi ($file_path)"; return \@ret; } sub load_pre_meisai { my ($self, $q) = @_; my $ret = {}; #upload時に /usr/tmp/にCGItemp63817のような形式で #一時uploadされ、処理が完了したら、CGI.pmが消すみたい my $temp_fh = $q->upload('meisai_file'); return undef unless $temp_fh; my $file_path = $q->tmpFileName($temp_fh); #ファイル名は $temp_fh にあり my $csv = Text::CSV_XS->new ({binary =>1}); open(my $fh,"<:encoding(cp932)",$file_path) or die "can't open pre_juchuu_midashi ($file_path)"; my $i = 0; my $ret = {}; while (my $row = $csv->getline($fh)) { next if $i++ == 0; #先頭行は見出なので、読飛し if ($row->[0] and not defined($ret->{$row->[0]}) ){ $ret->{$row->[0]} = []; } my $j=0; my $meisai = {}; for my $atri_key ( @PRE_MEISAI_COLS ){ $meisai->{$atri_key} = $self->trim($row->[$j++]); } push(@{$ret->{$row->[0]}}, \%$meisai); } close($fh) or die "can't close pre_juchuu_midashi ($file_path)"; return $ret; } sub validate_pre_juchuu { my ($self) = @_; for my $midashi ( @{$ret->{midashis}} ){ } } sub validate_midashi_official_id_org { my ($self,$pre_midashi) = @_; unless($pre_midashi){} } 1; __END__