quasar icon indicating copy to clipboard operation
quasar copied to clipboard

QTable - evt is undefined on @selection when using body-selection slot

Open ddenev opened this issue 2 years ago • 5 comments

What happened?

When using body-selection slot on QTable, the evt object which is passed to the @selection handler is undefined.

The @selection event handler is passed a payload object with the following 4 properties: rows, keys, adding, evt. The last one is the pointer event, when a selection checkbox is clicked with the mouse.

The problem is that when using the body-selection slot of QTable, this evt object is undefined:

<template #body-selection="scope">
  <q-checkbox v-model="scope.selected" />
</template>

The core reason why this is happening lies in the injectProp function which is defined in utils/private/inject-obj-prop.js:

export function injectProp (target, propName, get, set) {
  Object.defineProperty(target, propName, {
    get,
    set,
    enumerable: true
  })
}

injectProp is called from components/table/QTable.js:

...
hasSelectionMode.value === true && injectProp(
  data,
  'selected',
  () => isRowSelected(data.key),
  (adding, evt) => {
    updateSelection([ data.key ], [ data.row ], adding, evt)
  }
)
...

As you can see the setter for the selected property is passed 2 arguments - (adding, evt) - but object property setters can have only 1 argument. From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty:

set A function which serves as a setter for the property, or undefined if there is no setter. When the property is assigned, this function is called with one argument (the value being assigned to the property) and with this set to the object through which the property is assigned. Defaults to undefined.

What did you expect to happen?

When handling the @selection event, the passed payload should contain the event which was fired when clicking on the checkbox. This event usually contains info about kb modifiers such as Ctrl and Shift. Without this info, when using body-selection slot, it is impossible to use the checkboxes in order to implement Ctrl/Shift selection gestures.

Reproduction URL

https://jsfiddle.net/ddenev/69deofks/44/

How to reproduce?

  1. Go to the link above
  2. Click on any of the body selection checkboxes
  3. Observe the console

Flavour

Quasar CLI with Vite (@quasar/cli | @quasar/app-vite)

Areas

Components (quasar)

Platforms/Browsers

No response

Quasar info output

No response

Relevant log output

No response

Additional context

No response

ddenev avatar May 06 '22 19:05 ddenev

Nice analysis. Can you please make a PR to fix?

pdanpdan avatar May 06 '22 19:05 pdanpdan

How do I fix this?

ddenev avatar May 06 '22 19:05 ddenev

Hmm, good question, need to sleep on it. Maybe an idea will come to me

pdanpdan avatar May 06 '22 19:05 pdanpdan

TBH I'm not highly proficient in JS but please check if that could be of any help: https://devdreamz.com/question/191786-multiple-parameters-for-object-defineproperty-setter-function

ddenev avatar May 06 '22 19:05 ddenev

I am having this same issue. @ddenv that link look to be down.

mcmahonr avatar Jul 20 '22 14:07 mcmahonr

I have a userland solution (don't shoot me for it :), I know the setter should only receive 1 parameter ) https://jsfiddle.net/tcneLqjb/5/

For Qv2 split v-model in :model-value="scope.selected and @update:model-value="(val, evt) => { Object.getOwnPropertyDescriptor(scope, 'selected').set(val, evt) }"

For Qv1 split v-model in :value="scope.selected and @input="(val, evt) => { Object.getOwnPropertyDescriptor(scope, 'selected').set(val, evt) }"

pdanpdan avatar Sep 24 '22 16:09 pdanpdan

New example in docs will be available on next deployment.

rstoenescu avatar Sep 25 '22 10:09 rstoenescu