demo D218
The form, four ways
The same row form as a drawer, a dialog, an inline region and a curated set
rowForm: { mode: 'drawer' · 'dialog', container }
Loading a live grid…
The configuration
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.28.0/lattice-grid.min.css">
<style>
#buttons { display: flex; gap: 8px; margin-bottom: 12px; }
#panes { display: flex; gap: 14px; }
#grid { flex: 1; }
#grid > div { height: 520px; }
#inline-form { width: 320px; }
</style>
<div id="app"></div>
<script type="module">
import * as Vue from 'https://esm.sh/vue@3';
import { createGrid } from 'https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.28.0/lattice-grid.esm.min.js';
import createLatticeGrid from 'https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.28.0/modules/vue.esm.min.js';
const LatticeGrid = createLatticeGrid({ vue: Vue, createGrid });
Vue.createApp({
components: { LatticeGrid },
data() {
const fields = [
{ field: 'service', label: 'Service' },
{ field: 'team', label: 'Team' },
{ field: 'region', label: 'Region' },
{ field: 'tier', label: 'Tier' },
{ field: 'instances', label: 'Instances' },
{ field: 'monthlyCost', label: 'Monthly cost' },
{ field: 'notes', label: 'Notes', editor: 'textarea' },
];
return {
mode: 'drawer',
// The same form, placed four ways. Only the rowForm option differs:
// drawer - a right-hand panel (the default)
// dialog - a centred modal
// inline - built into an element of your own; a region, not a modal
// curated - the drawer with a chosen few fields
modes: {
drawer: { mode: 'drawer', title: 'Edit service', fields },
dialog: { mode: 'dialog', title: 'Edit service', fields },
inline: { fields, container: '#inline-form' },
curated: { mode: 'drawer', title: 'Quick edit',
fields: [{ field: 'tier', label: 'Tier' }, { field: 'instances', label: 'Instances' },
{ field: 'notes', label: 'Notes', editor: 'textarea' }] },
},
columns: [
{ field: 'service', title: 'Service', layout: { pin: 'start', width: 150 } },
{ field: 'team', title: 'Team', filter: { type: 'set' } },
{ field: 'region', title: 'Region', filter: { type: 'set' } },
{ field: 'tier', title: 'Tier' },
{ field: 'instances', title: 'Instances', type: 'number' },
{ field: 'monthlyCost', title: 'Monthly cost', type: 'number', format: { style: 'currency', currency: 'USD' } },
],
};
},
computed: {
// rowForm is read when the grid is built, so keying the component on the mode
// rebuilds it whenever the placement changes.
config() {
return { rowKey: 'id', editable: true, rowForm: this.modes[this.mode], columns: this.columns, rows };
},
},
watch: {
mode() {
// Open it on the rebuilt grid so the placement shows.
this.$nextTick(() => this.$refs.grid.grid().form.open(String(rows[0].id)));
},
},
mounted() {
this.$refs.grid.grid().form.open(String(rows[0].id));
},
template: `
<div>
<div id="buttons">
<button v-for="name in Object.keys(modes)" :key="name" @click="mode = name">{{ name }}</button>
</div>
<div id="panes">
<div id="grid"><lattice-grid :key="mode" ref="grid" v-bind="config" /></div>
<div id="inline-form"></div>
</div>
</div>
`,
}).mount('#app');
</script>