カテゴリーアーカイブ JavaScript

asaba 著者:asaba

【html-css】複数のセレクトボックスを並列で表示させる

今回は、セレクトボックスを複数並べたいかつ横に揃えたい時にしたことを書いていきます。

セレクトボックス、決められた項目をプルダウンで表示させるアレのことです。よくアンケートフォームやアプリの会員登録画面で

見受けられますが、案件によってはこのオブジェクトを複数決められた位置に並べたいという時もあるのではないでしょうか。

現に今どきのフォームだと○○県○○市といった県と市を分けて表示するデザインが増えており、今はもうそんな感じのデザインが

主流なのかなと勝手に考えております。

自分も、今回の開発でセレクトボックスを複数出したかったので汚いながらも気合でやってみたのでもしこんなのでよければ参考に

してください。

まずは、htmlからです。reactで書いた誕生日のサンプルですね。

</pre>
<span className="birthday">
<p>生年月日</p>
<select value={this.state.member.year || ''} onChange={(e) => this.handleYearChange(e)} >
{ this.yearData.map( d => <option key={d.value} value={d.value}>{d.label}</option>)}
</select>
<label htmlFor="select-01">年</label>
<select value={this.state.member.month || ''} onChange={(e) => this.handleMonthChange(e)} >
{ this.monthData.map( d => <option key={d.value} value={d.value}>{d.label}</option>)}
</select>
<label htmlFor="select-01">月</label>
<select value={this.state.member.day || ''} onChange={(e) => this.handleDayChange(e)} >
{ this.dayData.map( d => <option key={d.value} value={d.value}>{d.label}</option>)}
</select>
<label htmlFor="select-01">日</label>
<span className="error">{this.state.error ? this.state.error.birthday : ''}</span>
</span>
<pre>

なんでdivじゃないのとツッコミを受けそうですが、divを使うと改行してしまい一行ずつセレクトボックスが表示されてしまうという

事態が起きるので、代用して改行をしないspanを使い並列に並べるという意図でございます。

続いてcssです。

</pre>
span.birthday {
width: 90px;
padding:0;
font-size:0px;
}
span.birthday select {
width:110px;
height: 50px;
margin:10px;
border:1px solid black;
display: inline-block;
text-align: center;
font-size:16px;
background-color:#fff;
}
<pre>

あまり深いことは書いていないのですが、span.birthdayでセレクトボックスを三つ並べられるようエリアを拡大していますね。

下のspan.birthday.selectでセレクトボックスそのものの大きさとセレクトボックスの外線、位置を決めています。

以上でセレクトボックスを横向きに表示するコーディングはおしまいです。実はこれもネットにも中々乗っておらず、一つ一つ

パーツを繋ぎ合わせてせこせこ書いていました。いびつですが、正しく動きますので、reactで同じようなコンポーネントを

作りたい、でもどこにも思ったことが書いていない!というかたはもしよろしければ参考にしてみてください。

  • この記事いいね! (0)
著者:杉浦

Vue.jsでVue.js向けに開発されていないライブラリを用いる

 Vue.jsはwebページを部品化してコーディングすることを目的としたJavaScriptのフレームワークです。単一コンポーネントの仕組みを用いたVue.jsのコード例の多くは(少なくとも私の読んだコードでは)次の様になっています。

// コンポーネント定義用Vue.jsコード
<template>
  // Vue.jsと連携するHTMLコード
</template>

<script>
export default {
  name: 'hoge',
  // prop:{}とかdeta(){return {hogehoge}}とかmethods:{}とかVue.jsと連携するためのプロパティ
};
</script>

<style scoped>
  // このコンポーネント内でのみ適用されるcss
</style>
// コンポーネント読み込み用JavaScriptコード
window.$ = window.jQuery = require('jquery');
// 色々グローバルで使うライブラリ

window.Vue = require('vue');

Vue.component('hoge', require('./hoge.vue').default);

const app = new Vue({
  el: '#app',
});

 自分はVue.jsで使うことを前提にしていないライブラリはJavaScript側2、3行目の様に色々読み込むものだと思っていました。一方でこのようなやり方はグローバル汚染がひどく、重要なごく一部のライブラリ以外を読み込んだ場合あっという間にバグが生まれるとも思っていました。実際はそのようなことをせずともよく、次の様に記述することで管理しやすくライブラリを用いることができました。

<template>
  // Vue.jsと連携するHTMLコード
</template>

<script>
import 'fuga';
import foo from 'foo';

// Vue.jsに依らない静的処理
const bar = foo.bar();

export default {
  name: 'hoge',
  // importしたライブラリや変数barを用いたVue.jsと連携するコード
};
</script>

