jQuery在Django中出现错误:Uncaught TypeError: Cannot read property 'createDocumentFragment' of null

4
我无论如何也想不出这段代码出了什么问题。在早期版本中,它能正常工作,但在我重新排列页面底部的Javascript后,它就不能正常工作了。它一直给我报错:enter image description here
它抛出错误的代码行如下: $('.formset_row').formset({ 我使用了这个jQuery插件。它以前是完美地工作的,直到昨天我可能碰了些不应该碰的东西。
    <!-- Select2 JS -->
    <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/js/select2.min.js"></script>

    <!-- Semantic UI -->
    
   
    
    <script src="https://code.jquery.com/jquery-3.6.0.slim.min.js" integrity="sha256-u7e5khyithlIdTpu22PHhENmPcRdFiHRjhAuHcs05RI=" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.6.0/dist/umd/popper.min.js" integrity="sha384-KsvD1yqQ1/1+IA7gi3P0tyJcT3vR+NdBTt13hSJ2lnve8agRGXTTyNaBYmCR/Nwi" crossorigin="anonymous"></script>
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>
    <!-- Select2 JS -->
    <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/js/select2.min.js"></script>
    <script src="/static/js/script.js"></script>
    
    
    <script>
        /*$('body').on('focus',".my-date-picker", function(){
            $('.my-date-picker').datetimepicker({
                format: 'DD/MM/YYYY',
                ignoreReadonly: true,
                showTodayButton: true
            });
        });*/
    </script>
    <script src="/static/formset/jquery.formset.js"></script>
    <script type="text/javascript">
        $('.formset_row').formset({
            addText: '<div style="color: #34C6AA;" class="my-2 text-center"><span class="oi oi-plus"></span> Add Education</div>',
            deleteText: '<div style="color: #f4816e; text-decoration: none;" class="my-2 text-center"> <span class="oi oi-x"></span> Remove Education</div> ',
            prefix: 'educations'
        });
    </script>



</body>

编辑1:根据要求,我分享使用class formset的代码

{% extends '_base.html' %}
{% load crispy_forms_tags %}
{% load static %}



{% block content %}
</br>
    <h1 class="display-4 text-responsive">Edit your education information</h1>
<h3 class="display-6 text-muted">This will be visible on your profile</h3>
<p><span style="color: #f4816e;">IMPORTANT:</span></p>
<ul>
    <li>Leave the End Date field empty if you are currently enrolled in your school/university</li>
</ul>
<hr>    
<form method="POST" action=""> 
    {% csrf_token %} 

    {{ formset.management_form }} {# This is necessary when using formsets  #}
        {% for form in formset  %}
            
            {{ form.media }} {# This shit is responsible for showing the datepicker #}
            
            
            <div class="formset_row">
            <div class="row">
                    
                    {% if forloop.first %}
                            {% for hidden in form.hidden_fields %}
                                {{ hidden }}
                            {% endfor %}
                    {% endif %}
                    {% for field in form.visible_fields %}
                        
                            {% if field.name == "start_date" or field.name == 'end_date' %}
                                {% if  field.name == 'end_date' %}
                                    <div class="col-lg-2 col-sm-12 col-md-1">
                                        {{ field.label }} 
                                        {{ field }} </br>
                                        
                                    </div>
                                {% else %}
                                    <div class="col-lg-2 col-sm-12 col-md-1">
                                        {{ field.label }}
                                        {{ field }} </br>
                                    </div>
                                {% endif %}
                            {% elif field.name != 'DELETE' %}
                                <div class="col-lg-4 col-sm-12 col-md-4">
                                    {{ field.label }}
                                    {{ field }} </br>
                                </div>
                            {% else %}
                                {{ field }}
                            {% endif %}
                        
                        
                    {% endfor %}
            </div>
            </div>
        {% endfor %}
    
    <div class="d-block d-sm-none ">
        <input type="submit" name="save_and_next" value="Save and continue to next step" class="btn btn-success btn-block">
        <input type="submit" name="save_and_profile"value="Save and go to profile" class="btn btn-outline-info btn-block">
        <a href="{% url 'recruitment:update_coach_prof_exp' %}" class="btn btn-light btn-block">Skip step</a>
    </div>
    <div class="d-none d-md-block ">
        <input type="submit" name="save_and_next" value="Save and continue to next step" class="btn btn-success">
        <input type="submit" name="save_and_profile"value="Save and go to profile" class="btn btn-outline-info">
        <a href="{% url 'recruitment:update_coach_prof_exp' %}" class="btn btn-light">Skip step</a>
    </div>

    
</form>
<script>
    $('body').on('focus',".my-date-picker", function(){
        $(this).datetimepicker({
            format: 'DD/MM/YYYY',
            ignoreReadonly: true,
            showTodayButton: true
        });
    });
</script>
<script src="{% static 'formset/jquery.formset.js' %}"></script>
<script type="text/javascript">
    $('.formset_row').formset({
        addText: '<div style="color: #34C6AA;" class="my-2 text-center"><span class="oi oi-plus"></span> Add Education</div>',
        deleteText: '<div style="color: #f4816e; text-decoration: none;" class="my-2 text-center"> <span class="oi oi-x"></span> Remove Education</div> ',
        prefix: '{{ formset.prefix }}'
    });
</script>

{% endblock content %}

EDIT2: 我在 jQuery 插件的 insertDeleteLink 函数中添加了 console.log(row):

enter image description here

EDIT3: 添加了 jQuery 插件第 76 行及以上的内容: enter image description here

最终编辑:

enter image description here

最终我通过查找一个更新版本的插件并将整个代码替换来解决了这个问题。合并后,我发现问题出在 jQuery 插件设置上。

我对 jQuery 知之甚少,无法解释为什么之前它不起作用,而现在却可以。我只能说,在插件设置的第二行中,当 formTemplate 属性值为 $.data 时,它没有起作用。现在它的值为 null,所以它可以正常工作。

如果有人能在这里为我和其他人解释一下为什么出现了这个错误(它似乎突然出现了),我将奖励他们赏金。

这个问题给我带来了很大的困扰,尽管现在我已经克服了它并感到巨大的解脱,但我仍然想更好地理解发生了什么,以便下次不会被措手不及。此外,我相信许多人都会受益,因为这个特定的插件正在全网被数百甚至数千个 Django 网站使用。


1
请问您能否展示一下具有 formset_row 类的元素的 HTML 代码? - Danoram
嘿嘿嘿。。。嗯。。。有什么消息吗?这个无法解决的错误正在占据我的生活。 - Beikeni
从您的模板代码来看,对于formset上下文对象中的每个form,都会将<div class="formset_row">插入到模板中。由于javascript错误显示“无法读取null的属性...”,这意味着jquery找不到任何具有formset_row类的div。这意味着formset对象为空。除非您实际上可以在页面上看到表单,否则这只是一个猜测。 - Danoram
我确实可以在页面上看到表单! - Beikeni
我目前没有任何想法,抱歉。 - Danoram
显示剩余11条评论
1个回答

1
正如您所述,将formTemplate属性设置为null会使您的表单工作。
从插件文档中可以看到:

formTemplate

使用此选项来覆盖每次添加新表单实例时克隆的表单。如果指定了,则应该是一个jQuery选择器。

通过设置这个值,您用模板重写了整个表单元素。这就是为什么您会收到Cannot read property 'createDocumentFragment' of null错误,因为jQuery找不到.formset_row元素,因为您通过模板将其删除了。通过将formTemplate属性设置为null,插件被指示使用已经存在的元素(即不覆盖已经存在的元素),而不是模板(即使用模板覆盖已经存在的元素)。
希望这能为您解决问题。 :D

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接