Djangoで個人的にハマった事。その3

3回目の個人的な備忘録です。
javascript絡んだところでハマったので、また開発するときにハマらないようにしよう〜。

1.HTMLテンプレート側で動的に追加した要素のイベントが発火しない
ここが一番ハマって、まる3日悩んだと思う〜〜。
正直きれいな形では解決してなくて無理矢理で-o-;
forms.pyで定義したdatetimepicker.DatePickerInputが起動しなかったり、サジェスト機能が動かなかったり。。
絶対違うと思うけど追加したフォームにはjavascript側でdatetimepickerを定義。オプションはforms.pyで定義した物と同じ値を定義。サジェスト機能はその要素が含まれている上位の要素がクリックされた事を検知するようonを定義して対応。

# forms.py
class XForm(forms.Form):
 :
 :
 :
    xDay = forms.CharField(
       initial='',
       label='X日',
       required=False,  # 必須ではない
       widget = datetimepicker.DatePickerInput(
              format='%Y/%m/%d',
              options={
                   'locale': 'ja',
                   'dayViewHeaderFormat': 'YYYY年 MMMM',
                   'ignoreReadonly': True,
                   'allowInputToggle': True
               }
       ),
 :
 :


# XXXX.htmlのjavascript部分
//追加ボタン
$('body').on('click', '.btn-add', function(){  
    {% spaceless %}
        $('#list').prepend(
            '<tr>' + 
            '<td><input type="checkbox" name="chk[]" value="0"></td>' + 
            '<td>' + '{{ addXXXXXForm.sNm }}' + '</td>' +
            '<td>' + '{{ addXXXXXForm.g }}' + '</td>' +
            '<td>' + '{{ addXXXXXForm.pCd }}' + '</td>' +
            '<td>' + '{{ addXXXXXForm.entryDay }}' + '</td>' +
            '<td>' + '{{ addXXXXXForm.status }}' + '</td>' +
            '<td>' + '{{ addXXXXXForm.pCd }}' + '</td>' +
            '<td>' + '{{ addXXXXXForm.biko }}' + '</td>' +
            '<td>' + 
            '<input type="button" class="btn-save btn btn-sm btn-info" value="保存" name="">' + 
            '<input type="button" class="btn-delete btn btn-sm btn-danger" value="削除" name="" style="display: none;">' +
            '</td>' + 
            '</tr>'
        );
   {% endspaceless %}
     :
     :
     :
    //追加した要素にもカレンダーイベントを登録
    $('input#id_xDay.form-control').datetimepicker({
           showClose: true,
           showClear: true,
           showTodayButton: true, 
           locale: "ja",
           dayViewHeaderFormat: "YYYY年 MMMM",
           ignoreReadonly: true,
           allowInputToggle: true,
           format: "YYYY/MM/DD",
    });
 });

// サジェスト機能
$('body').on('keyup', '.suggest', function(){
    

2.HTMLテンプレート側で動的に要素を追加する時に空白を除去するforms.pyで定義したカスタマイズしたwigetが出力するhtmlが余計なところで改行されて出力されるため、エラーが発生する。
そのため、定義したjavascriptが動作しない。
{% spaceless %}{% endspaceless %}で括って改行を除く。
公式ドキュメントではブロック内の HTML タグ間にある空白文字やタブ文字も含んで除去するとの事。

//追加ボタン
$('body').on('click', '.btn-add', function(){  
    {% spaceless %}
        $('#list').prepend(
            '<tr>' + 
            '<td><input type="checkbox" name="chk[]" value="0"></td>' + 
            '<td>' + '{{ addXXXXXForm.sNm }}' + '</td>' +
            '<td>' + '{{ addXXXXXForm.g }}' + '</td>' +
            '<td>' + '{{ addXXXXXForm.pCd }}' + '</td>' +
            '<td>' + '{{ addXXXXXForm.entryDay }}' + '</td>' +
            '<td>' + '{{ addXXXXXForm.status }}' + '</td>' +
            '<td>' + '{{ addXXXXXForm.pCd }}' + '</td>' +
            '<td>' + '{{ addXXXXXForm.biko }}' + '</td>' +
            '<td>' + 
            '<input type="button" class="btn-save btn btn-sm btn-info" value="保存" name="">' + 
            '<input type="button" class="btn-delete btn btn-sm btn-danger" value="削除" name="" style="display: none;">' +
            '</td>' + 
            '</tr>'
        );
   {% endspaceless %}
     :
     :
     :

3.イベントを登録する時に引数を渡す方法
javascriptでサジェスト機能を実装する時に候補をクリックしたら、どの入力フォームに値を入れるかを判断したかったので引数を追加したかった。
オブジェクトとして渡すみたい。

function clickSuggest(e) {
   // サジェスト表示欄内のアイテムをクリックした際の処理
   const element = e.target;
   if (element.dataset.pk === '-1') {
       return;
   }
   // ★this.indexで引数として定義した値が取得できる
   $(`[id=${element.dataset.target}-input]`)[this.index].value = element.textContent;
   $(`[id=${element.dataset.target}-value]`)[this.index].value = element.dataset.pk;
};

$('body').on('keyup', '.suggest', function(){
    :
    :# 関係ないので省略
    :    
    for (const obj of response.object_list) {
        const li = document.createElement('li');
        li.textContent = obj.name;
        li.dataset.target = targetName;
        li.dataset.pk = obj.pk;
        //★
        li.addEventListener('mousedown', {index: index, handleEvent: clickSuggest});
        frag.appendChild(li);
    }
    :
    :# 関係ないので省略
    :
});



この記事が気に入ったらサポートをしてみませんか?