diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue
index 0a8f080f3..f1019e7ae 100644
--- a/src/components/VnTable/VnTable.vue
+++ b/src/components/VnTable/VnTable.vue
@@ -373,16 +373,20 @@ function handleSelection({ evt, added, rows: selectedRows }, rows) {
}
}
-function isEditableColumn(column) {
- const isEditableCol = column?.isEditable ?? true;
+function isEditableColumn(column, row) {
+ const isEditableCol =
+ typeof column?.isEditable == 'function'
+ ? column?.isEditable(row)
+ : (column?.isEditable ?? true);
+
const isVisible = column?.visible ?? true;
const hasComponent = column?.component;
return $props.isEditable && isVisible && hasComponent && isEditableCol;
}
-function hasEditableFormat(column) {
- if (isEditableColumn(column)) return 'editable-text';
+function hasEditableFormat(column, row) {
+ if (isEditableColumn(column, row)) return 'editable-text';
}
const clickHandler = async (event) => {
@@ -394,6 +398,7 @@ const clickHandler = async (event) => {
if (isDateElement || isTimeElement || isQSelectDropDown) return;
if (clickedElement === null) {
+ console.log('destroyInput 1');
await destroyInput(editingRow.value, editingField.value);
return;
}
@@ -404,17 +409,25 @@ const clickHandler = async (event) => {
if (editingRow.value !== null && editingField.value !== null) {
if (editingRow.value == rowIndex && editingField.value == colField) return;
+ console.log('destroyInput 2');
await destroyInput(editingRow.value, editingField.value);
}
- if (isEditableColumn(column)) {
+ if (
+ isEditableColumn(
+ column,
+ CrudModelRef.value.formData[rowIndex ?? editingRow.value],
+ )
+ ) {
await renderInput(Number(rowIndex), colField, clickedElement);
}
};
async function handleTabKey(event, rowIndex, colField) {
- if (editingRow.value == rowIndex && editingField.value == colField)
+ if (editingRow.value == rowIndex && editingField.value == colField) {
+ console.log('destroyInput 3');
await destroyInput(editingRow.value, editingField.value);
+ }
const direction = event.shiftKey ? -1 : 1;
const { nextRowIndex, nextColumnName } = await handleTabNavigation(
@@ -426,6 +439,7 @@ async function handleTabKey(event, rowIndex, colField) {
if (nextRowIndex < 0 || nextRowIndex >= arrayData.store.data.length) return;
event.preventDefault();
+ console.log('nextColumnName: ', nextColumnName);
await renderInput(nextRowIndex, nextColumnName, null);
}
@@ -467,16 +481,21 @@ async function renderInput(rowId, field, clickedElement) {
await column?.cellEvent?.['update:modelValue']?.(value, oldValue, row);
},
keyup: async (event) => {
- if (event.key === 'Enter')
+ if (event.key === 'Enter') {
+ console.log('destroyInput 4');
await destroyInput(rowId, field, clickedElement);
+ }
},
keydown: async (event) => {
switch (event.key) {
case 'Tab':
+ console.log('field: ', field);
+ console.log('target: ', event.target);
await handleTabKey(event, rowId, field);
event.stopPropagation();
break;
case 'Escape':
+ console.log('destroyInput 5');
await destroyInput(rowId, field, clickedElement);
break;
default:
@@ -511,6 +530,10 @@ async function updateSelectValue(value, column, row, oldValue) {
}
async function destroyInput(rowIndex, field, clickedElement) {
+ const column = $props.columns.find((col) => col.name === field);
+ if (typeof column?.beforeDestroy === 'function')
+ await column.beforeDestroy(CrudModelRef.value.formData[rowIndex]);
+
if (!clickedElement)
clickedElement = document.querySelector(
`[data-row-index="${rowIndex}"][data-col-field="${field}"]`,
@@ -523,6 +546,7 @@ async function destroyInput(rowIndex, field, clickedElement) {
child.style.position = '';
});
}
+
if (editingRow.value !== rowIndex || editingField.value !== field) return;
editingRow.value = null;
editingField.value = null;
@@ -540,7 +564,13 @@ async function handleTabNavigation(rowIndex, colName, direction) {
iterations++;
newColumnIndex = (newColumnIndex + direction + totalColumns) % totalColumns;
- if (isEditableColumn(columns[newColumnIndex])) break;
+ if (
+ isEditableColumn(
+ columns[newColumnIndex],
+ CrudModelRef.value.formData[rowIndex],
+ )
+ )
+ break;
} while (iterations < totalColumns);
if (iterations >= totalColumns + 1) return;
@@ -840,19 +870,19 @@ const handleHeaderSelection = (evt, data) => {
: getToggleIcon(row[col?.name])
"
style="color: var(--vn-text-color)"
- :class="hasEditableFormat(col)"
+ :class="hasEditableFormat(col, row)"
size="14px"
/>
{
beforeEach(() => {
- cy.login('developer');
+ cy.login('buyer');
cy.visit(`/#/item/list`);
});
it('should filter the items and redirect to the summary', () => {
- cy.dataCy('Category_select').type('Plant');
- cy.get('.q-menu .q-item').contains('Plant').click();
- cy.dataCy('Type_select').type('Anthurium');
- cy.get('.q-menu .q-item').contains('Anthurium').click();
+ cy.selectOption('[data-cy="Category_select"]', 'Plant');
+ cy.selectOption('[data-cy="Type_select"]', 'Anthurium');
cy.get('.q-virtual-scroll__content > :nth-child(4) > :nth-child(4)').click();
+ cy.url().should('include', '/summary');
});
it('should create an item', () => {
@@ -24,8 +23,6 @@ describe('Item list', () => {
cy.fillInForm(data);
cy.dataCy('FormModelPopup_save').click();
cy.checkNotification('Data created');
- cy.get(
- ':nth-child(2) > .q-drawer > .q-drawer__content > .q-scrollarea > .q-scrollarea__container > .q-scrollarea__content',
- ).should('be.visible');
+ cy.url().should('include', '/basic-data');
});
});