select 改变 input 值后如何触发 jQuery 保存
支付阿杰
结论
用 jQuery 修改 datepayment 的值后,需要主动触发该字段监听的事件。
目前 autoSubmit 插件监听的是 blur,最小改动如下:
$('#datepayment').val(datet).trigger('blur');
自动保存关注的是字段值是否改变,因此更适合监听 change,并在赋值后触发该事件:
$('#datepayment').val(datet).trigger('change');
通过 JavaScript 设置 .value 或调用 .val() 时,浏览器不会自动触发 change、blur 等用户交互事件。
最小改动方案
保留现有的 autoSubmit 代码,只在更新日期后触发 blur:
$(function () {
window.datum = function () {
var payment = $('#payment').val();
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth() + 1;
var yyyy = today.getFullYear();
var datet = '';
if (payment === 'yes') {
datet = dd + '.' + mm + '.' + yyyy;
}
$('#datepayment')
.val(datet)
.trigger('blur');
};
});
即使 datepayment 没有获得焦点,jQuery 的 .trigger('blur') 也会执行已经绑定的 blur 处理函数,并发送 Ajax 请求。
推荐方案:使用 change 表示值已改变
自动保存关注的是字段值变化,而不是字段是否失去焦点。可以把插件改为监听 change:
(function ($) {
$.fn.autoSubmit = function () {
return this.each(function () {
var input = $(this);
var column = input.attr('name');
var form = input.closest('form');
var method = form.attr('method');
var action = form.attr('action');
var whereInput = form.find('#where');
var whereVal = whereInput.val();
var whereCol = whereInput.attr('name');
input.on('change', function () {
$.ajax({
url: action,
type: method,
data: {
val: input.val(),
col: column,
w_col: whereCol,
w_val: whereVal
},
cache: false,
timeout: 10000,
success: function (data) {
if (data) {
alert(data);
} else {
$('#notice')
.stop(true, true)
.text('Updated')
.fadeOut()
.fadeIn();
}
}
});
});
});
};
})(jQuery);
$(function () {
$('#ajax-form input, #ajax-form select, #ajax-form textarea').autoSubmit();
});
修改日期时,再显式触发 change:
$(function () {
$('#payment').on('change', function () {
var payment = $(this).val();
var datet = '';
if (payment === 'yes') {
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth() + 1;
var yyyy = today.getFullYear();
datet = dd + '.' + mm + '.' + yyyy;
}
$('#datepayment')
.val(datet)
.trigger('change');
});
});
无论用户手动修改字段并产生 change 事件,还是脚本通过 .trigger('change') 通知字段发生变化,都会调用同一套保存逻辑。
原代码中需要修正的问题
原来的条件语句有两个错误:
var platba = document.getElementById('payment').value;
if (payment = 'yes') {
datet = today;
}
读取结果保存在 platba 中,判断时用的却是 payment。另外,= 是赋值运算符,不是比较运算符。应改为:
var payment = document.getElementById('payment').value;
if (payment === 'yes') {
datet = today;
}
还需要显式声明 datet,以免生成隐式全局变量:
var datet = '';
注意事项
.val(newValue)只会设置值,不会自动触发change。- 不要同时触发
change和blur,否则可能发送两次 Ajax 请求。 - 如果仍要在输入框失去焦点时保存,可以监听多个事件:
input.on('change blur', function () {
// 保存
});
此时需要记录上一次保存的值,避免重复提交同一个值。
- 后端不能直接信任客户端传来的
col、w_col等字段名。应通过白名单验证允许更新的数据库列,并对值使用参数化查询,避免 SQL 注入。 - 如果
datepayment可以编辑,最好统一日期格式,并确保后端使用相同的格式解析。
备注:内容仅供参考。
