fix(payment): 修复添加卡密页「确认提交」按钮静默失效
数字输入(auto_num / auto_price / auto_rand_number_limit / auto_rand_password_limit)此前被平铺成原生 HTML5 约束属性 (min/max/step),叠加两个问题后表现为按钮点了毫无反应: 1) 数值彼此不自洽:参考主题 CSF spinner 的 default=20 / min=1 / step=10 合法格点是 1,11,21…,默认值 20 当场就非法; auto_rand_number_limit 同理(默认 20、格点 1,6,11…)。 2) 这些行是条件显隐的(field_row 输出 <tr data-dep>,不满足依赖时 display:none)。提交时浏览器仍会校验隐藏控件,而隐藏控件无法聚焦 去弹提示气泡,于是 Chrome 只往控制台丢一句 "An invalid form control ... is not focusable" 便静默拒绝提交—— 不跳转、不报错、无 notice,用户看到的就是按钮坏了。 处置:数字输入改用 data-min/data-max/data-step + step="any" (与参考主题 CSF_Field_spinner::render() 语义一致),不再写任何原生 约束属性;auto_price 一并去掉 min="0",面额下限改由服务端夹取兜底 (max(0.0, ...)),避免「去掉客户端下限」变成放行负面额。 验证: - 无头 Chrome 探针:btn.click() 触发的 submit 事件 0 → 1, 参与校验控件 23 个、无效 3 个 → 0 个; - 服务端扫描页面 25 个 input:带原生约束的 0 个; - 服务端面额夹取:-5 拒绝、0.001 拒绝、12.5 正常生成 1 张; - 新增 tests/admin/charge-cards-form-constraints.test.cjs(4 例), 并做负向对照(重引入 min/step 后 2 pass / 2 fail); - tests/admin 四个套件合计 22 pass / 0 fail。
This commit is contained in:
@@ -346,7 +346,7 @@ class PayChargeCards {
|
||||
);
|
||||
$this->field_row(
|
||||
__('面额', 'aksrt'),
|
||||
'<input type="number" step="0.01" min="0" name="auto_price" value="0" />',
|
||||
'<input type="number" step="any" name="auto_price" value="0" />',
|
||||
[
|
||||
['key' => 'add_type', 'op' => '==', 'val' => 'auto'],
|
||||
['key' => 'type', 'op' => 'any', 'val' => 'balance,credits'],
|
||||
@@ -703,6 +703,9 @@ class PayChargeCards {
|
||||
case 'balance':
|
||||
case 'credits':
|
||||
$auto_price = isset($_REQUEST['auto_price']) ? floatval(round((float) $_REQUEST['auto_price'], 2)) : 0;
|
||||
// 面额不接受负数。数字输入不再写原生 min(见 spinner() 注释:原生约束会让条件隐藏行
|
||||
// 阻止表单提交),因此下限由服务端兜底。
|
||||
$auto_price = max(0.0, $auto_price);
|
||||
if (!$auto_price) {
|
||||
$this->page_notice(__('错误!', 'aksrt'), __('请输入卡密的面额', 'aksrt'), 'error');
|
||||
return;
|
||||
@@ -999,8 +1002,25 @@ class PayChargeCards {
|
||||
return $html . '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* 数字输入(对齐参考主题 CSF spinner 字段的语义)。
|
||||
*
|
||||
* **min / max / step 只放在 data-* 上,绝不写成原生约束属性。**
|
||||
* 参考主题 `CSF_Field_spinner::render()` 渲染的就是
|
||||
* `data-min/data-max/data-step` + `step="any"`,原生 min/max/step 一个都不写。
|
||||
* 移植时把它们平铺成原生属性,会引入两类问题:
|
||||
* 1) 这些值彼此不自洽 —— 例如 default=20 / min=1 / step=10 的合法格点是 1,11,21…,
|
||||
* 写成原生 step 会让**默认值当场非法**(20 不在格点上);
|
||||
* 2) 本表单的行是条件显隐的。HTML5 约束校验会检查**隐藏**控件,而隐藏控件无法聚焦、
|
||||
* 浏览器弹不出提示气泡,于是直接**静默拒绝提交**(只有控制台一句
|
||||
* "An invalid form control ... is not focusable"),页面毫无反应 ——
|
||||
* 用户看到的就是「确认提交按钮不起作用」。
|
||||
* 取值范围由服务端兜底:`ChargeCard::generate_cards()` 内已对数量与位数做 max/min 夹取。
|
||||
*/
|
||||
private function spinner(string $name, int $value, int $min, int $max, int $step, string $unit): string {
|
||||
return '<input type="number" class="small-text" name="' . esc_attr($name) . '" value="' . esc_attr((string) $value) . '" min="' . esc_attr((string) $min) . '" max="' . esc_attr((string) $max) . '" step="' . esc_attr((string) $step) . '" /> <span class="description">' . esc_html($unit) . '</span>';
|
||||
return '<input type="number" class="small-text" step="any" name="' . esc_attr($name) . '" value="' . esc_attr((string) $value) . '"'
|
||||
. ' data-min="' . esc_attr((string) $min) . '" data-max="' . esc_attr((string) $max) . '" data-step="' . esc_attr((string) $step) . '" />'
|
||||
. ' <span class="description">' . esc_html($unit) . '</span>';
|
||||
}
|
||||
|
||||
private function page_notice(string $title, string $msg, string $type = 'success'): void {
|
||||
|
||||
Reference in New Issue
Block a user