<style scoped>
  // このコンポーネント内でのみ適用されるcss
</style>

 <script>タグの先頭に記述するだけです。<script>タグの内部ならばVue.jsがいい感じにスコープを作ってくれるのでグローバル汚染を気にせず好き勝手できます。
 <script>export default {で始めて、}</script>で終わらなければならないという風に思い込んでいましたがVue.jsにその様な縛りはなく、実際はかなり自由に記述できました。

  • この記事いいね! (0)
村上 著者:村上

【JavaScript】「The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype」エラーの対処法

長いタイトルですみません…。
現在開発中のシステムで導入している ESLint という検証ツールで、タイトルにあるエラーが発生したので、対処法をまとめ。
エラー文は「The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.」というもので、翻訳したところ「for-inの本体は、プロトタイプから不要なプロパティをフィルタリングするためにif文でラップする必要があります。」とのことでした。
…いまいち意味が分からない…。

 

今回参考にさせていただいた記事はこちら。

JSLintオプション考察「unfiltered for in」|もっこりJavaScript|ANALOGIC(アナロジック)
http://analogic.jp/jslint-options-forin/

上の記事によると、for-in ループを使用したときに列挙されるプロパティには、実際のデータ以外にも、プロトタイプ連鎖から来たプロパティも含まれるとのことでした。
そのため、取得したデータがオブジェクト自身が持つプロパティなのか、プロトタイプ連鎖から来たプロパティなのかを判断する必要があります。
で、それは hasOwnProperty() を使うことで判断できるとのこと。

使い方は下記のとおりです。

const list = ['A', 'B', 'C', 'D', 'E'];
for (data in list) {
    if (list.hasOwnProperty(data)) {
        // 実行したい処理
    }
}

3行目で、データの判別を行っています。
こちらを追加したところ、エラーが解消され、問題なく実行できました。

 

以上、JavaScript の for-in 文で発生したエラーの対処方法でした。
なおこの後、実装しているコードでは for-in よりも forEach の方が向いているとわかり、上記は使用しないように修正しました…。
が、うっかりと再発させそうなエラーだったので、備忘録としてまとめました。
もし、同じことでお困りの方は参考にしていただければと思います。

  • この記事いいね! (0)
著者:杉浦

Leaflet関連のライブラリを用いる際たまに起こるライブラリのバグ

Leaflet – a JavaScript library for interactive maps
 LeafletはJavaScript上で地図を描画、操作できる様にするライブラリです。地図の需要は多くLeafletを拡張するライブラリもまた多くあります。紹介するのはこのLeafletに何かを付け足すようなライブラリにありがちなバグです。
 Leaflet関連のライブラリはLeafletに様々なものを載せます。例えばフルスクリーン化、google map、ミニマップ、サイドバー。重要なのはこれらのいずれもまずLeafletありきだということです。このためライブラリの中には単独で動くようにライブラリ内でLeafletを読み込んでくれるものがいます。これ自体はありがたいしそのライブラリ単独ではむしろ良いことです。ですがこの動作を既にLeafletが読み込まれているにも関わらず行った場合、問題が起きます。既に読み込まれていたLeafletを壊すことがあるのです。このLeafletを壊すような問答無用な読み込み動作を行うライブラリが稀にあります。
 Leaflet読み込み動作付きライブラリと他のライブラリを混ぜ合わせて使うと、他のライブラリを上書きして、存在するはずの関数が存在しない、引数の型が期待したものと異なるといった混乱が引き起こされバグが発生します。対処法はライブラリの中を見て

import L from 'leaflet'

の様な変数Lにleafletを出力している様な記述があるかチェックして消し、プロジェクト内に移動しパスを変更するだけです。
 ライブラリの中をいじること自体はバージョン管理が面倒になるアンチパターンもいい所なのであまり褒められたやり方ではありませんが、幸いLeaflet拡張機能系統のライブラリは小さなものが多く個人でもすぐに読み解け管理できます。

  • この記事いいね! (0)
村上 著者:村上

【React】エンターキーが押されたことを検知する方法

チャット画面を作成していたとき、エンターキーでテキスト入力エリアに入力したテキストを送信するという処理を行いたかったので、その方法について。
React と書いていますが、恐らく通常の JavaScript でも扱えるはず。

今回参考にさせていただいた記事はこちらから。

Reactでエンターキーのイベントを取得する方法 – 1日1%成長するブログ
http://masarufuruya.hatenadiary.jp/entry/2017/09/06/200551

 

さて、実装方法ですが、キー入力されたことは onKeyDown イベントで検知します。

