【JQuery】スマホ・タブレットでも使える、ひらがなソフトウェアキーボードを作ってみた

Javascript,開発

おはようございます。

今日はまた久しぶりに JQuery の話し。
まあ JQuery じゃなくてもいいんですが、簡単に実装できちゃうので使いますよね。

スマホやタブレットでは入力欄にフォーカスすると端末のキーボードが出てきますが、
それがちょっと使いにくい画面なんかでは自前でキーボードを実装した方がいい場合がありますよね。

スポンサーリンク

画面

こういった感じの、クリックして要素を表示する(メニューなど)ような動作を実現する場合は、
リスト要素(ul,li)を使うことが多いのですが、ちょっと自分が使いたい場面はテーブルの方が都合がよかったので。

常に全ての文字を表示しないのも、画面が狭い場合を考慮してのものです。

css

a:focus, *:focus { 
	outline:none; 
}
.table-bordered > tbody > tr > td {
	border: solid 2px #cccccc;
}

.dropdown > div.selected {
    display: block;
}

.dropdown a {
	display:block;
    padding: 10px 0px;
	color: black;
    text-decoration: none;
}

.table-bordered > tbody > tr > td.dropdown:hover {
	background-color: #f4c7aa;
}

.dropdown-content {
    display: none;
    position: absolute;
    background-color: #fcf8e3;
    z-index: 1;
    width: 50px;
    top: 56px;
    left: 0px;
}
.dropdown.selected > div {
    display: block;
}

.dropdown-content a {
    color: black;
    padding: 10px 0px;
    text-decoration: none;
    display: block;
    border: 1px solid #f4f4f4;
    width: 50px;
    height:50px;
}

.dropdown-content a:hover {
	background-color: #f4c7aa;
}

.form-group {
	margin:10px;
}

 

html

画面は、Bootstrapでちょっと見やすい感じにました。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta http-equiv="content-type" content="text/html; charset=UTF-8">
	<meta name="viewport" content="width=device-width">
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
	<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
	<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">
	<link rel="stylesheet" href="css/sample.css">
	<script type="text/javascript" src="js/sample.js"></script>
</head>
<div class="wrapper">
	<div class="container-fluid">
		<div class="row">
			<table class="table table-bordered table-keybord" style="margin: 0px;">
				<tr>
					<td class="text-center warning dropdown"><a href="#">あ</a><div class="dropdown-content"><a href="#">い</a><a href="#">う</a><a href="#">え</a><a href="#">お</a></div></td>
					<td class="text-center warning dropdown"><a href="#">か</a><div class="dropdown-content"><a href="#">き</a><a href="#">く</a><a href="#">け</a><a href="#">こ</a></div></td>
					<td class="text-center warning dropdown"><a href="#">さ</a><div class="dropdown-content"><a href="#">し</a><a href="#">す</a><a href="#">せ</a><a href="#">そ</a></div></td>
					<td class="text-center warning dropdown"><a href="#">た</a><div class="dropdown-content"><a href="#">ち</a><a href="#">つ</a><a href="#">て</a><a href="#">と</a></div></td>
					<td class="text-center warning dropdown"><a href="#">な</a><div class="dropdown-content"><a href="#">に</a><a href="#">ぬ</a><a href="#">ね</a><a href="#">の</a></div></td>
					<td class="text-center warning dropdown"><a href="#">は</a><div class="dropdown-content"><a href="#">ひ</a><a href="#">ふ</a><a href="#">へ</a><a href="#">ほ</a></div></td>
					<td class="text-center warning dropdown"><a href="#">ま</a><div class="dropdown-content"><a href="#">み</a><a href="#">む</a><a href="#">め</a><a href="#">も</a></div></td>
					<td class="text-center warning dropdown"><a href="#">や</a><div class="dropdown-content"><a href="#">ゆ</a><a href="#">よ</a></div></td>
					<td class="text-center warning dropdown"><a href="#">ら</a><div class="dropdown-content"><a href="#">り</a><a href="#">る</a><a href="#">れ</a><a href="#">ろ</a></div></td>
					<td class="text-center warning dropdown"><a href="#">わ</a><div class="dropdown-content"><a href="#">を</a></div></td>
					<td class="text-center warning dropdown"><a href="#">ん</a><div class="dropdown-content"><a href="#">ー</a></div></td>
					<td class="text-center warning dropdown"><a href="#" class="dakuten">゛</a></td>
					<td class="text-center warning dropdown"><a href="#" class="handaku">゜</a></td>
					<td class="text-center warning dropdown"><a href="#" class="komoji">小</a></td>
					<td class="text-center warning dropdown"><a href="#" class="backspace"><i class="fa fa-backspace" /></a></td>
				</tr>
			</table>
		</div>
		<div class="row">
			<form class="form-inline">
				<div class="form-group">
					<label>テキスト:</label>
					<input id="input-text" type="text" class="form-control" placeholder="入力">
				</div>
			</form>
		</div>
	</div>
</div>

</html>

 

スクリプト

javascript

