Javascript(jQuery)」カテゴリーアーカイブ

summernoteで画像をアップロード

summernoteで画像をアップロードする方法を調べてみたが情報が古く自分で実装したのでまとめ。
画像をアップロードしたらエディタに画像を反映させるところまで解説します。

環境
summernote v0.8.12
XAMPP
PHP 7.3

読み込むファイル

<!-- include libraries(jQuery, bootstrap) -->
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet">
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.js"></script>
<!-- include summernote css/js -->
<link href="summernote-master/dist/summernote.css" rel="stylesheet">
<script src="summernote-master/dist/summernote.min.js"></script>
<script src="summernote-master/dist/lang/summernote-ja-JP.js"></script>

<form method="post" enctype="multipart/form-data" action="">
  <textarea id="summernote" name="editordata"></textarea>
<input type="submit" name="send" value="送信する">

bootstrapはCDNでsummernoteは日本語で読み込んでいます。

画像ファイルのアップロード部

$(document).ready(function() {
    $('#summernote').summernote({
      lang: 'ja-JP',
        height: 200,
        callbacks: {
            onImageUpload: function(files) {
                sendFile(files[0]);
            },
        }
    });
});

function sendFile(file) {
    data = new FormData();
    data.append("file", file);
    $.ajax({
        data: data,
        type: "POST",
        url: "upimg.php",
        cache: false,
        contentType: false,
        processData: false,
    }).done(function(data, textStatus, jqXHR){
        $('#summernote').summernote('insertImage', 'http://localhost/develop.git/img/' + file.name);
    });
}

sendFileに渡すデータはfileだけなのとsummernoteで画像をアップしたらエディタに反映させるのはinsertImageで画像URLを指定しています。
その他は先人の知恵をお借りしました。

upimg.php

    move_uploaded_file($_FILES['file']['tmp_name'], "img/". $_FILES['file']['name']);

画像をアップしているだけなので
ファイル名が重複しないようしたりリサイズなどはこのファイルでするようにしましょう。

jQuery Table要素にappend

jQueryでTable要素にappendするときずれた位置に表示されてしまったのでまとめ

$(document).ready(function(){
    $('#foo').append('<tr>');
    $('#foo').append('<td>');
    $('#foo').append('ずれた位置に表示される');
    $('#foo').append('</td>');
    $('#foo').append('</tr>');
});

最初のtrタグをappendしたタイミングで/trされる。
tdタグについても同じくtdタグをappendしたタイミングで/tdされる。
なのでHTMLでみると以下のようになる

<table id="foo">
  <tr></tr>
  <td></td>
  ずれた位置に表示される
</table>

for文などで行と列が可変の場合とても面倒だが
tableにtrをappendする
trにtdをappendする

$(document).ready(function(){
    $('#foo').append('<tr id="bar"></tr>');
    $('#bar').append('<td>この書き方が正解</td>');
});

HTMLでみると以下のようになる

<table id="foo">
  <tr id="bar">
    <td>この書き方が正解</td>
  </tr>
</table>

なおtrをappendするタイミングで/trがされるので/trは省略できる。
tdタグについても同じくtdをappendするタイミングで/tdがされるので/tdは省略できる。
しかし/タグを省略して書くとプログラマとしては失格であるので/tr/tdでしっかりと閉じよう。
誰が見ても分かりやすいコードを書くように心がけよう。

jQuery 楽天 カレンダー

楽天のカレンダーが表示されなくなってたので自分で組みました。
1ヶ月毎に自動で切り替わる仕様です。

CSS

table.calbase_rakuten {
    background-color: #FFFFFF;
    border: 1px solid #CECECE;
    width: 100%;
    border-collapse: collapse;
    padding: 0px 0px 10px 0px;
}

table.calbase_rakuten * {
    font-size: 98%;
    color: #000000;
    border-collapse: collapse;
    padding: 0px;
    margin: 0px;
}

table.calbase_rakuten th {
    text-align: center;
}

