カテゴリー: css/html/Javascript

JavaScript覚書 CSVファイルのFile.Type

JavaScriptでファイル選択する処理のなかにファイルタイプまで確認する処理が入っているものがあって、
それが災いして、新しいChromeのバージョン100.**でファイルが選択できなくなってしまった。

MIMEタイプとかいうらしいが、
File.type – Web API | MDN

CSVファイルは、
Chromeのバージョンが99.***までだと「application/vnd.ms-excel」になっていた。
ところが、バージョン100になったとたん、「text/csv」になり、
「application/vnd.ms-excel」でタイプを確認していた箇所は軒並み不具合を起こすこととなった。

ちなみにIE11で同じCSVファイルを選択してみたところ、「application/vnd.ms-excel」になり、
Edgeだと「text/csv」という結果になった。

m.o.b windows での csv アップロード
というサイトではExcelが入っているかどうかで決まるっぽいことを書いてあるのだが、
今回はすべてExcel2019が入っているPCで、同じサイトを確認したので、違うような感じがする。

そして、こんなサイトを見つけた。
Qiita CSVファイルのMIMEタイプが環境によって異なる
「application/octet-stream」って・・・

ただでさえ、バージョン3桁行きました!問題があるのに、こういうのやめてほしいんですけど・・・
(ってか、なんで、MIMEタイプまでチェックしてんだ?)

JavaScript覚書 JSONパース

仕事でJSONデータをバリバリ使うことになった。
けど、階層が多いからちゃんとデータ設定できているのか気になって、解析しようとJavaScriptで組むことにした。
(本当はExcelのマクロでセルにペタッと出力させたかったのだが)

<body>
    <textarea id="src"></textarea><br>
    <button onclick="javascript:return parseData();">解析</button><br>
    <pre id="res"></pre>
    
    <script>
        var doc = "";
        var indent = "&nbsp;&nbsp;";
        
        // 解析
        function parseData() {
            var srcObj = document.getElementById("src");
            var resObj = document.getElementById("res");
            doc = "";
            resObj.innerHTML = doc;
            
            var json = JSON.parse(srcObj.value);
            convJson(json, "");
            resObj.innerHTML = doc;
        }
        
        // 解析処理本体
        // obj : JSONデータ, caps : 階層表示インデント
        function convJson(obj, caps) {
            if (typeof(obj) == "object") {
                for (var i in obj) {
                    if (typeof(obj[i]) == "object") {
                        doc += caps + "[" + i + "]<br>";
                        convJson(obj[i], caps + indent);   // 下の階層を解析
                    } else {
                        doc += caps + i + " : " + obj[i] + "<br>";
                    }
                }
            } else {
                        doc += caps + i + " : " + obj[i] + "<br>";
            }
        }
    </script>
</body>

JQuery3覚書 属性・階層と付き合う

HTMLを初めて触ったのは22とか23の頃で、もう20年以上前の話になってしまった。
そのころはタグは大文字で書くのが普通だった。

いつの間にかIDやNAME、CLASSでスタイルを指定できる世の中になってしまった。
タグは小文字で書くのが当然になった。

そして今、属性を自分で勝手に作ってデータ操作する時代。
jsのライブラリもいっぱい世の中に出回っているが、何をやっているのかわからないやら、余計なことをするわで、結局自分でゴリゴリ作った方がカスタマイズしやすいんではないのか?などと後戻りできない旅路の一歩をを踏み出してしまう。

■ 属性

例えばの以下のようなテーブル構成の場合でいうならば、「data-no」というのが勝手に作った属性。
この属性の設定値を取得する方法をメモする。

<table id="tab1">
    <thead>
        <tr>
            <th data-no='1'>COL1</th>
            <th data-no='2'>COL2</th>
            <th data-no='3'>COL3</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td data-cd="101">DATA1-1</td>
            <td data-cd="102">DATA1-2</td>
            <td data-cd="103">DATA1-3</td>
        </tr>
        <tr>
            <td data-cd="201">DATA2-1</td>
            <td data-cd="202">DATA2-2</td>
            <td data-cd="203">DATA2-3</td>
        </tr>
    </tbody>
</table>

JQueryで、thタグをクリックしたときに、そのdata-noが何かをアラート表示させてみる。

    $(document).on('click', '#tab1>thead>tr>th', function (event) {
        alert($(this).attr('data-no'));
    });

これは、以下のように書いても問題はないのだが、もし当該テーブル、あるいはテーブルの要素が動的であった場合は、CLICKイベントが検知できないので、上記のように書いた方が汎用的のよう。

    $('#tab1>thead>tr>th').on('click', function (event) {
        // (記載略)
    });

対象の指定は下のように省略して書いても、tbodyタグにthがないときは問題ない。

    $('#tab1 th').on('click', function (event) {
        // (記載略)
    });

なお、attrは、attr({要素名})とすると、指定した要素の値があればその設定を返し、ないときはundefindedを返す。
そして、指定した要素に値を設定するときは、 attr({要素名}, {設定値}) とする。


