海滨擎蟹

form 表单增加清空按钮,reset 方法无法清空

在写之前有预感,好像之前遇到这样的问题,找了一下,果然:input 标签中 reset 重置按钮点击后表单不能清空的原因

看了一下,比较有帮助的是一个概念:绑定点击事件先执行,将 value 值设置为空字串,然后执行表单重置。所以之前的处理逻辑,就是把属性去掉,选中状态去掉,这样默认的 type="reset" 类型操作就不会只恢复到修改之前的值。

当前情况是 PHP 嵌入式写法,使用 $form 表单参数记住搜索表单中的各项值,之后再渲染表单,把值带进去。有个高级搜索的按钮,会切换搜索和清空按钮的位置,这样直接绑定的点击事件就无法生效。所以需要在点击高级搜索的方法中,动态绑定,或者使用事件委托到 document 或者 body(deepseek)。两种都试过,最终采用标记为最靠谱的事件委托。

<button class="float-left btn btn-default clear-button" type="reset">清空</button>
.
.
.
$("body").on('click', '.clear-button', function(e) {
.
.
.
});

考虑到有些复杂的组件或者自定义组件,需要手动去修改,不能触发表单的 reset 方法,所以需要阻止表单默认重置行为。让 deepseek 出了一版针对通用输入元素的处理,之后再测试,对特殊的组件需要调用特别的方法处理。于是有了下面这版:

// 重新绑定清空按钮点击事件
        $("body").on('click', '.clear-button', function(e) {
            // 正确阻止表单默认重置行为
            e.preventDefault();
            console.log('事件委托:清除按钮被点击');

            // 清空表单逻辑 | 表单的 reset 是还原而非期望的设置为空或者默认选择项,需要手动修改
            var $form = $(this).closest('form');

            // 遍历表单所有输入元素
            $form.find('input, select, textarea').each(function() {
                var $element = $(this);
                var type = this.type || this.tagName.toLowerCase();

                switch(type) {
                    case 'text':
                    case 'password':
                    case 'email':
                    case 'tel':
                    case 'url':
                    case 'search':
                    case 'number':
                    case 'textarea':
                        $element.val('');
                        break;

                    case 'checkbox':
                    case 'radio':
                        $element.prop('checked', false);
                        break;

                    case 'select-one':
                    case 'select-multiple':
                        // 对于下拉框,设置为 -1 或第一个选项
                        if ($element.find('option[value="-1"]').length > 0) {
                            $element.val('-1');
                        } else {
                            $element.prop('selectedIndex', 0);
                        }
                        break;


                    case 'button':
                        // 不做任何处理
                        break;

                    case 'hidden':
                        // 根据需求决定是否清空hidden字段
                        // $element.val(''); // 如果需要清空hidden字段
                        break;

                    default:
                        $element.val('');
                }

                // 触发change事件,让其他监听器知道值已改变
                $element.trigger('change');
            });

            // 特殊处理
            // 组织机构清空
            $('input.clean').trigger('click');
            // 清空所有bootstrap-select组件
            $form.find('.selectpicker').each(function() {
                var $select = $(this);
                var isMultiple = $select.prop('multiple');

                if (isMultiple) {
                    // 多选框:使用空数组
                    $select.selectpicker('val', []);
                } else {
                    // 单选框:使用空字符串
                    $select.selectpicker('val', '');
                }

                // 刷新组件
                $select.selectpicker('refresh');
            });
        });

遇到的 select 都有一个名为"选择所有"、值为 -1 的选择项,所以统一处理,不然就得在特殊处理添加:

$('select[name="xx"], select[name="yy"]').val(-1).trigger('change');

最后处理的是 bootstrap-select 组件。发现单独 select 修改之后,选择项没有清空,还是之前的选择项。看了一下 html 结构,发现除了 select(原始,值)之外,还有一个 dropdown 下拉的 ul>li 的部分漏掉了。问 deepseek 拿到清空处理的方法。

当前页面是本站的「Google AMP」版。查看和发表评论请点击:完整版 »