th.caltitle_rakuten {
    font-size: 85%;
    padding: 10px 0px 0px 0px;
}

table.calframe_rakuten {
    border-collapse: collapse;
    margin: 10px 10px 0px 10px;
    table-layout: fixed;
    width: 178px;
}

table.calframe_rakuten th {
    text-align: center;
    padding: 0px 0px 3px 0px;
}

table.calframe_rakuten td {
    border: 1px solid #FFFFFF;
    background-color: #FFFFFF;
    width: 19px;
    height: 17px;
    text-align: center;
}

tr.weektitle_rakuten td {
    background-color: #EEEEEE;
}

td.event1day_rakuten {
    background-color: #FFC6C6 !important;
}

font.event1day_rakuten {
    color: #FFC6C6;
}

td.event2day_rakuten {
    background-color: #B5DAFF !important;
}

font.event2day_rakuten {
    color: #B5DAFF;
}

td.event3day_rakuten {
    background-color: #FEDE93 !important;
}

font.event3day_rakuten {
    color: #FEDE93;
}

table.event_rakuten {
    text-align: left;
    word-break: break-all;
    margin: 7px 10px 7px 10px;
    border-collapse: collapse;
    line-height: 120%;
    table-layout: fixed;
    width: 141px;
}

table.event_rakuten td {
    padding: 0px 0px 0px 0px;
}

table.text_rakuten {
    text-align: left;
    word-break: break-all;
    margin: 0px 10px 10px 10px;
    border-collapse: collapse;
    line-height: 120%;
    table-layout: fixed;
    width: 178px;
}

HTML

<table class="calbase_rakuten">
  <tr>
      <td align="center">
      <table>
        <tr>
          <td align="center">
            <table class="calframe_rakuten" id="forArea0">
              <tr>
                <th colspan="7"><span id="y0"></span>年<span id="m0"></span>月</th>
              </tr>
              <tr class="weektitle_rakuten">
                <td style="color:#BF0000">日</td>
                <td style="color:#000000">月</td>
                <td style="color:#000000">火</td>
                <td style="color:#000000">水</td>
                <td style="color:#000000">木</td>
                <td style="color:#000000">金</td>
                <td style="color:#1D54A7">土</td>
              </tr>
            </table>

            <table class="calframe_rakuten" id="forArea1">
              <tr>
                <th colspan="7"><span id="y1"></span>年<span id="m1"></span>月</th>
              </tr>
              <tr class="weektitle_rakuten">
                <td style="color:#BF0000">日</td>
                <td style="color:#000000">月</td>
                <td style="color:#000000">火</td>
                <td style="color:#000000">水</td>
                <td style="color:#000000">木</td>
                <td style="color:#000000">金</td>
                <td style="color:#1D54A7">土</td>
              </tr>
            </table>

          </td>
        </tr>
        <tr>
          <td colspan="2">
            <table class="event_rakuten">
              <tr><td><font class="event1day_rakuten">■</font> 休業日</td></tr>
              <tr><td><font class="event2day_rakuten">■</font> 受注・お問い合わせ業務のみ</td></tr>
              <tr><td><font class="event3day_rakuten">■</font> 発送業務のみ</td></tr>
            </table>
          </td>
        </tr>
        <tr>
          <td colspan="2">
            <table class="text_rakuten">
              <tr><td>
                ※ご注文は24時間年中無休で受け付けております。
              </td></tr>
            </table>
          </td>
        </tr>
      </table>
    </td>
  </tr>
</table>

Javascript

