在一页中使用具有多个 django 表单的 jQuery datepicker

Using jQuery datepicker with multiple django forms in one page

所以我有一个创建公告表单,然后是每个公告的编辑表单,每个表单都有自己的日期选择器。我控制日期选择器的功能是:

$(function() {
    $( ".datepicker" ).datepicker({
        changeMonth: true,
        changeYear: true,
    });
});

最初我的问题是在其中一个编辑表单中使用日期选择器会更改创建表单中的字段,因为 ID 相同。我通过添加 ID(在我的 forms.py 中)解决了这个问题,如下所示:

end_date = forms.DateField(label='Expires', widget=forms.TextInput(attrs={'class':'datepicker form-control', 'id':'end_date_create'}))

end_date = forms.DateField(label='Expires', widget=forms.TextInput(attrs={'class':'datepicker form-control', 'id':'end_date_edit'}))

我的 createAnnouncement 和 EditAnnouncement 表单。但是由于我每页有多个编辑表单,所以我仍然遇到同样的问题,即在任何编辑表单上使用日期选择器只会更改顶部编辑表单的字段。我正在使用 django 小部件调整来呈现我的表单,因此它会自动生成 HTML 和 ids 以及 类 和所有内容。每个编辑表单都在一个具有唯一 ID 的 div 中,但是表单字段本身在所有表单中都被命名为相同的东西。有谁知道我如何使用 Django 小部件调整为我的表单字段生成唯一的 ID?或者也许有一些 javascript 或我可以添加到我的日期选择器函数中的东西,它告诉日期选择器更改相同 div?

中的字段的值

编辑:我的模板如下所示:

{% if boardAnnouncements %}
<h3>Announcements</h3>
    <div class="container" style="margin: 0px; padding: 0px;">
        <ul>
            {% for announcement in boardAnnouncements %}
                <div class="row" style="padding-bottom: 10px;">
                <li>
                    <div class="col-md-6">
                        <!-- display announcement content -->
                    </div>
                    <div class="col-md-6">
                        <!-- edit button calls javascript function to hide/unhide div with edit form in it -->
                        <a href="javascript:unhide_announcement('editann-{{announcement.id}}', '{{announcement.id}}')" class="btn btn-primary" style="margin-left: 10px;"><i class="fa fa-pencil" aria-hidden="true"></i> Edit</a>
                    </div>
                </div>
                <!-- each div gets unique id that corresponds to announcemt id -->
                <div id="editann-{{announcement.id}}" class="hidden">
                    <form role="form" action="/editannouncement/{{announcement.id}}/" method="post">
                            <!-- display edit form with django widget tweaks -->
                            {% csrf_token %}
                            {% for field in editAnnouncement %}
                                {% if field.errors %}
                                    <div class="form-group has-error">
                                        <label class="col-sm-2 control-label" for="id_{{ field.name }}">
                                        {{ field.label }}</label>
                                        <div class="col-sm-10">
                                            {{ field }}
                                            <span class="help-block">
                                            {% for error in  field.errors %}
                                                {{ error }}
                                            {% endfor %}
                                            </span>
                                        </div>
                                    </div>
                                {% else %}
                                    <div class="form-group">
                                        <label class="col-sm-2 control-label" for="id_{{ field.name }}">{{ field.label }}</label>
                                        <div class="col-sm-10">
                                            {{ field }}
                                            {% if field.help_text %}
                                                <p class="help-block"><small>{{ field.help_text }}</small></p>
                                            {% endif %}
                                        </div>
                                    </div>
                                {% endif %}
                            {% endfor %}
                                <div class="form-group">
                                    <div class="col-sm-offset-2 col-sm-10">
                                        <button type="submit" name="edit_announcement" class="btn btn-primary">Save</button><br><br>
                                    </div>
                                </div>
                            </form>
                </li>
                </div>
            {% endfor %} 
        </ul>
    </div>  
    {% endif %}
<div>

