Is it possible to have rows in a grid, with each row having three columns, and each column cell containing a combo and when a value is selected in a combo, the other two combos are locally filtered with entries relevant to the value selected in the first combo?
The cascading combos example you have doesn't appear to operate within a grid...
Thanks!
Ben
Re: Cascading combos in row cells
Posted: Thu Oct 03, 2019 8:54 am
by sergey.maltsev
Hi, bensullivan!
You could check this sample code.
Changing filter combo affects on Room dropdown combo.
import '../_shared/shared.js'; // not required, our example styling etc.
import Grid from '../../lib/Grid/view/Grid.js';
import '../../lib/Grid/column/NumberColumn.js';
import Store from '../../lib/Common/data/Store.js';
import '../../lib/Grid/column/PercentColumn.js';
const roomStore = new Store({
idField : 'value',
data : [
{ value : 1, text : 'One' },
{ value : 2, text : 'Two' },
{ value : 3, text : 'Three' },
{ value : 11, text : 'Eleven' },
{ value : 12, text : 'Twelve' },
{ value : 13, text : 'Thirteen' }
]
});
const filterStore = new Store({
idField : 'min',
data : [
{ min : 1, max : 9, text : 'Filter room 1-9' },
{ min : 10, max : 19, text : 'Filter room 10-19' }
]
});
const myFields = [
'person',
{ name : 'room', type : 'number' },
{ name : 'filter', type : 'number' }
];
new Grid({
appendTo : 'container',
columns : [
{
field : 'filter',
text : 'Filter',
editor : {
type : 'dropdown',
store : filterStore,
listeners : {
change : onFilterComboSelect
}
},
renderer({ record }) {
const filter = filterStore.getById(record.filter);
return filter ? filter.text : record.filter;
},
width : 200
},
{
field : 'room',
text : 'Room',
editor : {
type : 'dropdown',
store : roomStore
},
renderer({ record }) {
const room = roomStore.getById(record.room);
return room ? room.text : record.room;
},
width : 200
},
{
field : 'person',
text : 'Person',
width : 100
}
],
store : new Store({
fields : myFields,
data : [{ room : 1, filter : 1 }]
})
});
function onFilterComboSelect({ source: combo }) {
const filter = combo.record;
roomStore.filter(room => room.value >= filter.min && room.value <= filter.max);
}
Re: Cascading combos in row cells
Posted: Thu Oct 03, 2019 8:55 am
by bensullivan
Thankyou!!
Re: Cascading combos in row cells
Posted: Mon Oct 07, 2019 9:35 am
by bensullivan
Hi Sergey
I used your code to build the following:
import {Grid, WidgetHelper, Store} from './build/grid.module.js';
let column = 2;
const myFields = [
{name: 'person'},
{name: 'role'},
{name: 'team'}
];
const personStore = new Store({
idField: 'value',
data : [
{ text : 'Select...' },
{ value: 'PER-1', text : 'Bilbo Baggins' },
{ value: 'PER-2', text : 'Samwise Gamjee' },
{ value: 'PER-3', text : 'Peregrin Took' }
]
});
const roleStore = new Store({
idField: 'value',
data : [
{ text : 'Select...' },
{ value: 'ROL-1', text : 'Hobbit1', person: 'PER-1' },
{ value: 'ROL-2', text : 'Hobbit2', person: 'PER-2' },
{ value: 'ROL-3', text : 'Hobbit3', person: 'PER-3' }
]
});
const grid = new Grid({
appendTo: 'target',
features : {
cellEdit: true,
stripe: true
},
showDirty: true,
columns: [
{
field: 'person',
text: 'Person',
editor : { type : 'dropdown', store : personStore, listeners : { change : onPersonComboChange } },
renderer({ record }) {
const person = personStore.getById(record.person);
return person ? person.text : record.person;
},
width: 300,
locked: true
},
{
field: 'role',
text: 'Role',
editor : { type : 'dropdown', store : roleStore },
renderer({ record }) {
const role = roleStore.getById(record.role);
return role ? role.text : record.role;
},
width: 300,
locked: true
},
{ field: 'team', text: 'Team', width: 150, locked: true },
{ text: '2019<br>Nov', type: 'percent', field: 'capacity1', width: 60}
],
store : new Store({
fields : myFields,
data : [
{person: 'Select...', role: 'Select...', team: 'Select...', capacity1: 0}
]
})
});
function onPersonComboChange({ source: combo }) {
const filter = combo.record;
console.log(`Selected person: ${filter.data.value}`);
roleStore.filter(role => {
console.log(role.data.person == filter.data.value);
role.data.person == filter.data.value;
});
}
WidgetHelper.append([
{
type : 'button',
ref : 'removeButton',
text : 'Remove Last Month',
color : 'b-orange b-raised',
icon : 'b-fa b-fa-minus',
tooltip : 'Remove Last Month',
onAction : () => grid.columns.count > 1 && grid.columns.last.remove()
},
{
type : 'button',
ref : 'addButton',
text : 'Add Month',
color : 'b-green b-raised',
icon : 'b-fa b-fa-plus',
tooltip : 'Add new month',
onAction : () => {
const fieldName = `capacity${column++}`;
myFields.push({ name : fieldName, type : 'percent', text: 'Dec', width: 60 });
const store = new Store({
fields : myFields,
data : grid.store.records.map(r => r.data)
});
grid.store = store;
grid.refreshRows();
grid.columns.add({ text : 'Dec', type : 'percent', field : fieldName, width : 100 });
// grid.store.add({ id : grid.store.count + 1, [fieldName] : column });
// grid.columns.add({ text: 'Dec', type: 'percent', field: 'capacity2', width: 60});
}
}
], { insertFirst : document.getElementById('gridButtons') || document.body });
For some reason, the listener is firing for both person and role combos and I don' understand why. Also, the roleStore.filter call in the listener does not appear to be filtering the role dropdown contents after the listener finishes execution. Can you see what I'm doing wrong?
Thanks!
Ben
Re: Cascading combos in row cells
Posted: Mon Oct 07, 2019 11:23 am
by bensullivan
I seemed to get it working with this code:
import {Grid, Store} from './build/grid.module.js';
const personStore = new Store({
idField : 'personId',
data : [
{ personId : 'PER-1', text : 'Bilbo' },
{ personId : 'PER-2', text : 'Samwise' },
{ personId : 'PER-3', text : 'Peregrine' }
]
});
const roleStore = new Store({
idField : 'roleId',
data : [
{ roleId : 'ROL-1', text : 'Farmer', personId: 'PER-1'},
{ roleId : 'ROL-2', text : 'Cook', personId: 'PER-3' }
]
});
const myFields = [
'team',
{ name : 'person' },
{ name : 'role' }
];
new Grid({
appendTo : 'target',
columns : [
{
field : 'role',
text : 'Role',
editor : {
type : 'dropdown',
store : roleStore,
listeners : {
change : onRoleComboChange
}
},
renderer({ record }) {
const role = roleStore.getById(record.role);
return role ? role.text : record.role;
},
width : 200
},
{
field : 'person',
text : 'Person',
editor : {
type : 'dropdown',
store : personStore
},
renderer({ record }) {
const person = personStore.getById(record.person);
return person ? person.text : record.person;
},
width : 200
},
{
field : 'team',
text : 'Team',
width : 100
}
],
store : new Store({
fields : myFields,
data : [{ role : 'Cook' }]
})
});
// function onFilterComboSelect({ source: combo }) {
function onRoleComboChange({ source: roleCombo }) {
const filterRole = roleCombo.record;
personStore.filter(person => person.personId == filterRole.personId);
}
Is it possible to clear a column dropdown editor from a listener function?
Is it possible to clear a dropdown from in the combo itself like on the cascading combo example?
Can a column dropdown editor be activated without having to double click on the cell?
Thanks
Ben
Re: Cascading combos in row cells
Posted: Mon Oct 07, 2019 12:00 pm
by sergey.maltsev
Hi!
You can update personStore whenever you want and this will update dropdown list when editor is shown.
This code clears personStore and shows empty dropdown.
if (grid.startEditing({
record : grid.store.first,
field : 'person' })) {
personStore.clear();
grid.features.cellEdit.editorContext.editor.inputField.showPicker();
}
Re: Cascading combos in row cells
Posted: Tue Oct 08, 2019 4:12 am
by bensullivan
Is it possible to configure a grid such that the editing of a cell is initiated by a single click instead of a double click?
I'm guessing this might interfere with the fact that a row in a grid is selected by a single click?
Thanks
Ben
Re: Cascading combos in row cells
Posted: Tue Oct 08, 2019 5:25 am
by sergey.maltsev
Hi!
Please next time create new post for each separate question.