$(document).ready(function(){
    var dt = new Date();
    var echoCount = 2;
    var holidayDates = ['2019/3/21','2019/4/29','2019/4/30','2019/5/1','2019/5/2','2019/5/3','2019/5/4','2019/5/5','2019/5/6','2019/7/15','2019/8/11','2019/8/12','2019/9/16','2019/9/23','2019/10/14','2019/10/22','2019/11/3','2019/11/4','2019/11/23'];

    for (var i = 0; i < echoCount; i++) {
	    $('#y' + i).append(dt.getFullYear());
	    $('#m' + i).append(dt.getMonth() + 1);
	    createClendar(dt, '#forArea' + i, 'row' + i);
        var nextLastDay = new Date(dt.getFullYear(), dt.getMonth()+2, 0).getDate();
        if (nextLastDay <= dt.getDate()) {
	        dt.setDate(dt.getDate() + 1);
        } else {
            dt.setMonth(dt.getMonth() + 1);
        }
	}

    function createClendar(dt, areaName, rowName) {
        var lastDay = new Date(dt.getFullYear(), dt.getMonth()+1, 0).getDate();
        var row = 0;
        var k = 0;
        var a = dt.getDay();
        var beginMonth = new Date(dt.getFullYear(), dt.getMonth(), 1).getDay();
        if (beginMonth != 0) {
            var lateLastMonth = new Date(dt.getFullYear(), dt.getMonth(), 0).getDate();
            var beginMonth = new Date(dt.getFullYear(), dt.getMonth(), 1).getDay();
            var i = lateLastMonth - beginMonth + 1;
            var j = 0;
            $(areaName).append('<tr id="' + rowName + row + '"></tr>');
            for (i; i <= lateLastMonth; i++) {
                $('#' + rowName + row).append('<td style="color:#CECECE">' + i + '</td>');
                j++;
            }
            for (j; j < 7; j++) {
                k++;
                if (j == 0 || j == 6) {
                    $('#' + rowName + row).append('<td style="color:#1D54A7" class="event1day_rakuten">' + k + '</td>');
                } else if (holidayDates.some(function(e) {return e == dt.getFullYear() + '/' + (dt.getMonth()+1) + '/' + k})) {
                    $('#' + rowName + row).append('<td style="color:#BF0000" class="event1day_rakuten">' + k + '</td>');
                } else {
                    $('#' + rowName + row).append('<td style="color:#000000">' + k + '</td>');
                }
            }
        }
        for (var i = 0; i < 7; i++) {
        	k++;
        	if (i == 0) {
        		row++;
    	        $(areaName).append('<tr id="' + rowName + row + '"></tr>');
        	}
        	if (i == 0 || i == 6) {
                $('#' + rowName + row).append('<td style="color:#1D54A7" class="event1day_rakuten">' + k + '</td>');
            } else if (holidayDates.some(function(e) {return e == dt.getFullYear() + '/' + (dt.getMonth()+1) + '/' + k})) {
                $('#' + rowName + row).append('<td style="color:#BF0000" class="event1day_rakuten">' + k + '</td>');
            } else {
                $('#' + rowName + row).append('<td style="color:#000000">' + k + '</td>');
            }
        	if (i == 6) {
        	    i = -1;
        	}
    	    if (k >= lastDay) {
    	    	var forCount = 7 - new Date(dt.getFullYear(), dt.getMonth(), k).getDay();
        		for (j = 1; j < forCount; j++) {
    	            $('#' + rowName + row).append('<td style="color:#CECECE">' + j + '</td>');
        		}
    	    	break;
    	    }
        }
    }
});

まとめ

祝日判定をarray.someでしているがIE11で動かなかった。

if (holidayDates.some(e) => e == '2019/4/29') {
    // ie11で動かないよ
    // でもChromeとFirefoxでは動くよ
}
if (holidayDates.some(function(e) {return e == '2019/4/29'})) {
    // ie11でも動くよ
}

Javascript Dateで日付比較

最近Javascriptで土日祝日を飛ばして出荷日を自動表示する依頼があったのでまとめ

