使用pickadate.js选择日期时HTMX事件未触发的问题排查
问题描述
使用django-forms-dynamic包结合htmx,为MultipleChoiceField动态加载可选选项,选项基于Amsul的pickadate.js实现的日期字段。初始查询能从数据库获取正确选项,但更改日期时change事件未触发,手动触发HTMX事件也失败。
reservation_form.html
<div class="col-lg-6"> <div class="form-floating"> {% render_field reservation_form.date class="datepicker form-control mb-3" hx-get="/reservation/filter-seats" hx-include="#id_dinner" hx-trigger="click change" hx-target="#id_seat_reservation" %} <label for="id_date">晚餐日期</label> </div> <div class="form-floating"> {% render_field reservation_form.amount_guests class+="form-control" placeholder="" %} <label for="id_amount_guests">宾客人数</label> </div> <div class="visually-hidden"> {% render_field reservation_form.dinner %} </div> <div class="form-check"> {% render_field reservation_form.seat_reservation class+="form-select" %} <label for="id_seat_reservation">选择座位</label> </div> </div>
pickadate脚本
<script> var $input = $('.datepicker').pickadate({ format: 'yyyy-mm-dd', formatSubmit: 'yyyy-mm-dd', min: 0, max: 90, disable: {{ blocked_dates }}, firstDay: 1, onOpen: function() { // 获取隐藏输入字段 var hiddenInput = $(this.$node).siblings('[name="date_submit"]'); // 为隐藏输入字段添加HTMX属性 hiddenInput.attr('hx-trigger', 'change'); hiddenInput.attr('hx-get', "{% url 'filter-seats' %}"); hiddenInput.attr('hx-target', '#modal-xl'); } }); $input.on('change', function() { var hiddenInput = $(this).siblings('[name="date_submit"]'); hiddenInput.val($(this).val()); htmx.trigger(hiddenInput[0], 'change'); }); </script>
排查与解决要点
- pickadate事件绑定错误:pickadate实例不能直接用jQuery的
on('change')监听,得用它内置的onSet事件来捕获日期选择变化。 - 隐藏字段的冗余与目标错误:额外添加的隐藏字段完全没必要,而且你把它的hx-target设成了
#modal-xl,和原日期字段的#id_seat_reservation不匹配,导致更新错了元素。 - 触发对象错误:不用绕到隐藏字段,直接触发原日期输入框的HTMX事件就行——pickadate会自动把选中的日期同步到原输入框的value里。
- 修正后的脚本:
<script> var picker = $('.datepicker').pickadate({ format: 'yyyy-mm-dd', formatSubmit: 'yyyy-mm-dd', min: 0, max: 90, disable: {{ blocked_dates }}, firstDay: 1, onSet: function(context) { // 仅当用户选中日期时触发 if (context.select) { var dateInput = this.$node; // 直接触发原输入框的HTMX change事件 htmx.trigger(dateInput, 'change'); } } }); </script>
- 验证请求状态:打开浏览器开发者工具的Network面板,看日期变化时有没有发送
/reservation/filter-seats请求。没请求就是事件没触发,有请求就检查后端返回的HTML是不是正确更新了#id_seat_reservation的选项。
内容的提问来源于stack exchange,提问作者T_Torture
相关产品推荐
相关产品推荐