■ 階層(親・子)

次に階層(親・子)を考慮しながら値を取る方法をメモしておく。
はじめにイベントの対象要素を「$(‘#tab1>thead>tr>th’)」と、恩着せがましく記述したのだが、これは親子関係をわかりやすくするためでもある。

#tabの子供がthead、その子供はtr、その子供はth

ということで、逆に言うと、thの親はtr、trの親は・・・と、もう書かないけどそんな感じ。

> 階層(親)

親は簡単に取れる。なんせ1つだから。

親である(tr)のHTML記述内容をアラート表示させてみる。

    $(document).on('click', '#tab1>thead>tr>th', function (event) {
        alert($(this).parent().html());
    });

簡単。親の親(thead)はparent().parent()。
親の親の親(#tab1)なら、parent().parent().parent()ということに。もはやfor文でも使った方がよさそうだ。

> 階層(子)

子の取り方はいろいろ。

試しに#tab1 tbody tr の行をクリックしたら、子要素(td)を順番にとって、コンソールに出力してみる。

    $(document).on('click', '#tab1>tbody>tr', function (event) {
        $(this).children().each(function (event) {    // (a)
            console.log($(this).html());              // (b)
        });
    });

(a)の$(this)は「tr」の要素のこと。
(b)の$(this)は子要素「td」のこと。
これだと、trの子要素はすべて取得できるので、tdとthの両方のタグがある場合は両方とも取得できる。

    $(document).on('click', '#tab1>tbody>tr', function (event) {
        $(this).children('td').each(function (event) {
            console.log($(this).html());
        });
    });

これだと、trの子要素のうちtdタグのみを取得できる。

    $(document).on('click', '#tab1>tbody>tr', function (event) {
        $(this).find('td').each(function (event) {
            console.log($(this).html());
        });
    });

findだと、引数で指定した要素であれば、子要素でも、孫要素でも範囲内すべてから取得可能になる。
サンプルだとテーブルの中にテーブルを入れ子していないので、子要素のみ取得できる。

children()を使うか、find()を使うかは子要素だけなのか、関係なく下の階層すべてに適用するのかで決める。

> 階層(子要素のn個目)
    $(document).on('click', '#tab1>tbody>tr', function (event) {
        $(this).children('td:nth-child(2)').each(function (event) {
            console.log($(this).html());
        });
    });

childrenで対象を指定するときに「:nth-child({n})」を使うと、n番目の要素だけ取得できる。

今日はここまで。次はソートについてメモせねば。

JQuery3覚書 初歩的なこと

歩道を歩いていて、前のヤツがタバコ吸うとこっちは受動喫煙になる。
もっとも、周りに気使う喫煙者は、路上や屋外で喫煙はしない。
路上や屋外で喫煙する奴は基本的にアホです。ハイ。ハッキリ断言します。
周りに人がいる、来るかもしれない場所での喫煙はやめましょう。ただの迷惑。

久しぶりの投稿の冒頭がこれかい!って感じですが、いつになったら分かるんでしょうねって思うので書いてみた。

で、JQuery。
今使っているのはバージョンは3.3.1。
色々データをこねくり回さなければいけないということで、ネットを検索しながらHTML/CSS/JSのファイルを作成。
今頃気づいたのだが、JavaScriptとJQueryは別モノ。
当たり前なのだが、JQueryで取得した要素に、JavScriptの標準メソッドを適用させようとするとエラーになる。

$('#table1').innerHTML 

これはダメ。左はJQuery、右はJavaScript標準。

$('#table1').html()

これはJQueryの記述方法で、OK。

document.getElementById('table1').innerHTML 

これはJavaScript標準の記述方法で、OK。

という話なのである。

jQuery覚書 Datetimepicker

日付と時刻両方設定できるJavaScriptのカレンダーを探していたところ

DateTimePicker

なるものを発見。jQueryのPlug-inとのこと。

早速ダウンロードして、サンプルを参考に設定していく。
いとも簡単に、日付と時刻が設定できた。分間隔もOptionで設定できる。

で、これって日付設定もできるんだよねぇ・・・(要は時刻設定は要らない!の場合)
って「timpicker:false」にするとできたことはできたんだけど、日付をクリックしてもカレンダーが消えてくれないのね。

困ったわぁ~と昼下がりに物思いにふける主婦の体(テイ)で、細かく説明を読んでみる。
すると、日付を選択したときのイベントみたいなものがあるではないか!

よし!
「onSelectDate」で、カレンダーを閉じる処理を追加しちゃえ!

ということで、以下のような設定で、うまいこと日付選択時もカレンダーが消えてくれましたとさ。

// HTML側は <input type="textbox" id="kaishibi" value /> 
$('#kaishibi').datetimepicker({
	dayOfWeekStart : 0 ,
	lang:'ja' ,
	value:'' ,
	format:'Y/m/d',
	formatDate:'Y/m/d',
	timepicker: false ,
	onSelectDate:function(ct,$i){
		$('#kaishibi').datetimepicker('hide')
	},
});