编辑表单生成的 HTML 是:

<div id="editann-1" class="unhidden">
    <form class="ng-pristine ng-valid" role="form" action="/editannouncement/1/" method="post">
        <input name="csrfmiddlewaretoken" value="AbTEZYmK1RF9yeom1C34IFFCj3EBrOD3" type="hidden">
        <div class="form-group">
            <label class="col-sm-2 control-label" for="id_description">Edit Description</label>
            <div class="col-sm-10">
                <textarea class="form-control" cols="40" id="id_description" name="description" rows="10"></textarea>
            </div>
        </div>
        <div class="form-group">
            <label class="col-sm-2 control-label" for="id_end_date">Expires</label>
            <div class="col-sm-10">
                <input class="datepicker form-control hasDatepicker" id="end_date_edit" name="end_date" type="text">
            </div>
        </div>
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <button type="submit" name="edit_announcement" class="btn btn-primary">Save</button><br><br>
            </div>
        </div>
    </form>
</div>
<div id="editann-2" class="unhidden">
    <form class="ng-pristine ng-valid" role="form" action="/editannouncement/2/" method="post">
        <input name="csrfmiddlewaretoken" value="AbTEZYmK1RF9yeom1C34IFFCj3EBrOD3" type="hidden">
        <div class="form-group">
            <label class="col-sm-2 control-label" for="id_description">Edit Description</label>
            <div class="col-sm-10">
                <textarea class="form-control" cols="40" id="id_description" name="description" rows="10"></textarea>
            </div>
        </div>
        <div class="form-group">
            <label class="col-sm-2 control-label" for="id_end_date">Expires</label>
            <div class="col-sm-10">
                <input class="datepicker form-control hasDatepicker" id="end_date_edit" name="end_date" type="text">
            </div>
        </div>
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <button type="submit" name="edit_announcement" class="btn btn-primary">Save</button><br><br>
            </div>
        </div>
    </form>
</div>

所以为了澄清每个 editann-# div 都有一个编辑表单(每个编辑表单都有一个日期选择器)。现在,由于所有编辑表单 "Expire" 字段的 ID id_end_date 日期选择器都会更改第一个编辑表单的值,无论我使用的是哪个日期选择器。

您不应在一页上有两个相同的 idID's must be unique。这就是造成错误的原因。

要在页面上添加多个表单,您应该使用 Formsets,它会自动确保您的 ID 是唯一的。

通过从您的代码中删除 id 属性,我能够使日期选择器正常工作。参见 this working fiddle

请注意,我必须从您粘贴的 html 中删除 hasDatepicker class,因为它实际上是由 datepicker 函数插入的 - 如果您将其留在其中造成冲突,日期选择器将不会显示。

我想出了一个涉及 javascript 和 jQuery 的解决方案。

function unhide_announcement(divID, ID) {
var item = document.getElementById(divID);
if (item) {
    /* hide/unhide div */
    item.className=(item.className=='hidden')?'unhidden':'hidden';
    /* give each end_date field a unique ID */
    var newID = 'id_end_date' + ID;
    item.querySelector('#id_end_date').id = newID;
    /* datepicker functionality */
    $(function() {                                                    
        $( '#'+newID ).datepicker({
          changeMonth: true,
          changeYear: true,
        });
      })
    }
}

由于每个编辑公告表单都是唯一的 div,我首先得到 div 然后在 div 中只有 1 个编辑公告表单所以我更改了那个 id从 id_end_dateid_end_date1 或与其关联的任何公告 ID。然后我将 jQuery 日期选择器函数更改为 select by id 而不是 class 并且它起作用了。所以当我在我的模板中调用它时,它看起来像这样:

<a href="javascript:unhide_announcement('editann-{{announcement.id}}', '{{announcement.id}}')" class="btn btn-primary">Edit</a>
<div id="editann-{{announcement.id}}" class="hidden">
    <!-- edit announcement form -->
    <form>
        ...
    </form>
</div>