$(document).ready(function(){
    var dt = noonDecision();
    var w = dt.getDay();
    var wd = ['日', '月', '火', '水', '木', '金', '土'];
    var holidayDates = ['2019/3/21','2019/4/29','2019/4/30','2019/5/1','2019/5/2','2019/5/3','2019/5/4','2019/5/5','2019/5/6','2019/7/15','2019/8/11','2019/8/12','2019/9/16','2019/9/23','2019/10/14','2019/10/22','2019/11/3','2019/11/4','2019/11/23'];
    var startWork = '2020/01/01';
    var endWork = '2019/12/31';
    var errorFlg = true;

    if (new Date(dt.getFullYear(), dt.getMonth(), dt.getDate()).getTime() >= new Date(endWork).getTime()) {
        dt = new Date(startWork);
    }
    else {
        while (errorFlg) {
            // 祝日判定
            holidayDecision();
            // 土日判定
            satSunDecision();
        }
    }

    $('body').html('<center>' + (dt.getMonth()+1) + '月' + dt.getDate() + '日 (' + wd[dt.getDay()] + ')</center>');

    /**
    * 祝日判定
    **/
    function holidayDecision() {
        var checkDate = dt.getDate();
        for (var i = 0; i < holidayDates.length; i++) {
            if (new Date(dt.getFullYear(), dt.getMonth(), dt.getDate()).getTime() == new Date(holidayDates[i]).getTime()) {
                dt.setDate(dt.getDate() + 1);
            }
        }
        if (checkDate == dt.getDate()) {
            errorFlg = false;
        } else {
            errorFlg = true;
        }
    }

    /**
    * 土日判定
    **/
    function satSunDecision() {
        if (dt.getDay() == 6) {
            dt.setDate(dt.getDate() + 2);
            errorFlg = true;
        } else if (dt.getDay() == 0) {
            dt.setDate(dt.getDate() + 1);
            errorFlg = true;
        } 
    }

    /**
    * 正午判定
    * return Date
    **/
    function noonDecision() {
        var dt = new Date();
        var insObj = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate(), 12, 0, 0);
        if (dt >= insObj) {
            dt.setDate(dt.getDate() + 1);
        }
        return dt;
    }
});

まとめ

whileで繰り返してるのはGWなど祝日明けが土日の場合と土日明けが祝日だったりするため。
祝日でも土日でもない場合に初めてwhile文を抜けます。

ややこしかったところ

月を取得するとき1月ならgetMonth()で0が取れてくるところ
(n – 1)なので+1をする。

オブジェクト生成するときは文字列を渡す場合と数値を渡す場合で結果が異なる。

new Date().getMonth(); // 3月だと2 (n-1)
new Date('2019/3/1').getMonth(); // 2
new Date(2019,3,1).getMonth(); // 3

公式
注: 引数 monthIndex は 0 から始まります。 つまり 1 月 = 0、 12 月 = 11 です。

日付比較は.getTimeを使う

if (new Date(2019, 3, 1).getTime() == new Date('2019/3/1').getTime()) {
    // false
}
if (new Date(2019, (3-1), 1).getTime() == new Date('2019/3/1').getTime()) {
    // true
}
// getTimeを使わないとfalseになる
var foo = new Date(2019, 3, 1);
var bar = new Date(2019, 3, 1);
if (foo == bar) {
    //false
}

曜日はgetDay()で数値が取れてくるだけなので別に文字列で曜日配列を作成する必要がある。
日曜日なら0,月曜日なら1・・・土曜日なら6

祝日は自分で定義する必要がある。

日付オブジェクトを作成するとき文字列を渡す場合YYYY/MM/DDかYYYY/M/D形式にするとよい。
(スラッシュ区切り)
Date.parseは使用しない。
公式
注: ブラウザごとに動作が異なり一貫性がないため、Date コンストラクタ (または同等の Date.parse) で日付文字列を解釈しないように強くすすめます。RFC 2822 形式の文字列のサポートは、慣例にすぎません。 ISO 8601 フォーマットのサポートは、日付のみの文字列 (例: “1970-01-01”) が地方時ではなくUTCとして扱われる点で異なります。

末日を取得するときはdに0を指定すると指定した月の末日が取れてくる。
new Date(2019, 2, 0).getDate()と渡すと28が取得できる。

日付に31以上の数値を渡すと月を繰り上げてくれる。