var voiced_list = {
	'か' : ['か', 'が'],
	'き' : ['き', 'ぎ'],
	'く' : ['く', 'ぐ'],
	'け' : ['け', 'げ'],
	'こ' : ['こ', 'ご'],
	'さ' : ['さ', 'ざ'],
	'し' : ['し', 'じ'],
	'す' : ['す', 'ず'],
	'せ' : ['せ', 'ぜ'],
	'そ' : ['そ', 'ぞ'],
	'た' : ['た', 'だ'],
	'ち' : ['ち', 'ぢ'],
	'つ' : ['つ', 'づ'],
	'て' : ['て', 'で'],
	'と' : ['と', 'ど'],
	'は' : ['は', 'ば', 'ぱ'],
	'ひ' : ['ひ', 'び', 'ぴ'],
	'ふ' : ['ふ', 'ぶ', 'ぷ'],
	'へ' : ['へ', 'べ', 'ぺ'],
	'ほ' : ['ほ', 'ぼ', 'ぽ'],
}

var lower_case = {
	'あ' : ['あ', 'ぁ'],
	'い' : ['い', 'ぃ'],
	'う' : ['う', 'ぅ'],
	'え' : ['え', 'ぇ'],
	'お' : ['お', 'ぉ'],
	'つ' : ['つ', 'っ'],
	'や' : ['や', 'ゃ'],
	'ゆ' : ['ゆ', 'ゅ'],
	'よ' : ['よ', 'ょ'],
	'わ' : ['わ', 'ゎ'],
}

$(function(){

	// 文字クリック
	$(".dropdown a").on("click", function(){
		
		$(this).parents(".dropdown").siblings().removeClass("selected");

		// サイズ調整
		$(".dropdown-content").css("width", $(this).parents(".dropdown").css("width"));

		$(".dropdown-content a").css("width", $(this).parents(".dropdown").css("width"));

		
		// 1回選択でキーボード表示
		// 2回目の選択で文字入力
		if ($(this).parents(".dropdown").hasClass("selected")) {
			setString(this, $("#input-text"));
			$(this).parents(".dropdown").removeClass("selected");
		} else {
			$(this).parents(".dropdown").addClass("selected");
		}
		
		// 削除、濁点、半濁点、小文字は別途処理する
		if ($(this).attr("class")) {
			console.log("child other")
			$(this).parents(".dropdown").removeClass("selected");
			setString(this, $("#input-text"));
		}
	});
	
	// フィルタ以外の場所が選択されたら閉じる
	$(".wrapper").on("click", function(event) {
		var target = $(event.target).parents();
		if (!target.hasClass("dropdown")) {
			$(target).find("td.selected, div.selected").removeClass("selected");
		}
	});
});


/**
 * 濁点、半濁点に変換
 */
function convertChar(str, mode) {
	
	if (mode == 3) {
		for (item in lower_case) {
			var hira = lower_case[item][0];
			var lowe = lower_case[item][1];
			
			if (str == hira) {
				return lowe;
			} else if (str == lowe) {
				return hira;
			}
		}
	
	} else {
		for (item in voiced_list) {
			var hira = voiced_list[item][0];
			var daku = voiced_list[item][1];
			var hann = "";
			if (voiced_list[item][2]) {
				hann = voiced_list[item][2];
			}
			
			if ((str == hira || str == hann) && mode == 1) {
				return daku;
			} else if ((str == hira || str == daku) && mode == 2) {
				return hann;
			} else if (str == daku || str == hann) {
				return hira;
			}
		}
	
	}
	return str;
}

/**
 * 文字をセット
 */
function setString(element, input) {
	var value = $(input).val();
	
	// 削除
	if ($(element).hasClass("backspace")) {
		if (value.length > 0) {
			value = value.substring(0, value.length -1);
		}
		$(input).val(value);
		return;
	}

	// 濁点
	if ($(element).hasClass("dakuten")) {
		if (value.length > 0) {
			var char = value.substring(value.length -1, value.length);
			value = value.substring(0, value.length -1);
			$(input).val(value + convertChar(char, 1));
		}
		return;
	}

	// 半濁点
	if ($(element).hasClass("handaku")) {
		if (value.length > 0) {
			var char = value.substring(value.length -1, value.length);
			value = value.substring(0, value.length -1);
			$(input).val(value + convertChar(char, 2));
		}
		return;
	}
	
	// 小文字
	if ($(element).hasClass("komoji")) {
		if (value.length > 0) {
			var char = value.substring(value.length -1, value.length);
			value = value.substring(0, value.length -1);
			$(input).val(value + convertChar(char, 3));
		}
		return;
	}
	
	var text = $(element).text();
	if (text != "") {
		$(input).val(value + text);
	}
	
}

サンプルイメージ

初期表示

初期表示。
各行の頭文字を横並びに表示。

行選択

試しに「た」をクリック、た行が表示される。

文字選択

た行の中から「と」を選択、テキスト欄に入力される。

そのほか、濁音、半濁音、小文字、バックスペースに対応。

まとめ

結構使いどころは難しいかもしれませんが、
何かのお役に立てれば。

ではでは。

 

スポンサーリンク


関連するコンテンツ