検索フォームを追加したいとご依頼あり。
最初からたくさんフォームを出しとくのもかっこ悪いし、
とはいえ一個一個要素を増やすのもめんどくさい。
追加ボタンで動的にまるっとコピーできないかしら、ってことでやってみました。
jQueryほんとべんり。
Add & Remove form elements dynamically
(2018/12/19変更:runnableがリンク切れしていたのでjsfiddleに引っ越し)
以下解説↓
#元のフォーム
これがないと始まらない。
フォーム全体をform-blockとしてくくり、idに番号0を振っておきます。
中の要素も同じ番号。増やすのはform-block単位。
<form method="post" action="confirm">
<div class="form-block" id="form_block[0]">
<!-- Closeボタン -->
<span class="close" title="Close" style="display: none;">-</span>
<p>Name:<input type="text" name="name[0]" id="name[0]" /></p>
<p>Sex:
<input type="radio" name="sex[0]" id="sex_male[0]" value="male" checked>male
<input type="radio" name="sex[0]" id="sex_female[0]" value="female">female
</p>
<p>Memo:<textarea name="memo[0]" id="memo[0]" rows="3"></textarea></p>
</div>
<!-- Addボタン -->
<div class="form-block" id="form_add">
<span class="add" title="Add">+</span>
</div>
</form>
#フォームの追加
Addボタンを押したら、一つ上のフォームをクローンします。
現在フォーム数はグローバル変数frm_cnt
で管理。
var original = $('#form_block\\[' + frm_cnt + '\\]');
var originCnt = frm_cnt;
var originVal = $("input[name='sex\\[" + frm_cnt + "\\]']:checked").val();
frm_cnt
をインクリメントする前にオリジナル(一つ前のフォーム)オブジェクトを取得しておく。
ラジオボタンのvalueも取っておくのは後のため。
frm_cnt++;
original
.clone()
.hide()
.insertAfter(original)
.attr('id', 'form_block[' + frm_cnt + ']') // クローンのid属性を変更。
.find("input[type='radio'][checked]").prop('checked', true)
.end() // 一度適用する
.find('input, textarea').each(function(idx, obj) {
$(obj).attr({
id: $(obj).attr('id').replace(/\[[0-9]\]+$/, '[' + frm_cnt + ']'),
name: $(obj).attr('name').replace(/\[[0-9]\]+$/, '[' + frm_cnt + ']')
});
$(obj).val('');
});
オリジナルからクローンします。
やっていることは上から順に、
1. クローンする
2. 一旦隠す
3. オリジナルの後ろに突っ込む
4. クローンしたform_blockのidを新しい番号に変更
5. ラジオボタンのデフォルト値を設定
6. 上記を一旦適用
7. text及びtextareaのidとnameを新しい番号に変更、テキストの値をクリア
// clone取得
var clone = $('#form_block\\[' + frm_cnt + '\\]');
clone.children('span.close').show();
clone.slideDown('slow');
クローンができたので表示します。
クローズボタンも一緒に。
// originalラジオボタン復元
original.find("input[name='sex\\[" + originCnt + "\\]'][value='" + originVal + "']").prop('checked', true);
で、これ。
クローンしたとき、オリジナルのラジオボタンのチェックが消えてしまうんですよね。
なのでここで戻しています。
#フォームの削除
フォーム内部に配置したCloseボタンを押すと、親フォームを削除します。
その後、全体的に番号の振り直しをします。
※[0]のフォームは消しません。
var removeObj = $(this).parent();
removeObj.fadeOut('fast', function() {
removeObj.remove();
// 番号振り直し
frm_cnt = 0;
$(".form-block[id^='form_block']").each(function(index, formObj) {
if ($(formObj).attr('id') != 'form_block[0]') {
frm_cnt++;
$(formObj)
.attr('id', 'form_block[' + frm_cnt + ']') // id属性を変更。
.find('input, textarea').each(function(idx, obj) {
$(obj).attr({
id: $(obj).attr('id').replace(/\[[0-9]\]+$/, '[' + frm_cnt + ']'),
name: $(obj).attr('name').replace(/\[[0-9]\]+$/, '[' + frm_cnt + ']')
});
});
}
});
});