An issues-only repository for the Bryntum project management component suite which includes powerful Grid, Scheduler, Calendar, Kanban Task Board and Gantt chart components all built in pure JS / CSS / TypeScript
I have implemented a custom menu column along with the menu event listeners. I had posted some queries regarding this in the forum viewtopic.php?t=27647 which were resolved.
However, there is one issue. On the page load, if we open the actions menu for different rows in the grid a few times, the menu stops showing for those rows. For the first 5 to 6 times we open the actions menu, it shows fine. After that, sometimes it flickers i.e. shows for less than a second and then disappears or does not show up at all. This is happening on the latest bryntum grid demo as well.
I have provided a basic example which can be tested here https://bryntum.com/products/grid/examples/celledit/"
import { Widget, Menu, EventHelper, Grid, DataGenerator, DateHelper } from '../../build/grid.module.js?473556';
import shared from '../_shared/shared.module.js?473556';
const menu = new Menu({
anchor : false,
autoShow : false,
align : 't-b',
items : [
{
icon : 'fa-thin fa-info',
cls : 'viewAssetDetails',
html : `<a>View Details<\a>`,
onItem({source, item}) {
debugger;
var gridObj = source.up('grid'),
element = source.parent.owner.element.closest('.b-grid-row'),
asset = gridObj.getRecordFromElement(element);
}
}]
});
// YesNo is a custom button that toggles between Yes and No on click
class YesNo extends Widget {
static get $name() {
return 'YesNo';
}
// Factoryable type name
static get type() {
return 'yesno';
}
// Hook up a click listener during construction
construct(config) {
// Need to pass config to super (Widget) to have things set up properly
super.construct(config);
// Handle click on the element
EventHelper.on({
element : this.element,
click : 'onClick',
thisObj : this
});
}
// Always valid, this getter is required by CellEdit feature
get isValid() {
return true;
}
// Get current value
get value() {
return Boolean(this._value);
}
// Set current value, updating style
set value(value) {
this._value = value;
this.syncInputFieldValue();
}
// Required by CellEdit feature to update display value on language locale change
// Translation is added to examples/_shared/locales/*
syncInputFieldValue() {
const
{
element,
value
} = this;
if (element) {
element.classList[value ? 'add' : 'remove']('yes');
element.innerText = value ? this.L('L{Object.Yes}') : this.L('L{Object.No}');
}
}
// Html for this widget
template() {
return `<button class="yesno"></button>`;
}
// Click handler
onClick() {
this.value = !this.value;
}
}
// Register this widget type with its Factory
YesNo.initClass();
let newPlayerCount = 0;
const grid = new Grid({
appendTo : 'container',
features : {
cellEdit : true,
sort : 'name',
stripe : true
},
// Show changed cells
showDirty : true,
async validateStartDateEdit({ grid, value }) {
if (value > DateHelper.clearTime(new Date())) {
return grid.features.cellEdit.confirm({
title : 'Selected date in future',
message : 'Update field?'
});
}
return true;
},
columns : [
{ text : 'Name', field : 'name', flex : 1 },
{
text : 'Birthplace',
field : 'city',
width : '8em',
editor : { type : 'dropdown', items : DataGenerator.cities }
},
{ text : 'Team', field : 'team', flex : 1 },
{ text : 'Score', field : 'score', editor : 'number', width : '5em' },
{
text : 'Start',
id : 'start',
type : 'date',
field : 'start',
width : '9em',
finalizeCellEdit : 'up.validateStartDateEdit'
},
{ text : 'Finish (readonly)', type : 'date', field : 'finish', width : '9em', editor : false },
{ text : 'Time', id : 'time', type : 'time', field : 'time', width : '10em' },
// Column using the custom widget defined above as its editor
{
text : 'Custom', // `text` gets localized automatically, is added to examples/_shared/locales/*
field : 'done',
editor : 'yesno',
width : '5em',
renderer : ({ value }) => value ? YesNo.L('L{Object.Yes}') : YesNo.L('L{Object.No}')
},
{ type : 'percent', text : 'Percent', field : 'percent', flex : 1 },
{
type: 'widget',
text: '',
minWidth: 30,
maxWidth: 50,
htmlEncode: false,
cls: 'text-center hidden-xs',
cellCls: 'hidden-xs',
hidden: false, // Set to false to make the column initially visible
hideable: false, // Set to false to prevent the user from hiding the column
widgets : [
{
type: 'button',
flex : 1,
menu,
}
]
}
],
data : DataGenerator.generateData(50),
listeners : {
selectionChange({ selection }) {
removeButton.disabled = !selection.length || grid.readOnly;
}
},
tbar : [
{
type : 'button',
ref : 'readOnlyButton',
text : 'Read-only',
tooltip : 'Toggles read-only mode on grid',
toggleable : true,
icon : 'b-fa-square',
pressedIcon : 'b-fa-check-square',
onToggle : ({ pressed }) => {
addButton.disabled = insertButton.disabled = grid.readOnly = pressed;
removeButton.disabled = pressed || !grid.selectedRecords.length;
}
},
{
type : 'buttongroup',
items : [
{
type : 'button',
ref : 'addButton',
icon : 'b-fa-plus-circle',
text : 'Add',
tooltip : 'Adds a new row (at bottom)',
onAction : () => {
const
counter = ++newPlayerCount,
added = grid.store.add({
name : `New player ${counter}`,
cls : `new_player_${counter}`
});
grid.selectedRecord = added[0];
}
},
{
type : 'button',
ref : 'insertButton',
icon : 'b-fa-plus-square',
text : 'Insert',
tooltip : 'Inserts a new row (at top)',
onAction : () => {
const
counter = ++newPlayerCount,
added = grid.store.insert(0, {
name : `New player ${counter}`,
cls : `new_player_${counter}`
});
grid.selectedRecord = added[0];
}
}
]
},
{
type : 'button',
ref : 'removeButton',
color : 'b-red',
icon : 'b-fa b-fa-trash',
text : 'Remove',
tooltip : 'Removes selected record(s)',
disabled : true,
onAction : () => {
const selected = grid.selectedRecords;
if (selected && selected.length) {
const
store = grid.store,
nextRecord = store.getNext(selected[selected.length - 1]),
prevRecord = store.getPrev(selected[0]);
store.remove(selected);
grid.selectedRecord = nextRecord || prevRecord;
}
}
}
]
});
const { addButton, removeButton, insertButton } = grid.widgetMap;
// Show the dirty marker
grid.store.getAt(0).score = 200;
Forum post
"Hi
I have implemented a custom menu column along with the menu event listeners. I had posted some queries regarding this in the forum viewtopic.php?t=27647 which were resolved. However, there is one issue. On the page load, if we open the actions menu for different rows in the grid a few times, the menu stops showing for those rows. For the first 5 to 6 times we open the actions menu, it shows fine. After that, sometimes it flickers i.e. shows for less than a second and then disappears or does not show up at all. This is happening on the latest bryntum grid demo as well. I have provided a basic example which can be tested here https://bryntum.com/products/grid/examples/celledit/"
https://github.com/bryntum/support/assets/16693227/ca8d437a-f2b6-45c6-8371-21996f40d88b