[ECAI]LIFFのフォームで選択した内容により付与するタグを変更させる

前回のやつとほぼ同じではある

動作イメージ

通常通り、回答したらタグを付与する。

radioの設問が複数あって、それぞれ選択したものに応じてタグを付与する。

なので、タグの総数は1+設問数になる。

ギミック

以前書いた内容はcheckboxでチェックしたものに応じてタグをつける内容だったんで、似てるというかほぼ一緒。

今回はcheckboxじゃなくてradioなので、設問につき回答は1個。しかし設問が複数あるよという形。

サンプル

radioが4つ並んでる状態。

<dl>
    <input type="hidden" name="col_1_title" value="****">
    <dt>****<span>*</span></dt>
    <dd>
        <ul class="aura_radiolist">
            <li><label><input type="radio" name="col_1" class="validate[required]" value="***" data-prompt-position="topLeft"><span>***</span></li>
            <li><label><input type="radio" name="col_1" class="validate[required]" value="***" data-prompt-position="topLeft"><span>***</span></li>
        </ul>
    </dd>
    <input type="hidden" name="col_2_title" value="****">
    <dt>****<span>*</span></dt>
    <dd>
        <ul class="aura_radiolist">
            <li><label><input type="radio" name="col_2" class="validate[required]" value="***" data-prompt-position="topLeft"><span>***</span></li>
            <li><label><input type="radio" name="col_2" class="validate[required]" value="***" data-prompt-position="topLeft"><span>***</span></li>
        </ul>
    </dd>
    <input type="hidden" name="col_3_title" value="****">
    <dt>****<span>*</span></dt>
    <dd>
        <ul class="aura_radiolist">
            <li><label><input type="radio" name="col_3" class="validate[required]" value="***" data-prompt-position="topLeft"><span>***</span></li>
            <li><label><input type="radio" name="col_3" class="validate[required]" value="***" data-prompt-position="topLeft"><span>***</span></li>
        </ul>
    </dd>
    <input type="hidden" name="col_4_title" value="****">
    <dt>****<span>*</span></dt>
    <dd>
        <ul class="aura_radiolist">
            <li><label><input type="radio" name="col_4" class="validate[required]" value="***" data-prompt-position="topLeft"><span>***</span></li>
            <li><label><input type="radio" name="col_4" class="validate[required]" value="***" data-prompt-position="topLeft"><span>***</span></li>
        </ul>
    </dd>

こうなる。

$(function(){
	var TagArray = {
		'key':'value',
		'key':'value',
		'key':'value',
		'key':'value',
		'key':'value',
		'key':'value',
		'key':'value',
		'key':'value',
	};
	$('form').submit(function(){
		var addTag = '****';
		var num = 1;
		for(let i = 1; i <= 4; i++){
			addTag = addTag + ',' + TagArray[$('input[name="col_'+ i"]:checked').val()];
		}
		$('input#add_tags').val(addTag);
	})
	alert(addTag);
})

submitを押したタイミングで発火。

radioのvalueをkey、対応するタグコードをvalueとした連想配列をTagArrayに格納。選択したradioのvalueを拾って連想配列からタグコードを引っ張ってくる。引っ張ってきたコードをaddTag内で文字列としてカンマ区切りで繋いで、#add_tagsのvalueに突っ込む。

今回のネックはfor文を使ってる点で、radioが複数あっても連番になってたらピンキリの指定ができるから繰り返しができるねってところ。タグコードにかかわる設問が飛び飛びだったらこれは使えない。

連想配列は設問毎に分けても良いんだけどめんどくさいからまとめてしまった。無駄な読み込みが発生しまくってるのは分かるんだけど、設問毎に配列を作ってもそれはそれでダルいんじゃないかって思ったもので。どっちもどっちじゃないかって思った。

タグ付与に関わる設問が飛び飛びなら、対象のinputに共通するclassを振るとかして、eachで回す事も考えられる。そういうことを考えると汎用性を求めだしてradioとcheckboxの併用も視野になってくるので、そうすると対象のnameはcheckboxじゃなくても[]を付けて値を配列として受け取ってバラシてってやっていく感じで組まないとだなーって。感じですね。

考え方

LIFF回答時のタグ付与は個数制限がない。「,」で連結すればいくらでも追加できる。

<input type="hidden" id="add_tags" name="add_tags" value="aaa,bbb,ccc,ddd,eee,...">

ベタ打ちだろうがjsでの挿入だろうが手段は問わないので、どうすれば効率的か、使い勝手を向上できるかを考えるゲームになる。

回答にタグが紐づいてるわけだから、現状の最適解は連想配列だと思ってる。そもそもこれしか無いわけじゃなくて、他にも手段は考えられる。inputにタグコード用のdata属性を追加しておいて、入力があるor選択があればタグコードを取得するとか。この場合に気をつけるべきはバリデーションに引っかかった後の再submitで、submitを発火トリガーにしてタグコードを連結してるもんだから、タグコードは残っちゃってるわけで、再submit時にリセットして再度取得・連結しなきゃいけない。この「リセット」を考えると連想配列でまとめておいたほうが楽じゃない?って話。inputからしかタグコードを拾わないなら良いんだけど、どれを回答するにせよ必ずくっつけるタグコードがあった場合、それはjs内で宣言しておかないといけない。散り散りで書くよりはまとめるのが手間がないよねと。htmlに手を加える必要がない、jsで完結できることは結構なメリット。

ところでこのjsは発火トリガーをsubmitにしてある。

$('form').submit(function(){

発火タイミングがバリデーションのjs(validationEngine)と被るので、厳密なところで棲み分けをするため。

$('[type="submit"]').click(function () {

submitを押したときとsubmitされたときは地味に違う。文字数を削減してミニマルにやっていくならvalidationEngineと同じところに追記すれば良かったんだけど、元々用意されてるコードに手を入れるのは抵抗があった。なので完全に分ける。

注意点

1つの連想配列で全てをまとめてるけど、ぶっちゃけこれは良くないradioのvalueが被ってたら詰む。ということで、以下のような感じで作ると安心できる。

回答毎に配列を分ける

参照元の配列を分けちゃえば安心。多次元配列にしてもいい。ちゃんとinputと配列がリンクするように組む必要があるのでそこをがんばる。そうするとinputにタグコードを仕込んだほうが楽じゃない?とも考えられるけど。

連想配列のkeyを改造する

例えばこんな感じ。

var TagArray = {
    'col_1はい':'****',
    'col_1いいえ':'****',
    'col_2はい':'****',
    'col_2いいえ':'****',
    'col_3はい':'****',
    'col_3いいえ':'****',
}

取得部分はこうなる。

addTag = addTag + ',' + TagArray['col_' + i + $('input[name="col_'+ i +'"]:checked').val()];

実務的なことをいえば、タグコードの生成とか管理を考えるとexcelを使わないと面倒がすごい。使えばkeyとvalueをセル別でまとめることになるんで、concat()で楽に連想配列が作れるんで、これもちょっと手を入れるだけだから組みやすいよねってことになる。対象になるinputのnameにある連番がリンクしてあれば視覚的にもわかりやすいし良いんじゃないですかね、どうでしょう。

コメント

タイトルとURLをコピーしました