Edited at

inputにURLしか入らないようにしたい&リアルタイムに制限をかけたい

More than 1 year has passed since last update.

Vue.jsでシンプルな入力制限の副産物というか本命というか。


要件


  • 指定した形式の文字列以外入らないようにして欲しい

  • 指定した形式の一つはURL

  • つまり、単にURLとしてvalidな文字列の連続ではなく、http(s)://までは順番に、それ以降はURLとしてvalidな文字列の連続としなければならない


    • 面倒くさい




実装例


Vueによる実装

<template>

<main id="app"><main id="app">
<h1>VueでURL入力制限</h1>
<table>
<tbody>
<tr>
<th>URL:</th><td><input type="text" pattern="^(https?://[\w/:%#\$&\?\(\)~\.=\+\-]*|https?:/|https?:|https?|htt|ht|h)" maxlength="100" :value="test1" @input="test1=opt(test1,$event)"></td>
</tr>
</tbody>
</table>
</main>
</template>
<script>
var vue = new Vue({
el:'#app',
data:{
test1:'',
},
methods:{
opt:function(oldVal,e){
var re = new RegExp(e.target.pattern);
var result = re.exec(e.target.value);

return e.target.value = (result)?result[0]:oldVal;
}
}
})
</script>



DEMO

http://jsrun.it/hadakadenkyu/22SK/


解説

HTML5のinputにはpatternというプロパティが追加され、これをに正規表現を入れるとバリデーションがかけられる。


patternの例

<form>

<input type="text" pattern="[0-9]*" value="" placeholder="数字のみ">
<button type="submit" value="送信">
</form>

ただし、見ての通り値は入力されてしまう。

これを、そもそもinvalidなら入力できないようにするにはinputイベントの度にvalidateをかける必要がある(実装例ではVueでやっている)。

しかし、その場合でも数字のみやアルファベットのみ、というのはいいのだが、今回のようにURLを入力させたい場合、単にURLとしてvalidな文字列の連続を定めるとhttpから始まらない文字列が入力可能になってしまう

そこで、正規表現のORを表すメタ文字(|)を利用し、validな場合を全て列挙する

このとき、前にあるパターンが優先的に引っかかるため、長いパターンから順に記述する。


蛇足

正直プロトコルをチェックボックスにしてドメイン名以降を入力させたほうがスマートだと思う。

ただ日本語を見て英単語を打たせるタイピングゲームみたいのには使えそう。