<input type='text' onKeyDown={(e) => this.handleKeyDown(e)} />

上記は、なにかしらのキーが押された場合、その都度 handleKeyDown 関数が呼び出されます。

で、handleKeyDown 関数の中身は下記のとおりです。

handleKeyDown(e) {
  if (e.keyCode === 13) {
    // エンターキーが押された時の処理
  }
}

エンターキーは keyCode では 13 という数字が割り振られているとのことだったので、keyCode の値を見て判断します。
あとは、この if 文の中で、テキストを送信した際に行いたい処理を実行すればOKです。
非常に簡単でした!

 

以上、エンターキーが押されたかどうかを検知する方法でした。
なお、Androidの実機と iOS の Simulator でも動作確認を行いましたが、問題なく動作しました。
実行ボタンが無くなると、やはりレイアウトがすっきりする気がします。
是非、ご参考にしていただければと思います。

  • この記事いいね! (0)
asaba 著者:asaba

【react】render内で’===’を使うとなぜか文字列に変換される

reactのrender内では三項演算子がうまく働かない時があるんですが原因はなんなのでしょうか。

例えば

</pre>
const number = 1;

const shelter = number === 1 ? 'number' : 'ather';
<pre>

三項演算子はこのように定義するのですが、ここでは通常ならばnumber変数の中身は1なので変数shelterには’number’が入ります。

ですが、これをrender()内で実行すると、なぜかatherさんが格納されてしまうという事態に!

render()はstateが呼ばれるたびに更新するので、その時に変数も更新されてundefinedになっているのではと思ったのですがどちらの変数に

もしっかりと1が入っている(どういうこと!?)しかも文字列ではなくて普通に数値なんですがそれは・・・。

だとしたらもう怪しいのはお前しかいない、===!とりあえず特定をしたくてこれと==を比較して使ってみたのですが

見事にそれぞれ文字列と数値を吐き出していました。

てな訳で原因が分かったところで結局=を一つ減らして再render()して力ずくで解決させてしまいました。

そもそも数値で定義しているのになぜ文字列に解釈されているのかが分からないのですが。reactには勝手に値を変換するプラグインとかも

入れていないしjavascriptに型推論なんて存在しないしデフォルトの状態でこれならもう’===’を使うのを躊躇してしまいますw

ここは素直に’==’を使いましょうということでしょうか・・・

とりあえずrender()内で値を扱う時は値の型に気を配ってコーディングしなさいという戒めだと思って肝に銘じておきます。

  • この記事いいね! (0)
村上 著者:村上

【Cordova】端末のシェイクジェスチャーを検知できるプラグイン「cordova-plugin-shake」

今回は、スマートフォン端末がシェイクされたことを検知できるプラグイン「cordova-plugin-shake」をご紹介。
正直、今回実際に使うまでは「こんなプラグイン、一体いつ使うのか…」とも思っていましたが…意外と使うものなんですね。

そんな意外なプラグインのGitHubページはこちらから。

GitHub – leecrossley/cordova-plugin-shake: Cordova / PhoneGap Plugin to detect when a physical device performs a shake gesture
https://github.com/leecrossley/cordova-plugin-shake

 

実装方法ですが、まず下記のコマンドでプラグインをインストールします。

cordova plugin add cordova-plugin-shake

で、サンプルコードは下記のとおりです。

const onShake = function () {
  // シェイク検知成功時の処理
};
const onError = function () {
  // シェイク検知失敗時の処理
};
// シェイクジェスチャーの検知を開始
shake.startWatch(onShake, 30, onError);

shake.startWatch() 関数の第2引数と第3引数はオプションなので、指定しなくてもOKです。
ちなみに、第2引数の数値は、シェイク検知の感度のようですが…いまいちよく分かっていません。
なお、こちらのデフォルト値は 30 です。

で、シェイクの検知を終了したいときは、下記を呼び出します。

// シェイクジェスチャーの検知を終了
shake.stopWatch();

コードとしては以上です。
上記のサンプルコードそのままではないのですが、実際に使ってみたところ、問題なく動作しました。
感度も良く、何度も端末を振らなくてもすぐにシェイクジェスチャーが検知されました。

 

以上、シェイクジェスチャーを検知できるプラグイン「cordova-plugin-shake」のご紹介でした。
冒頭でも書きましたが、実際に使う場面はそうそう多くなさそうですが…もしご入用の際はご活用ください。

  • この記事いいね! (0)
asaba 著者:asaba

【npm】phonegap-plugin-speech-recognationが読み込めない

今回のネタはphonegap-plugin-speech-recognitionを使おうとしてReferenceError: SpeechRecognition is not definedで怒られたのと

