地味に使える
どういうアレか
仕様として、<form>の送信にはPOSTとGETがある。POST送信された情報はURLにパラメータとして記述される。GET送信だとURLに載ることはない。
https://example.com/form/?name01=value01&name02=value02
今回の話はPOSTの動作を逆にやる感じで、要するにURLに書いた内容を<form>に放り込むのをやりたい。
そもそものところで、通常のPOSTの動作はPHPで取得してという形なので、ちょっと厄介。対象のページがPHPじゃないとか、組み込めない環境だとか、無理な場合がある。
だから汎用性を考えてjsでやっていく。
作り方と考え方
まずはURLからパラメータを拾って連想配列に格納する。記述はnameとvalueのセットとする。
https://example.com/form/?[name]=[value]&[name]=[value]&[name]=[value]
これ系は色々書いてたんだけど、うまくやると2行で済むらしい。
const urlSearchParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlSearchParams.entries());
console.log(params);
汎用性を優先して、「対象のnameが連想配列内にあるならその値をvalueに突っ込む」という内容。eachで回してるので複数のinputに対応できる。
$(function(){
const urlSearchParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlSearchParams.entries());
console.log(params);
$('input').each(function(){
var targetName = $(this).attr('name');
if(targetName in params){
$(this).val(params[targetName]);
}
})
})
で、これが使える状況は限られる。text、email、telとかの自由記入と、textareaとselectも指定すれば同じ内容でいける。checkboxとradioには使えない。
対応しないtypeは無視すればいいっちゃいいんだけど気持ち悪いならセレクタできちんと指定する。ついでにtextareaとselectも入れてしまう。全部ベタ打ちするとセレクタがめちゃくちゃ長くなってアレなので、.not()で除外分を指定してもいい。
//対応するものを指定
$('input[type="text"],input[type="tel"],input[type="email"],input[type="number"],textarea,select').each(function(){
//全部指定した上で除外するものを指定
$('input,textarea,select').not('[type="radio"],[type="checkbox"]').each(function(){
普段使うinputのtype属性は限られるけど、どっちを使うのが楽かわからなくなるくらい、実は種類がいっぱいある。都合の良い方で指定する。
radio部分の取得と出力はこんな感じ。
$('input[type="radio"]').each(function(){
var targetName = $(this).attr('name');
if(targetName in params){
$('input[name="'+targetName+'"][value="'+params[targetName]+'"]').prop('checked', true);
}
})
既にある要素にチェックを入れることになるから書き方が変わる。
checkboxはややこしい。まず、パラメータ側に記述ルールを作らなきゃいけない。
複数選択を考慮すると、配列に対応させる必要がある。そのためには受け取った文字列を配列に変換することになるので、区切り文字を何にするかを明確にしておかなきゃいけない。今回は「,」で区切るとする。nameはinputをそのまま指定する前提なので、「[]」が付いたものを書く。
?checkbox[]=aaa,bbb,ccc
で、こうなる。
$('input[type="checkbox"]').each(function(){
var targetName = $(this).attr('name');
if(targetName in params){
var valArray = params[targetName].split(',');
$.each(valArray, function(){
$('input[name="'+targetName+'"][value="'+this+'"]').prop('checked', true);
})
}
})
受け取った値をsplitで配列にして、それをeachで回す。
よく考えたら、textareaは改行が使えるわけで、それをやっていく必要がある。
$('textarea').each(function(){
var targetName = $(this).attr('name');
if(targetName in params){
$(this).val(params[targetName].replace(/\\n/g, "\n"));
}
})
改行タグは「\n」で入れるとして、これを出力すると改行タグが文字列のまま表示されちゃって改行にならないのでreplaceを噛ませる。他のinputのところでまとめてやっちゃってもいいっちゃいいけど良くないのでやっぱり分ける。
いわゆる一般的な入力フォームのタグが揃ったので、整形して完成。
完成形
$(function(){
const urlSearchParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlSearchParams.entries());
$('input,textarea,select').each(function(){
var targetName = $(this).attr('name');
if(targetName in params){
if($(this).is('[type="radio"]')){
$('input[name="'+targetName+'"][value="'+params[targetName]+'"]').prop('checked', true);
}else if($(this).is('[type="checkbox"]')){
var valArray = params[targetName].split(',');
$.each(valArray, function(){
$('input[name="'+targetName+'"][value="'+this+'"]').prop('checked', true);
})
}else if($(this).is('textarea')){
$(this).val(params[targetName].replace(/\\n/g, "\n"));
}else{
$(this).val(params[targetName]);
}
}
})
})
前項のものを並べても良いんだけど、こうすればeachを一つにまとめられる、という感じ。変数も共通なので削減できる。結局該当しない属性を指定しちゃったらって不備が残ってんだけど、まあ、変なことするやつが悪いとも言える。
パラメータの書き方はこう。
?[name]=[value]
//checkbox複数指定の場合はカンマ区切り
?[name]=[value],[value],[value]
以上。
使い方
フォームのページにjQueryと上記jsを読み込む。URL末尾にパラーメタを追加してアクセスする。
<input type="text" name="text01">
<input type="email" name="email01">
<input type="tel" name="tel01">
<textarea name="textarea01"></textarea>
<input type="checkbox" name="checkbox01[]" value="aaa">
<input type="checkbox" name="checkbox01[]" value="bbb">
<input type="checkbox" name="checkbox01[]" value="ccc">
?text01=ああああああああ&email01=hogehoge@hogehoge.jp&tel01=00011112222&textarea01=ええええ\nおおおお&checkbox01[]=aaa,bbb
まあ実際のところ、全項目をパラメータで書けるのはリスクもあると思うんで、idなり何なりで挿入できる枠を限定したほうが良いですね。
活用の話
パラメータを仕込めばフォームに自動記入されるギミックなので、広告周りとかの計測でいい感じになれる。どこから流入したかユーザー別のステータスに入力をお願いするよりは、このQRから入って申し込んでねをする方が楽だし確実という場面は結構出てくると思う。
単純に自動記入でもいいし、readonlyに突っ込んで強制するとか。
例えば申込みフォームを作ったとして、「代理店コード」付きのURLなりQRをばらまけばいいし、広告別で仕込めば流入元の集計が楽になる、どこから来ましたか・知りましたかの記入の手間をスキップできる。
コメント