We have a reasonable layout for the table-editor in the specialist. To be further refined.
This commit is contained in:
@@ -41,17 +41,17 @@ configuration:
|
|||||||
required: false
|
required: false
|
||||||
competency_details:
|
competency_details:
|
||||||
title:
|
title:
|
||||||
name: "title"
|
name: "Title"
|
||||||
description: "Competency Title"
|
description: "Competency Title"
|
||||||
type: "str"
|
type: "str"
|
||||||
required: true
|
required: true
|
||||||
description:
|
description:
|
||||||
name: "description"
|
name: "Description"
|
||||||
description: "Description (in context of the role) of the competency"
|
description: "Description (in context of the role) of the competency"
|
||||||
type: "text"
|
type: "text"
|
||||||
required: true
|
required: true
|
||||||
is_knockout:
|
is_knockout:
|
||||||
name: "Is Knockout"
|
name: "KO"
|
||||||
description: "Defines if the competency is a knock-out criterium"
|
description: "Defines if the competency is a knock-out criterium"
|
||||||
type: "boolean"
|
type: "boolean"
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
@@ -33,21 +33,47 @@ window.EveAI.OrderedListEditors = {
|
|||||||
// Create column definitions from list type
|
// Create column definitions from list type
|
||||||
const columns = this._createColumnsFromListType(listTypeConfig);
|
const columns = this._createColumnsFromListType(listTypeConfig);
|
||||||
|
|
||||||
|
// Debug log for data and columns
|
||||||
|
console.log('Data for Tabulator:', data);
|
||||||
|
console.log('Columns for Tabulator:', columns);
|
||||||
|
|
||||||
|
// Debug log for column titles
|
||||||
|
console.log('Column titles:', columns.map(col => col.title || ''));
|
||||||
|
|
||||||
// Initialize Tabulator
|
// Initialize Tabulator
|
||||||
try {
|
try {
|
||||||
console.log('Creating Tabulator for', containerId);
|
console.log('Creating Tabulator for', containerId);
|
||||||
const table = new Tabulator(container, {
|
const table = new Tabulator(container, {
|
||||||
data: data || [],
|
data: data || [],
|
||||||
columns: columns,
|
columns: columns,
|
||||||
layout: "fitColumns",
|
layout: "fitColumns", // Changed to fitColumns to ensure columns display horizontally
|
||||||
movableRows: true,
|
movableRows: true,
|
||||||
height: "400px",
|
{#rowHeader: {headerSort:false, resizable: false, minWidth:30, width:30, rowHandle:true, formatter:"handle"},#}
|
||||||
|
maxHeight: "50%", // Auto height to display all rows
|
||||||
|
placeholder: "No Data Available",
|
||||||
|
autoResize: false,
|
||||||
|
resizableColumnFit: true,
|
||||||
|
responsiveLayout: false,
|
||||||
|
tooltips: true, // Enable tooltips
|
||||||
|
tooltipsHeader: true,
|
||||||
|
selectable: false, // Disable row selection to prevent jumping
|
||||||
|
selectableRangeMode: "click", // Only select on click, not on drag
|
||||||
|
selectableRollingSelection: false, // Disable rolling selection
|
||||||
|
scrollToRowIfVisible: false, // Don't scroll to row even if it's already visible
|
||||||
|
scrollToRowPosition: "nearest",
|
||||||
...options
|
...options
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('Tabulator created for', containerId);
|
console.log('Tabulator created for', containerId);
|
||||||
container.classList.add('tabulator-initialized');
|
container.classList.add('tabulator-initialized');
|
||||||
|
|
||||||
|
// Debug: Log table structure
|
||||||
|
console.log('Table structure:', {
|
||||||
|
tableElement: container,
|
||||||
|
tableData: table.getData(),
|
||||||
|
tableColumns: table.getColumnDefinitions()
|
||||||
|
});
|
||||||
|
|
||||||
// Add row button
|
// Add row button
|
||||||
const addRowBtn = document.createElement('button');
|
const addRowBtn = document.createElement('button');
|
||||||
addRowBtn.className = 'btn btn-sm btn-primary mt-2';
|
addRowBtn.className = 'btn btn-sm btn-primary mt-2';
|
||||||
@@ -56,21 +82,65 @@ window.EveAI.OrderedListEditors = {
|
|||||||
const newRow = {};
|
const newRow = {};
|
||||||
// Create empty row with default values
|
// Create empty row with default values
|
||||||
Object.entries(listTypeConfig).forEach(([key, field]) => {
|
Object.entries(listTypeConfig).forEach(([key, field]) => {
|
||||||
newRow[key] = field.default || '';
|
if (field.type === 'boolean') {
|
||||||
|
newRow[key] = field.default === true;
|
||||||
|
} else {
|
||||||
|
newRow[key] = field.default !== undefined ? field.default : '';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
table.addRow(newRow);
|
table.addRow(newRow);
|
||||||
this._updateTextarea(containerId, table);
|
this._updateTextarea(containerId, table);
|
||||||
});
|
});
|
||||||
container.parentNode.insertBefore(addRowBtn, container.nextSibling);
|
container.parentNode.insertBefore(addRowBtn, container.nextSibling);
|
||||||
|
|
||||||
|
// Add explode button for fullscreen mode
|
||||||
|
const explodeBtn = document.createElement('button');
|
||||||
|
explodeBtn.className = 'btn btn-sm btn-secondary mt-2 ms-2';
|
||||||
|
explodeBtn.innerHTML = '<i class="material-icons">fullscreen</i> Expand';
|
||||||
|
explodeBtn.addEventListener('click', () => {
|
||||||
|
container.classList.toggle('fullscreen-mode');
|
||||||
|
|
||||||
|
// Update button text based on current state
|
||||||
|
if (container.classList.contains('fullscreen-mode')) {
|
||||||
|
explodeBtn.innerHTML = '<i class="material-icons">fullscreen_exit</i> Collapse';
|
||||||
|
} else {
|
||||||
|
explodeBtn.innerHTML = '<i class="material-icons">fullscreen</i> Expand';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redraw table to adjust to new size
|
||||||
|
table.redraw(true);
|
||||||
|
});
|
||||||
|
container.parentNode.insertBefore(explodeBtn, addRowBtn.nextSibling);
|
||||||
|
|
||||||
// Store instance
|
// Store instance
|
||||||
this.instances[containerId] = {
|
this.instances[containerId] = {
|
||||||
table: table,
|
table: table,
|
||||||
textarea: document.getElementById(containerId.replace('-editor', ''))
|
textarea: document.getElementById(containerId.replace('-editor', ''))
|
||||||
};
|
};
|
||||||
|
|
||||||
// Update textarea on data change
|
// Prevent scrolling when clicking on cells
|
||||||
|
container.addEventListener('click', function(e) {
|
||||||
|
// Prevent the default behavior which might cause scrolling
|
||||||
|
if (e.target.closest('.tabulator-cell')) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}, { passive: false });
|
||||||
|
|
||||||
|
// Update textarea on various events that change data
|
||||||
table.on("dataChanged", () => {
|
table.on("dataChanged", () => {
|
||||||
|
console.log("dataChanged event triggered");
|
||||||
|
this._updateTextarea(containerId, table);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Listen for row movement
|
||||||
|
table.on("rowMoved", () => {
|
||||||
|
console.log("rowMoved event triggered");
|
||||||
|
this._updateTextarea(containerId, table);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Listen for cell edits
|
||||||
|
table.on("cellEdited", () => {
|
||||||
|
console.log("cellEdited event triggered");
|
||||||
this._updateTextarea(containerId, table);
|
this._updateTextarea(containerId, table);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -87,65 +157,147 @@ window.EveAI.OrderedListEditors = {
|
|||||||
_updateTextarea: function(containerId, table) {
|
_updateTextarea: function(containerId, table) {
|
||||||
const instance = this.instances[containerId];
|
const instance = this.instances[containerId];
|
||||||
if (instance && instance.textarea) {
|
if (instance && instance.textarea) {
|
||||||
instance.textarea.value = JSON.stringify(table.getData());
|
const data = table.getData();
|
||||||
|
console.log('Updating textarea with data:', data);
|
||||||
|
instance.textarea.value = JSON.stringify(data);
|
||||||
|
console.log('Textarea value updated:', instance.textarea.value);
|
||||||
|
|
||||||
|
// Trigger change event on textarea to ensure form validation recognizes the change
|
||||||
|
const event = new Event('change', { bubbles: true });
|
||||||
|
instance.textarea.dispatchEvent(event);
|
||||||
|
|
||||||
|
// Also trigger input event for any listeners that might be using that
|
||||||
|
const inputEvent = new Event('input', { bubbles: true });
|
||||||
|
instance.textarea.dispatchEvent(inputEvent);
|
||||||
|
} else {
|
||||||
|
console.error('Cannot update textarea: instance or textarea not found for', containerId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_getListTypeConfig: function(listType) {
|
_getListTypeConfig: function(listType) {
|
||||||
// This would need to be implemented to fetch the list type configuration
|
// Try to get the list type configuration from window.listTypeConfigs
|
||||||
// Could be from a global variable set in the template or via an API call
|
if (window.listTypeConfigs && window.listTypeConfigs[listType]) {
|
||||||
return window.listTypeConfigs && window.listTypeConfigs[listType];
|
return window.listTypeConfigs[listType];
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not found, log a warning and return a default configuration
|
||||||
|
console.warn(`List type configuration for ${listType} not found in window.listTypeConfigs. Using a default configuration.`);
|
||||||
|
return {
|
||||||
|
title: {
|
||||||
|
name: "Title",
|
||||||
|
description: "Title",
|
||||||
|
type: "str",
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
name: "Description",
|
||||||
|
description: "Description",
|
||||||
|
type: "text",
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
// Custom formatter for text columns to truncate text in normal mode
|
||||||
|
_truncateFormatter: function(cell, formatterParams, onRendered) {
|
||||||
|
const value = cell.getValue();
|
||||||
|
const maxLength = formatterParams.maxLength || 100;
|
||||||
|
|
||||||
|
if (value && value.length > maxLength) {
|
||||||
|
// Create a truncated version with "..." and show more indicator
|
||||||
|
const truncated = value.substring(0, maxLength) + "...";
|
||||||
|
|
||||||
|
// Return HTML with truncated text and a "show more" button
|
||||||
|
return `<div class="truncated-cell">
|
||||||
|
<div class="truncated-content">${truncated}</div>
|
||||||
|
<div class="show-more" title="Click to edit and see full text">
|
||||||
|
<i class="material-icons">more_horiz</i>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
},
|
},
|
||||||
|
|
||||||
_createColumnsFromListType: function(listTypeConfig) {
|
_createColumnsFromListType: function(listTypeConfig) {
|
||||||
const columns = [];
|
const columns = [];
|
||||||
|
|
||||||
// Add drag handle column for row reordering
|
|
||||||
columns.push({
|
|
||||||
formatter: "handle",
|
|
||||||
headerSort: false,
|
|
||||||
frozen: true,
|
|
||||||
width: 30,
|
|
||||||
minWidth: 30
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add columns for each field in the list type
|
// Add columns for each field in the list type
|
||||||
Object.entries(listTypeConfig).forEach(([key, field]) => {
|
Object.entries(listTypeConfig).forEach(([key, field]) => {
|
||||||
const column = {
|
const column = {
|
||||||
title: field.name || key,
|
title: field.name || key,
|
||||||
field: key,
|
field: key,
|
||||||
tooltip: field.description
|
headerTooltip: field.description,
|
||||||
|
headerSort: false,
|
||||||
|
visible: true,
|
||||||
|
resizable: "header",
|
||||||
};
|
};
|
||||||
|
console.log("Column ", field.name, " type: ", field.type)
|
||||||
|
// Set width based on field type
|
||||||
|
if (field.type === 'boolean') {
|
||||||
|
column.minWidth = 50;
|
||||||
|
column.maxWidth = 80; // Limit maximum width
|
||||||
|
column.widthGrow = 0; // Don't allow boolean columns to grow
|
||||||
|
} else if (field.type === 'text') {
|
||||||
|
column.width = 400; // Much larger width for text columns (especially description)
|
||||||
|
column.minWidth = 300; // Ensure text columns have adequate minimum width
|
||||||
|
column.widthGrow = 2; // Allow text columns to grow significantly more
|
||||||
|
} else {
|
||||||
|
column.width = 150; // Default width for other columns
|
||||||
|
column.minWidth = 100;
|
||||||
|
column.widthGrow = 1; // Allow some growth
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure consistent width calculation
|
||||||
|
column.widthShrink = 0; // Don't allow shrinking below minWidth
|
||||||
|
|
||||||
// Set editor based on field type
|
// Set editor based on field type
|
||||||
if (field.type === 'boolean') {
|
if (field.type === 'boolean') {
|
||||||
column.formatter = 'tickCross';
|
column.formatter = 'tickCross';
|
||||||
column.editor = 'tickCross';
|
column.editor = 'tickCross';
|
||||||
column.hozAlign = 'center';
|
column.hozAlign = 'center';
|
||||||
|
column.headerHozAlign = 'center';
|
||||||
|
column.formatterParams = {
|
||||||
|
allowEmpty: true,
|
||||||
|
allowTruthy: true,
|
||||||
|
tickElement: "<i class='material-icons'>check_circle</i>",
|
||||||
|
crossElement: "<i class='material-icons'>cancel</i>"
|
||||||
|
};
|
||||||
} else if (field.type === 'enum' && field.allowed_values) {
|
} else if (field.type === 'enum' && field.allowed_values) {
|
||||||
column.editor = 'select';
|
column.editor = 'select';
|
||||||
column.editorParams = {
|
column.editorParams = {
|
||||||
values: field.allowed_values
|
values: field.allowed_values
|
||||||
};
|
};
|
||||||
|
column.hozAlign = 'left';
|
||||||
|
column.headerHozAlign = 'left';
|
||||||
|
} else if (field.type === 'text') {
|
||||||
|
column.editor = 'textarea';
|
||||||
|
column.formatter = this._truncateFormatter; // Use custom formatter to truncate text
|
||||||
|
column.variableHeight = true;
|
||||||
|
// Configure formatter parameters
|
||||||
|
column.formatterParams = {
|
||||||
|
maxLength: 50,
|
||||||
|
autoResize: true
|
||||||
|
};
|
||||||
|
// Prevent scrolling when editing text cells
|
||||||
|
column.editorParams = {
|
||||||
|
elementAttributes: {
|
||||||
|
preventScroll: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
column.hozAlign = 'left';
|
||||||
|
column.headerHozAlign = 'left';
|
||||||
} else {
|
} else {
|
||||||
column.editor = 'input';
|
column.editor = 'input';
|
||||||
|
column.hozAlign = 'left';
|
||||||
|
column.headerHozAlign = 'left';
|
||||||
}
|
}
|
||||||
|
|
||||||
columns.push(column);
|
columns.push(column);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add delete button column
|
// We don't add a delete button column as per requirements
|
||||||
columns.push({
|
// to prevent users from deleting rows
|
||||||
formatter: function(cell, formatterParams, onRendered) {
|
|
||||||
return "<button class='btn btn-sm btn-danger'><i class='material-icons'>delete</i></button>";
|
|
||||||
},
|
|
||||||
width: 40,
|
|
||||||
hozAlign: "center",
|
|
||||||
headerSort: false,
|
|
||||||
cellClick: function(e, cell) {
|
|
||||||
cell.getRow().delete();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return columns;
|
return columns;
|
||||||
},
|
},
|
||||||
@@ -176,8 +328,17 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
// Initialize ordered list editors
|
// Initialize ordered list editors
|
||||||
document.querySelectorAll('.ordered-list-field').forEach(function(textarea) {
|
document.querySelectorAll('.ordered-list-field').forEach(function(textarea) {
|
||||||
const containerId = textarea.id + '-editor';
|
const containerId = textarea.id + '-editor';
|
||||||
const container = document.getElementById(containerId);
|
console.log('Initializing ordered list editor for', containerId);
|
||||||
if (!container) return;
|
|
||||||
|
// Create container if it doesn't exist
|
||||||
|
let container = document.getElementById(containerId);
|
||||||
|
if (!container) {
|
||||||
|
container = document.createElement('div');
|
||||||
|
container.id = containerId;
|
||||||
|
container.className = 'ordered-list-editor';
|
||||||
|
textarea.parentNode.insertBefore(container, textarea.nextSibling);
|
||||||
|
textarea.classList.add('d-none'); // Hide the textarea
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = textarea.value ? JSON.parse(textarea.value) : [];
|
const data = textarea.value ? JSON.parse(textarea.value) : [];
|
||||||
@@ -185,7 +346,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
|
|
||||||
// Check if we have the list type configuration
|
// Check if we have the list type configuration
|
||||||
if (listType && !window.listTypeConfigs[listType]) {
|
if (listType && !window.listTypeConfigs[listType]) {
|
||||||
console.warn(`List type configuration for ${listType} not found. The editor may not work correctly.`);
|
console.warn(`List type configuration for ${listType} not found. Using default configuration.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.EveAI.OrderedListEditors.initialize(containerId, data, listType);
|
window.EveAI.OrderedListEditors.initialize(containerId, data, listType);
|
||||||
@@ -203,19 +364,57 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
/* Tabulator styling */
|
/* Tabulator styling */
|
||||||
.ordered-list-editor {
|
.ordered-list-editor {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
|
min-height: 200px; /* Minimum height, will expand as needed */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure the Tabulator container has a proper height */
|
/* Make sure the Tabulator container has a proper height */
|
||||||
.ordered-list-editor .tabulator {
|
.ordered-list-editor .tabulator {
|
||||||
height: 400px;
|
height: auto; /* Auto height to display all rows */
|
||||||
|
min-height: 200px; /* Minimum height */
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: 1px solid #dee2e6;
|
border: 1px solid #dee2e6;
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure the table holder has a scrollbar */
|
||||||
|
.ordered-list-editor .tabulator-tableholder {
|
||||||
|
/* overflow-y: auto !important; - Removed to allow Tabulator to handle overflow */
|
||||||
|
/* max-height: calc(100% - 42px) !important; - Removed to allow Tabulator to handle height */
|
||||||
|
/* Consider using non-!important values if specific scrolling behavior is needed */
|
||||||
|
overflow-y: auto;
|
||||||
|
max-height: calc(100% - 42px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style for the table element */
|
||||||
|
.ordered-list-editor .tabulator-table {
|
||||||
|
display: table !important; /* Force display as table */
|
||||||
|
width: 100% !important;
|
||||||
|
table-layout: fixed !important; /* Use fixed table layout for consistent column widths */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Style for the handle column */
|
/* Style for the handle column */
|
||||||
.ordered-list-editor .tabulator-row-handle {
|
.ordered-list-editor .tabulator-row-handle {
|
||||||
cursor: move;
|
cursor: move;
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
border-right: 1px solid #dee2e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style for the handle bars to make them more visible */
|
||||||
|
.ordered-list-editor .tabulator-row-handle-box {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ordered-list-editor .tabulator-row-handle-bar {
|
||||||
|
background: #666;
|
||||||
|
display: inline-block;
|
||||||
|
width: 10px;
|
||||||
|
height: 2px;
|
||||||
|
margin: 1px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Style for the delete button */
|
/* Style for the delete button */
|
||||||
@@ -228,4 +427,133 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
.ordered-list-editor .tabulator-cell[data-type="boolean"] {
|
.ordered-list-editor .tabulator-cell[data-type="boolean"] {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Style for the table header */
|
||||||
|
.ordered-list-editor .tabulator-header {
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
border-bottom: 2px solid #dee2e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style for the headers container */
|
||||||
|
.ordered-list-editor .tabulator-headers {
|
||||||
|
display: table-row !important; /* Force display as table row */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style for the header cells */
|
||||||
|
.ordered-list-editor .tabulator-col {
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
padding: 8px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
display: table-cell !important; /* Force display as table cell */
|
||||||
|
box-sizing: border-box !important; /* Include padding in width calculation */
|
||||||
|
position: relative !important; /* Ensure proper positioning */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Override any inline styles that might hide column headers */
|
||||||
|
.ordered-list-editor .tabulator-col[style*="display: none"] {
|
||||||
|
display: table-cell !important; /* Force display as table cell */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure header cells have the same width as their corresponding data cells */
|
||||||
|
.ordered-list-editor .tabulator-col,
|
||||||
|
.ordered-list-editor .tabulator-cell {
|
||||||
|
{#width: auto !important; /* Let the table-layout: fixed handle the width */#}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style for the header cell content */
|
||||||
|
.ordered-list-editor .tabulator-col-title {
|
||||||
|
white-space: normal; /* Allow header text to wrap */
|
||||||
|
word-break: break-word; /* Break words to prevent horizontal overflow */
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style for the table rows */
|
||||||
|
.ordered-list-editor .tabulator-row {
|
||||||
|
border-bottom: 1px solid #dee2e6;
|
||||||
|
display: table-row !important; /* Force display as table row */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style for the table cells */
|
||||||
|
.ordered-list-editor .tabulator-cell {
|
||||||
|
padding: 8px;
|
||||||
|
white-space: normal; /* Allow text to wrap */
|
||||||
|
overflow: visible; /* Show overflowing content */
|
||||||
|
height: auto !important; /* Allow cell to grow as needed */
|
||||||
|
word-break: break-word; /* Break words to prevent horizontal overflow */
|
||||||
|
display: table-cell !important; /* Force display as table cell */
|
||||||
|
scroll-margin-top: 100px; /* Prevent unwanted scrolling when focusing */
|
||||||
|
scroll-behavior: auto; /* Disable smooth scrolling which might cause jumping */
|
||||||
|
font-size: 0.85rem; /* Smaller font size */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style for truncated cells */
|
||||||
|
.ordered-list-editor .truncated-cell {
|
||||||
|
position: relative;
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ordered-list-editor .truncated-content {
|
||||||
|
white-space: normal;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ordered-list-editor .show-more {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
color: #007bff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style for the visible cells */
|
||||||
|
.ordered-list-editor .tabulator-cell-visible {
|
||||||
|
display: table-cell !important; /* Force display as table cell */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Override any inline styles that might hide cells */
|
||||||
|
.ordered-list-editor .tabulator-cell[style*="display: none"] {
|
||||||
|
display: table-cell !important; /* Force display as table cell */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style for the textarea editor */
|
||||||
|
.ordered-list-editor .tabulator-cell textarea {
|
||||||
|
min-height: 60px;
|
||||||
|
resize: vertical;
|
||||||
|
width: 100%; /* Ensure textarea fills the cell */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style for the placeholder */
|
||||||
|
.ordered-list-editor .tabulator-placeholder {
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
color: #6c757d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style for the Add Row button */
|
||||||
|
.ordered-list-editor + .btn-primary {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fullscreen mode styles */
|
||||||
|
.ordered-list-editor.fullscreen-mode {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
z-index: 9999;
|
||||||
|
background: white;
|
||||||
|
padding: 20px;
|
||||||
|
margin: 0;
|
||||||
|
overflow: auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ordered-list-editor.fullscreen-mode .tabulator {
|
||||||
|
height: calc(100vh - 100px) !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -69,8 +69,9 @@
|
|||||||
<div id="{{ field.id }}-editor" class="json-editor-container"></div>
|
<div id="{{ field.id }}-editor" class="json-editor-container"></div>
|
||||||
{{ field(class="form-control d-none " + class, disabled=disabled, readonly=readonly) }}
|
{{ field(class="form-control d-none " + class, disabled=disabled, readonly=readonly) }}
|
||||||
{% elif field.type == 'OrderedListField' or 'ordered-list-field' in field_class %}
|
{% elif field.type == 'OrderedListField' or 'ordered-list-field' in field_class %}
|
||||||
{# Behoud ordered-list-field class en voeg form-control toe #}
|
{# Create container for ordered list editor and hide the textarea #}
|
||||||
{{ field(class="form-control " + field_class|trim, disabled=disabled, readonly=readonly) }}
|
<div id="{{ field.id }}-editor" class="ordered-list-editor"></div>
|
||||||
|
{{ field(class="form-control d-none " + field_class|trim, disabled=disabled, readonly=readonly) }}
|
||||||
{% elif field.type == 'SelectField' %}
|
{% elif field.type == 'SelectField' %}
|
||||||
{{ field(class="form-control form-select " + class, disabled=disabled, readonly=readonly) }}
|
{{ field(class="form-control form-select " + class, disabled=disabled, readonly=readonly) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
@@ -449,4 +450,3 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
|||||||
@@ -13,11 +13,15 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
// Initialize tooltips
|
// Initialize tooltips if bootstrap is available
|
||||||
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
|
if (typeof bootstrap !== 'undefined') {
|
||||||
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
|
||||||
return new bootstrap.Tooltip(tooltipTriggerEl)
|
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||||||
});
|
return new bootstrap.Tooltip(tooltipTriggerEl)
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.warn('Bootstrap is not defined. Tooltips will not be initialized.');
|
||||||
|
}
|
||||||
|
|
||||||
// De JSON editor initialisatie is hierboven al samengevoegd.
|
// De JSON editor initialisatie is hierboven al samengevoegd.
|
||||||
// Deze dubbele DOMContentLoaded listener en .json-editor initialisatie kan verwijderd worden.
|
// Deze dubbele DOMContentLoaded listener en .json-editor initialisatie kan verwijderd worden.
|
||||||
@@ -47,9 +51,12 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
|
|
||||||
// Find and click the corresponding tab button
|
// Find and click the corresponding tab button
|
||||||
const tabButton = document.querySelector(`[data-bs-toggle="tab"][data-bs-target="#${tabId}"]`);
|
const tabButton = document.querySelector(`[data-bs-toggle="tab"][data-bs-target="#${tabId}"]`);
|
||||||
if (tabButton) {
|
if (tabButton && typeof bootstrap !== 'undefined') {
|
||||||
const tab = new bootstrap.Tab(tabButton);
|
const tab = new bootstrap.Tab(tabButton);
|
||||||
tab.show();
|
tab.show();
|
||||||
|
} else if (tabButton) {
|
||||||
|
// Fallback if bootstrap is not available
|
||||||
|
tabButton.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scroll the invalid field into view and focus it
|
// Scroll the invalid field into view and focus it
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ import * as Popper from '@popperjs/core';
|
|||||||
window.Popper = Popper; // Maak het globaal beschikbaar als Bootstrap het extern verwacht.
|
window.Popper = Popper; // Maak het globaal beschikbaar als Bootstrap het extern verwacht.
|
||||||
|
|
||||||
// Bootstrap JavaScript
|
// Bootstrap JavaScript
|
||||||
import 'bootstrap'; // Importeert alle BS JS componenten.
|
import * as bootstrap from 'bootstrap'; // Importeer Bootstrap als object
|
||||||
|
window.bootstrap = bootstrap; // Maak bootstrap globaal beschikbaar
|
||||||
|
|
||||||
// Bootstrap's JS koppelt zichzelf meestal aan jQuery en gebruikt Popper.
|
// Bootstrap's JS koppelt zichzelf meestal aan jQuery en gebruikt Popper.
|
||||||
// Als je 'bootstrap' als object nodig hebt (bijv. voor new bootstrap.Modal()), importeer het dan als:
|
// Als je 'bootstrap' als object nodig hebt (bijv. voor new bootstrap.Modal()), importeer het dan als:
|
||||||
// import * as bootstrap from 'bootstrap';
|
// import * as bootstrap from 'bootstrap';
|
||||||
@@ -42,8 +44,7 @@ import { createJSONEditor } from 'vanilla-jsoneditor';
|
|||||||
// Maak de factory functie globaal beschikbaar als je dit elders in je code gebruikt.
|
// Maak de factory functie globaal beschikbaar als je dit elders in je code gebruikt.
|
||||||
window.createJSONEditor = createJSONEditor;
|
window.createJSONEditor = createJSONEditor;
|
||||||
|
|
||||||
import { Tabulator } from 'tabulator-tables';
|
import './tabulator-setup.js';
|
||||||
window.Tabulator = Tabulator;
|
|
||||||
|
|
||||||
// Eventueel een log om te bevestigen dat de bundel is geladen
|
// Eventueel een log om te bevestigen dat de bundel is geladen
|
||||||
console.log('JavaScript bibliotheken gebundeld en geladen via main.js.');
|
console.log('JavaScript bibliotheken gebundeld en geladen via main.js.');
|
||||||
|
|||||||
8
nginx/frontend_src/js/tabulator-setup.js
Normal file
8
nginx/frontend_src/js/tabulator-setup.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// CSS importeren
|
||||||
|
import 'tabulator-tables/dist/css/tabulator.min.css';
|
||||||
|
|
||||||
|
// JavaScript imports
|
||||||
|
import { TabulatorFull as Tabulator } from 'tabulator-tables';
|
||||||
|
|
||||||
|
// Maak Tabulator globaal beschikbaar
|
||||||
|
window.Tabulator = Tabulator;
|
||||||
4
nginx/static/dist/main.js
vendored
4
nginx/static/dist/main.js
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user