投稿者「後藤 祐一」のアーカイブ

後藤 祐一 について

フリーランスとしてWebプログラミングを行っています。 宜しくお願いします。

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);
	    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 beginMonth = new Date(dt.getFullYear(), dt.getMonth(), 1).getDay();
        if (beginMonth != 0) {
            var lateLastMonth = new Date(dt.getFullYear(), dt.getMonth(), 0).getDate();
            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が取得されます。

WordPress ショートコードでPHPファイルをインクルード

ショートコードを使ってPHPファイルをインクルードする方法についてechoするPHPファイルを読み込みたいとき表示がずれたので公式ドキュメントを調べました。

公式より抜粋
echo ではなく return を使うようにしてください。
echo されたものはすべてブラウザへ出力されますが、ページの適切な箇所に表示されません。

ob_get_cleanをリターンすればいいとのことでさっそく作成

function my_shortcode() {
    ob_start();
    include('phpfile.php');
    return ob_get_clean();
}
add_shortcode('shortcode', 'my_shortcode');

phpfile.phpがecho するファイルでも【shortcode】で呼び出したとき正しく表示されるようになります。

WordPress 新しいエディタ 使いにくい Gutenberg

gutenberg

WordPressを更新したら新しいエディタになっていました。
Gutenbergと言うらしいのですが筆者はVim使いなのでテキストしか使わないのですよね。
画像の通り①、②と2回クリックしてテキストモードに切り替えるのが面倒でビジュアルエディタを前のバージョンに戻しました。

classiceditor

Classic Editorと言うプラグインを追加するだけで前のバージョンのエディタに変更できるので助かりました。