var foo = new Date(2019, (3-1), 33); // 3月は31日まで (n-1)で3月と認識させている
$('body').html((foo.getMonth() + 1) + '月'); // 33を渡すことにより繰り上がった結果4月
$('body').append(foo.getDate() + '日'); // 3月31日に33を渡すことにより繰り上がった結果2日

とてもややこしいですが月は0が1月扱いなのでDateオブジェクトを作成するときは-1
表示させるときは+1しています。

仮にDateオブジェクトを作成するときにMonthに-1をせず3を渡すと4月扱いとなりますので
2019年4月の末日は30日となり、33 – 30の計算でgetMonth()で繰り上がって4、getDate()では3が取得されます。

jQuery 郵便番号から住所を自動入力 AjaxZip3.0

ここでは郵便番号から住所を自動入力してくれるAjaxZip3.0の紹介をしていきます。

ajaxzip2

デモはこちら
https://office-goto.info/demo/ajaxzip3/

AjaxZip3.0の公式サイト
https://code.google.com/p/ajaxzip3/

head内で読み込み

<script src="https://ajaxzip3.github.io/ajaxzip3.js" charset="UTF-8"></script>

jQueryを読み込まなくても大丈夫でした。
また、2.0と違い、ファイルをダウンロードして、読み込ませる必要がなくなりました。

html

郵便番号
<input type="text" name="pos1" style="width:50px; ime-mode:disabled;" />
&nbsp;-&nbsp;
<input type="text" name="pos2" style="width:50px; ime-mode:disabled;" onKeyUp="AjaxZip3.zip2addr('pos1','pos2','pref','city');"/>
都道府県
<select name="pref">
    <option value="">--</option>
    <option value='北海道'>北海道</option><option value='青森県'>青森県</option>
    <option value='岩手県'>岩手県</option><option value='宮城県'>宮城県</option>
    <option value='秋田県'>秋田県</option><option value='山形県'>山形県</option>
    <option value='福島県'>福島県</option><option value='茨城県'>茨城県</option>
    <option value='栃木県'>栃木県</option><option value='群馬県'>群馬県</option>
    <option value='埼玉県'>埼玉県</option><option value='千葉県'>千葉県</option>
    <option value='東京都'>東京都</option><option value='神奈川県'>神奈川県</option>
    <option value='新潟県'>新潟県</option><option value='富山県'>富山県</option>
    <option value='石川県'>石川県</option><option value='福井県'>福井県</option>
    <option value='山梨県'>山梨県</option><option value='長野県'>長野県</option>
    <option value='岐阜県'>岐阜県</option><option value='静岡県'>静岡県</option>
    <option value='愛知県'>愛知県</option><option value='三重県'>三重県</option>
    <option value='滋賀県'>滋賀県</option><option value='京都府'>京都府</option>
    <option value='大阪府'>大阪府</option><option value='兵庫県'>兵庫県</option>
    <option value='奈良県'>奈良県</option><option value='和歌山県'>和歌山県</option>
    <option value='鳥取県'>鳥取県</option><option value='島根県'>島根県</option>
    <option value='岡山県'>岡山県</option><option value='広島県'>広島県</option>
    <option value='山口県'>山口県</option><option value='徳島県'>徳島県</option>
    <option value='香川県'>香川県</option><option value='愛媛県'>愛媛県</option>
    <option value='高知県'>高知県</option><option value='福岡県'>福岡県</option>
    <option value='佐賀県'>佐賀県</option><option value='長崎県'>長崎県</option>
    <option value='熊本県'>熊本県</option><option value='大分県'>大分県</option>
    <option value='宮崎県'>宮崎県</option><option value='鹿児島県'>鹿児島県</option>
    <option value='沖縄県'>沖縄県</option>
</select>
市区町村
<input type="text" name="city" />
番地等
<input type="text" name="address" />

解説

onKeyUp=”…” (4行目)
表示させるinputタグのnameで指定します。

関連記事
jQuery 郵便番号から住所を自動入力 AjaxZip2.0
https://office-goto.info/javascript-jquery/ajaxzip2-0/