AngularJS Advent Calendar 2014 の 13日目の投稿です。
javascript で全角英数字を半角英数字に変換するときは、
いつも こちら の記事を参考にさせていただいているのですが、
今回はこれをAngularJSで使ってみようと思います。
AngularJS なら即時変換も簡単!
日本語ローマ字モードで全角英数字のみ入力される、という条件で書いてみます。
(今回、記号の入力に対する処理は省略します。)
<div ng-app="myApp" ng-controller="SampleCtrl">
<input type="text" ng-model="hoge" ng-change="strReplace()" />
<p>{{hoge}}</p>
</div>
var myApp = angular.module('myApp',[]);
myApp.controller('SampleCtrl', ['$scope', function($scope) {
$scope.hoge= "";
// テキストボックスに文字が入力されたらイベント発火
$scope.strReplace = function () {
var str = $scope.hoge;
// 1文字ずつ変換されていくので、正規表現のグローバルマッチ(g)は不要
if (str.match(/[^0-9a-zA-Z]/)) {
str = str.replace(/[A-Za-z0-9]/, function(s) {
return String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
});
$scope.hoge= str;
}
};
}]);
デモはこちら
どうでしょう、入力したそばからどんどん変換されていきます!
問題点: 日本語の母音は残ってしまう
デモを動かしてみた方、お気付きかもしれません。
日本語の母音(あ、い、う、え、お) だけは半角英字に変換されず残ってしまいます。
日本語ローマ字入力の未確定文字(Enterキーを押す前の文字) への対応は
各言語共通の悩みのようで、技術Blog等にはほとんど書かれていません。
おそらくここからは個人のセンスが問われそうです。
幸い今回のサンプルでは
「ぎゃ(gya)」「ぁ(la)」「ん(n)」などの子音部分だけは変換できているので、
どうにかしなければいけないのは「あ~お」の5文字のみ。
というわけで、次のように対応してみました。
(決してスマートなやり方ではない。。。)
苦し紛れの回避策
<div ng-app="myApp" ng-controller="SampleCtrl">
<input type="text" ng-model="hoge" ng-change="strReplace()" ng-blur="vowelReplace()"/>
<p>{{hoge}}</p>
</div>
var myApp = angular.module('myApp',[]);
myApp.controller('SampleCtrl', ['$scope', function($scope) {
$scope.hoge= "";
// テキストボックスに文字が入力されたらイベント発火
$scope.strReplace = function () {
var str = $scope.hoge;
// 1文字ずつ変換されていくので、正規表現のグローバルマッチ(g)は不要
if (str.match(/[^0-9a-zA-Z]/)) {
str = str.replace(/[A-Za-z0-9]/, function(s) {
return String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
});
$scope.hoge= str;
}
};
// ***** ここからが変更箇所です *****
// 日本語母音はフォーカスアウト時に変換
$scope.vowelReplace = function () {
$scope.hoge= replaceVowel($scope.hoge);
};
}]);
function replaceVowel(str) {
// テキストボックス内に「あいうえお」が含まれていたら「aiueo」に変換するだけ。
if (str.match(/[あ-お]/g)){
str = str.replace(/[あ]/g, "a");
str = str.replace(/[い]/g, "i");
str = str.replace(/[う]/g, "u");
str = str.replace(/[え]/g, "e");
str = str.replace(/[お]/g, "o");
}
return str;
}
デモはこちら
いかがでしょうか。もっといいやり方があればコメントいただけると嬉しいです。
以上、ありがとうございました。