こんにちは、みんな大好きひつじさん(@youmounlp)です。
今日はみんな大好きjQueryの記事です。
設定
- ペラアプリ
- ボタン押下でフォームをAPIへ送信
- 実際にはjQueryでイベントを拾ってAPIにはAjaxでPOST
- HTML5のバリデーション機能は使いたい
- APIのレスポンスを使ってHTMLの一部を書き換え
典型的ペラアプリ。
フォーム送信の場合、関連するイベントは以下の2つ。
clickイベント:
.on( "click", handler );
.click( handler );
submitイベント:
.on( "submit", handler );
.submit( handler );
送信ボタンとしては以下の2つ
button要素: <button></button>
input要素: <input type="button"/>
jQueryだからたいていのブラウザでは同じ挙動をしてくれると信じたい。でもスマホとPCだと差が出るかも。
click/submit x button/input x PC/スマホ
パターンが多い…。
結果から
フォーム送信の場合、<form></form>
の中で<input type="submit />"
を使う。イベントハンドラはform要素のsubmitイベントをセットする。
郵便番号検索風のサンプル
<form id="myform">
<fieldset>
<legend>郵便番号検索</legend>
<input
type='number'
name='myinput'
id='myinput'
placeholder='郵便番号を入力'
pattern="\d{7}"
required autoforcus
/>
<input
type="submit"
name="mysubmit"
id="mysubmit"
value="送信"
/>
</fieldset>
</form>
JavaScriptは以下。/cgi-bin/search.cgi
に検索APIがあるとする。
<script>
$(function(){
$("#myform").on("submit", function(event){
event.preventDefault();
var isvalidate = $("#myform")[0].checkValidity();
if (isvalidate) {
$.ajax({
url:'/cgi-bin/search.cgi',
type:'POST',
data:{
'myinput': $("#myinput").val()
}
})
.done( (data) => {
console.log(data);
})
.fail( (data) => {
console.log(data);
})
}
});
});
</script>
input要素とbutton要素は何が違うんですか〜?
同じです(機能的には)。
<input>
要素のbutton
型は完全に妥当な HTML ですが、より新しい<button>
要素が、ボタンの作成にはより好まれるようになりました。
https://developer.mozilla.org/ja/docs/Web/HTML/Element/Input/button
閉じタグつきのbutton要素のほうが中身を色々装飾できますってことらしい。
以下説明ではinput要素のみ使うけどほぼ同じだと思ってもらえれば。
ちなみに「機能的に同等」とあるが、機能を決めるのは要素ではなくtype
属性の値。
type="button"
とするとただのクリックできるだけのボタン
type="submit"
とするとフォームのsubmitイベントが発生するボタンになる。
onclickとclick、onsubmitとsubmitは何が違うんですか〜?
同じです。
This method is a shortcut for
.on( "click", handler )
This method is a shortcut for.on( "submit", handler )
https://api.jquery.com/click/
https://api.jquery.com/submit/
ショートカットってだけらしい。私は.on()
のほう使ってるけど記事中では長さの関係でショートカットのほうで表記している。
で、どう組み合わせればいいの
<input type="button />"
要素に対しては.click()
を使う。
<form></form>"
要素に対しては.submit()
を使う。
そもそも適用する対象が違う。
フォーム送信以外の汎用的なアクションの起点にしたい場合、<input type="button />"
要素を使う。
フォーム送信の場合、<form></form>
の中では<input type="submit />"
を使う。
formの中で<input type="button />"
を使い、.click()
でイベントを拾って、そのあとAjaxでpost、、、という実装もできなくはない。
けど、ユーザーに何かしらのデータを送信させる以上、ボタンの上には
<input type='text' />
なりがあるはず。これにフォーカスしている状態でEnterキーを押すと大抵のブウザではフォームを送信する。1
この場合、submitイベントが発生するので.click()
ではキャッチできない。そのため、画面更新を伴う通常のForm送信が発生する。
Ajaxを使うつもりならform要素のaction属性は何も書いてないはずなので、書いていない場合は、その画面(フォーム画面)と同じURLへのGETリクエストが発生する。
画面が更新されてAjaxの取得結果は消えるし、ブラウザのアドレスバーにGETリクエストのクエリパラメータが露出するしで、明らかに実装ミスっぽい感じになる。
なお、<input type="submit />"
の場合は、他のinput要素で誤ってEnterキーを押してフォーム送信してしまった場合でも、clickイベントは発生する仕様っぽい。なので.click()
をセットしていてもキャッチできる、けれどform要素に.submit()
が無難かな。
どっちがいいの
PC/スマホの軸でいうと、スマホの仮想キーボードはEnterキー相当のキーを押しても、submitせず次のinput要素へよしなにフォーカス遷移してくれる印象がある。
とはいえ、PC/スマホで実装をわける必要もないので、冒頭の結論で書いたとおり、form要素を使うのであれば、form要素にsubmitイベントをセットするのが一番よさそう。
というかよく考えたら本質的にキャッチしたいイベントはsubmitイベントなんだから.submit()
を使う、これだけで良いか。
まとめ
状態管理が複雑なアプリならVueやReactなんだろうけど、jQueryにはAjaxも同梱されてるし、ちょっとしたミニアプリなら必要十分感がある。自分でテンプレを作っておいて使いまわすとよさそう。
あと、ユーザーからの入力をブラウザに表示し返す場合は、適切にエスケープ処理を行い、XSSに気をつけましょう。
入力途中に誤ってフォーム送信してしまった経験が誰しも…。 ↩︎
0 件のコメント:
コメントを投稿