その対処法についてです。

phonegap-plugin-speech-recognitionとは、入力された文字に対して、その文字を読み取って音声で返してくれるプラグインのことです。

プラグインの紹介をしたところで本題に入らせていただきます。

まず、あるアプリにphonegap-plugin-speech-recognitionを追加して動作確認をしたところReferenceError: SpeechRecognition is not

definedで行き止まりをくらいました。

ん~、インストールしたのにな・・・と思い渋々npm install phonegap-plugin-speech-recognitionをすると

下記の画像のようにエラーがずららっと表示されました。

 

ここで、試しにnpm lsコマンドでphonegap-plugin-speech-recognationが存在するか確認をしてみました。

するとなにやらにおうエラーを発見

npm ERR! missing: phonegap-plugin-speech-recognition@git+https://github.com/macdonst/SpeechRecognitionPlugin.gitとな・・・

missingのエラーなので、webpack関係ではないし、コルドバのバージョンを指摘されている訳ではない。だとしたら保存形式の関係?

という訳でpackage.jsonの中身を探索してみることに・・・

 

package.jsonの中身を見てみると、やはりバージョン形式ではなくurl形式で保存されていたので、これで読み込みができていないのでは

と思いpackage.jsonの中の“phonegap-plugin-speech-recognition”: “https://github.com/macdonst/SpeechRecognitionPlugin.git”,を

現行のバージョンである“phonegap-plugin-speech-recognition”: “0.3.0”,に変更

無事にプラグインも動作しました。npm のバージョンを変えたりしていなければこの保存形式で問題ないと思われます。

※githubのアカウントを作って公開鍵を登録しないと”https://github.com/macdonst/SpeechRecognitionPlugin.git”では読み込んでくれない

ことが判りました。gitとか登録していない人は上のようにバージョンを表記する形にしておいてください。

 

参考ー>https://ja.stackoverflow.com/questions/20541/vue-js%E3%81%AE%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88%E3%82%92%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%81%A7%E5%AE%9F%E8%A1%8C%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%99%E3%82%8B%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84

  • この記事いいね! (0)
著者:杉浦

お手軽に機能付きテーブルを作るJavaScriptライブラリDataTables

DataTables | Table plug-in for jQuery
 DataTablesはJavaScriptのみでテーブルにページネーション、検索、並び替えを付与するライブラリです。
bootstrap4のスタイルをベースにdatatablesを爆速で利用してみた(CDN利用) – Qiita
に載っているコードをJSFiddleで動かしてみたのが次です。

 きれいなインデントのHTMLコード64行だけで構成されています。要は簡単ということです。tableタグと中身を用意してidをつけて次のコードで適用してもうおおよそ完成です。

$(document).ready( function () {
    $('#myTable').DataTable();
} );

 注意点として大量のデータを扱うのには向いていない点があります。基本ブラウザで閉じて扱うことを前提としており、対象のデータ全体をJavaScriptだけで扱おうとしています。このため大量のデータ(1万件でもう辛い)を扱おうとした場合、テーブルのデータをブラウザに渡すための最初のデータ読み込みでとても時間がかかります。ajaxを用いて外部サーバと連携することで逐次読み込みも可能なのですが、そちらはフォーマットの調整が面倒な上、サーバ上で渡すデータを加工すればDataTablesを用いるまでもありません。
 欠点をあげましたが少なめのデータで機能付きのテーブルを作る際にはとてもいいものです。

  • この記事いいね! (0)
村上 著者:村上

【React-Router】history.pushで遷移先のページにデータを渡す方法

昨日の記事に引き続き、React-Router でのページ遷移について。
今回は、遷移先ページにデータを渡す方法です。
パスからパラメータを取得する方法もありますが、個人的にはこちらの方が好きですね。

 

早速、値の渡し方ですが、history.push() を下記のように指定します。

this.props.history.push({ pathname: '[遷移先パス]', state: { [変数名]: [値] }});

history.push() の引数には、遷移先パスのみを指定することが多いと思いますが、上記のように連想配列で pathnamestate をそれぞれ指定することで、遷移先にデータを渡すことができます。

なお、渡したデータについては、遷移先で下記のように指定すると、値を取得することができます。

this.props.location.state.[変数名];

渡す値は多次元配列でも問題ないので、限度はあるかと思いますが、かなりのデータを渡すことができます。
渡したい値が1つだけだった場合は、パスのパラメータで渡すのもありだと思いますが、データ数が多い場合はこちらがおすすめです。
個人的に、指定方法もこちらの方が好みですね。

 

以上、React-Router で遷移先のページにデータを渡す方法でした。

  • この記事いいね! (0)