Skip to content

Bug: e.preventDefault is not a function when clicking upload inside form (v4.18.13) #3267

Description

@abcabc0330

Bug Report: e.preventDefault is not a function when clicking upload button inside VbenForm

Version: vxe-table 4.18.13
Vue: 3.5.34
Browser: Chrome
Link: https://github.com/x-extends/vxe-table/issues


Description

When clicking an upload button (or any non-input element that triggers form value change) inside a vxe-table form, the following error occurs:

TypeError: e.preventDefault is not a function
    at prevent (vendor-vxe.js:3:67059)
    at vendor-vxe.js:3:67506
    ...

The prevent function in Ql (event helper object) blindly calls e.preventDefault() without checking whether e is a valid Event object:

Ql = {
  stop: e => e.stopPropagation(),
  prevent: e => e.preventDefault(),  // ← crash here when e is not Event
  self: e => e.target === e.currentTarget,
}

Reproduction Steps

  1. Use vxe-table with useVbenForm (Vben admin form integration)
  2. Add a form field with an upload component (e.g. CustomPdfDisplay or FileUpload)
  3. Click the upload button to trigger file selection
  4. The form value change triggers vxe-table's internal event system
  5. prevent() receives a non-Event object → error

Root Cause

The prevent helper in Ql at table/src/table.js line 67059 (compiled) does not guard against non-Event objects:

// Current (unsafe):
prevent: e => e.preventDefault()

// Expected (safe):
prevent: e => e?.preventDefault?.()

Or more defensively:

prevent: e => {
  if (e && typeof e.preventDefault === 'function') {
    e.preventDefault();
  }
}

Related Code

Located in lib/table/src/table.js around the Ql helper object:

var Ql = {
  stop: e => e.stopPropagation(),
  prevent: e => e.preventDefault(),  // unsafe
  self: e => e.target === e.currentTarget,
};

This Ql object is used in various event handling contexts (keydownEvent, handleGlobalKeydownEvent, pointerDownOutside, etc.). Some of these callers may pass non-Event objects, especially when the table is embedded in a form system that programmatically triggers value changes.

Suggested Fix

Add a type guard to prevent:

prevent: e => {
  if (e && typeof e.preventDefault === 'function') {
    e.preventDefault();
  }
}

This is a safe, backward-compatible change that won't break any existing functionality.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions