function getData() {
return [
{ value: 14, type: 'age', vehicle: 'model' },
{ value: 'Female', type: 'gender', model: 'model' },
{ value: 'Happy', type: 'mood', vehicle: 'model' },
{ value: 21, type: 'age', vehicle: 'model' },
{ value: 'Male', type: 'gender', vehicle: 'model' },
{ value: 'Sad', type: 'mood', vehicle: 'model' },
{ value: 'Honda', type: 'model', vehicle: 'Manufacturer' },
];
}
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-alpine.css';
import 'ag-grid-enterprise';
import { AgGridVue } from 'ag-grid-vue3';
import { createApp } from 'vue';
import MoodEditor from './moodEditorVue.js';
import NumericCellEditor from './numericCellEditorVue.js';
const VueExample = {
template: `
<div style="height: 100%">
<div>TEST</div>
<ag-grid-vue
style="width: 100%; height: 100%;"
class="ag-theme-alpine"
id="myGrid"
:columnDefs="columnDefs"
@grid-ready="onGridReady"
:defaultColDef="defaultColDef"
:rowData="rowData"
:icons="icons"
:suppressMenuHide="true"
:statusBar="statusBar"
@row-editing-started="onRowEditingStarted"
@row-editing-stopped="onRowEditingStopped"
@cell-editing-started="onCellEditingStarted"
@cell-editing-stopped="onCellEditingStopped"></ag-grid-vue>
</div>
`,
components: {
'ag-grid-vue': AgGridVue,
MoodEditor,
NumericCellEditor,
},
data: function () {
return {
columnDefs: [
{
field: 'type',
sortable: true,
unSortIcon: true,
cellStyle: {color: '#319FBE'}
},
{
field: 'value',
filter: 'agSetColumnFilter',
suppressMenu: false,
sortable: true,
unSortIcon: true,
editable: true,
cellRenderer: function (params) {
return (
'<span>' +
params.value +
'<i class="ag-icon ag-icon-small-down"></i></span>'
);
},
cellEditorSelector: (params) => {
if (params.data.type === 'age') {
return {
component: 'NumericCellEditor',
};
}
if (params.data.type === 'gender') {
return {
component: 'agSelectCellEditor',
params: {
values: ['Male', 'Female'],
},
popup: true,
};
}
if (params.data.type === 'mood') {
return {
component: 'MoodEditor',
popup: true,
popupPosition: 'under',
};
}
return undefined;
},
},
{
field: 'vehicle',
filter: 'agSetColumnFilter',
editable: true,
sortable: true,
unSortIcon: true,
cellEditorSelector: (params) => {
if (params.data.type === 'model') {
return {
component: 'agSelectCellEditor',
params: {
values: ['Honda', 'Toyota', 'Nissan'],
},
popup: true,
};
}
return undefined;
},
},
],
gridApi: null,
columnApi: null,
defaultColDef: {
flex: 1,
floatingFilter: true,
},
rowData: null,
};
},
created() {
this.rowData = getData();
this.statusBar = {
statusPanels: [
{ statusPanel: 'agTotalAndFilteredRowCountComponent', align: 'left' },
{ statusPanel: 'agTotalRowCountComponent', align: 'center' },
{ statusPanel: 'agAggregationComponent' },
],
};
},
methods: {
onRowEditingStarted(event) {
console.log('never called - not doing row editing');
},
onRowEditingStopped(event) {
console.log('never called - not doing row editing');
},
onCellEditingStarted(event) {
console.log('cellEditingStarted');
},
onCellEditingStopped(event) {
console.log('cellEditingStopped');
},
onGridReady(params) {
this.gridApi = params.api;
this.gridColumnApi = params.columnApi;
},
},
};
createApp(VueExample).mount('#app');
import { nextTick } from 'vue';
export default {
template: `
<div :ref="'container'" class="mood" tabindex="0" @keydown="onKeyDown">
<img src="https://www.ag-grid.com/example-assets/smileys/happy.png" @click="onClick(true)" :class="{ selected: happy, default: !happy }">
<img src="https://www.ag-grid.com/example-assets/smileys/sad.png" @click="onClick(false)" :class="{ selected: !happy, default: happy }">
</div>
`,
data() {
return {
happy: false,
imgForMood: null,
};
},
methods: {
getValue() {
return this.happy ? 'Happy' : 'Sad';
},
setHappy(happy) {
this.happy = happy;
},
toggleMood() {
this.setHappy(!this.happy);
},
onClick(happy) {
this.setHappy(happy);
this.params.stopEditing();
},
onKeyDown(event) {
let key = event.key;
if (
key === 'ArrowLeft' || // left
key == 'ArrowRight'
) {
// right
this.toggleMood();
event.stopPropagation();
}
},
},
created() {
this.setHappy(this.params.value === 'Happy');
},
mounted() {
nextTick(() => {
this.$refs.container.focus();
});
},
};
import { nextTick } from 'vue';
// backspace starts the editor on Windows
const KEY_BACKSPACE = 'Backspace';
const KEY_ENTER = 'Enter';
const KEY_TAB = 'Tab';
export default {
template: `<input :ref="'input'" class="simple-input-editor" @keydown="onKeyDown($event)" v-model="value"/>`,
data() {
return {
value: '',
cancelBeforeStart: true,
};
},
methods: {
getValue() {
return this.value;
},
isCancelBeforeStart() {
return this.cancelBeforeStart;
},
setInitialState(params) {
let startValue;
if (params.eventKey === KEY_BACKSPACE) {
// if backspace or delete pressed, we clear the cell
startValue = '';
} else if (params.charPress) {
// if a letter was pressed, we start with the letter
startValue = params.charPress;
} else {
// otherwise we start with the current value
startValue = params.value;
}
this.value = startValue;
},
// will reject the number if it greater than 1,000,000
// not very practical, but demonstrates the method.
isCancelAfterEnd() {
return this.value > 1000000;
},
onKeyDown(event) {
if (event.key === 'Escape') {
return;
}
if (this.isLeftOrRight(event) || this.isBackspace(event)) {
event.stopPropagation();
return;
}
if (
!this.finishedEditingPressed(event) &&
!this.isKeyPressedNumeric(event)
) {
if (event.preventDefault) event.preventDefault();
}
},
isCharNumeric(charStr) {
return /\d/.test(charStr);
},
isKeyPressedNumeric(event) {
const charStr = event.key;
return this.isCharNumeric(charStr);
},
finishedEditingPressed(event) {
const key = event.key;
return key === KEY_ENTER || key === KEY_TAB;
},
isBackspace(event) {
return event.key === KEY_BACKSPACE;
},
isLeftOrRight(event) {
return ['ArrowLeft', 'ArrowRight'].indexOf(event.key) > -1;
},
},
created() {
this.setInitialState(this.params);
// only start edit if key pressed is a number, not a letter
this.cancelBeforeStart =
this.params.charPress && '1234567890'.indexOf(this.params.charPress) < 0;
},
mounted() {
nextTick(() => {
// need to check if the input reference is still valid - if the edit was cancelled before it started there
// wont be an editor component anymore
if (this.$refs.input) {
this.$refs.input.focus();
}
});
},
};
span{
color: #585858;
}
.mood {
border-radius: 15px;
border: 1px solid #EDF1F5;
background: #e6e6e6;
padding: 15px;
text-align: center;
display: inline-block;
outline: none;
}
.default {
border: 1px solid transparent !important;
padding: 4px;
}
.selected {
border: 1px solid lightgreen !important;
padding: 4px;
}
.simple-input-editor {
width: 100%;
height: 100%;
}
/* Custom */
.ag-header-row, .ag-header-row-column{
background-color: #F5F7FF;
}
.ag-rich-select-list {
width: 100%;
min-width: 200px;
/*height: calc(var(--ag-row-height) * 1.5) !important;*/
height: auto !important;
}
.ag-select .ag-picker-field-wrapper {
min-height: 42px !important;
width: calc()
}
.ag-theme-alpine {
/* bright green, 10% opacity */
--ag-selected-row-background-color: rgb(0, 255, 0, 0.1);
--ag-odd-row-background-color: #f3f3f3;
}
.ag-root-wrapper.ag-layout-normal{
border-radius: 10px;
}
.ag-icon.ag-icon-small-down{
float: right;
vertical-align: middle;
padding-top: 4%;
}
(function (global) {
// simplified version of Object.assign for es3
function assign() {
var result = {};
for (var i = 0, len = arguments.length; i < len; i++) {
var arg = arguments[i];
for (var prop in arg) {
result[prop] = arg[prop];
}
}
return result;
}
System.config({
transpiler: 'plugin-babel',
defaultExtension: 'js',
paths:
assign(
{
// paths serve as alias
"npm:": "https://cdn.jsdelivr.net/npm/",
}, systemJsPaths),
map: assign(
{
// babel transpiler
'plugin-babel': 'npm:systemjs-plugin-babel@0.0.25/plugin-babel.js',
'systemjs-babel-build': 'npm:systemjs-plugin-babel@0.0.25/systemjs-babel-browser.js',
// css plugin
css: boilerplatePath + "css.js",
// css: 'npm:systemjs-plugin-css@0.1.37/css.js',
// vuejs
'vue': 'npm:vue@3.2.29/dist/vue.esm-browser.js',
'@vue/reactivity': 'npm:@vue/reactivity@3.0.0/dist/reactivity.esm-browser.prod.js',
// vue class component
'vue-class-component': 'npm:vue-class-component@^8.0.0-beta.3/dist/vue-class-component.cjs.js',
app: appLocation + 'app'
},
systemJsMap
), // systemJsMap comes from index.html
packages: {
'vue': {
defaultExtension: 'js'
},
'vue-class-component': {
defaultExtension: 'js'
},
'vue-property-decorator': {
defaultExtension: 'js'
},
app: {
defaultExtension: 'js'
},
'ag-grid-vue3': {
main: './lib/AgGridVue.js',
defaultExtension: 'js'
},
'ag-grid-community': {
main: './dist/ag-grid-community.cjs.min.js',
defaultExtension: 'js'
},
'ag-grid-enterprise': {
main: './dist/ag-grid-enterprise.cjs.min.js',
defaultExtension: 'js'
},
'@ag-grid-community/vue3': {
main: './lib/AgGridVue.js',
defaultExtension: 'js'
}
},
meta: {
'*.js': {
babelOptions: {
stage1: true,
stage2: true,
es2015: true
}
},
'*.css': { loader: 'css' }
}
});
})(this);
if (typeof window !== 'undefined') {
var waitSeconds = 100;
var head = document.getElementsByTagName('head')[0];
var isWebkit = !!window.navigator.userAgent.match(/AppleWebKit\/([^ ;]*)/);
var webkitLoadCheck = function(link, callback) {
setTimeout(function() {
for (var i = 0; i < document.styleSheets.length; i++) {
var sheet = document.styleSheets[i];
if (sheet.href == link.href)
return callback();
}
webkitLoadCheck(link, callback);
}, 10);
};
var cssIsReloadable = function cssIsReloadable(links) {
// Css loaded on the page initially should be skipped by the first
// systemjs load, and marked for reload
var reloadable = true;
forEach(links, function(link) {
if(!link.hasAttribute('data-systemjs-css')) {
reloadable = false;
link.setAttribute('data-systemjs-css', '');
}
});
return reloadable;
}
var findExistingCSS = function findExistingCSS(url){
// Search for existing link to reload
var links = head.getElementsByTagName('link')
return filter(links, function(link){ return link.href === url; });
}
var noop = function() {};
var loadCSS = function(url, existingLinks) {
const stylesUrl = url.includes("styles.css") || url.includes("style.css");
return new Promise((outerResolve, outerReject) => {
setTimeout(() => {
new Promise(function(resolve, reject) {
var timeout = setTimeout(function() {
reject('Unable to load CSS');
}, waitSeconds * 1000);
var _callback = function(error) {
clearTimeout(timeout);
link.onload = link.onerror = noop;
setTimeout(function() {
if (error) {
reject(error);
outerReject(error)
} else {
resolve('');
outerResolve('');
}
}, 7);
};
var link = document.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
link.href = url;
link.setAttribute('data-systemjs-css', '');
if (!isWebkit) {
link.onload = function() {
_callback();
}
} else {
webkitLoadCheck(link, _callback);
}
link.onerror = function(event) {
_callback(event.error || new Error('Error loading CSS file.'));
};
if (existingLinks.length)
head.insertBefore(link, existingLinks[0]);
else
head.appendChild(link);
})
// Remove the old link regardless of loading outcome
.then(function(result){
forEach(existingLinks, function(link){link.parentElement.removeChild(link);})
return result;
}, function(err){
forEach(existingLinks, function(link){link.parentElement.removeChild(link);})
throw err;
})
}, stylesUrl ? 5 : 0)
})
};
exports.fetch = function(load) {
// dont reload styles loaded in the head
var links = findExistingCSS(load.address);
if(!cssIsReloadable(links))
return '';
return loadCSS(load.address, links);
};
}
else {
var builderPromise;
function getBuilder(loader) {
if (builderPromise)
return builderPromise;
return builderPromise = System['import']('./css-plugin-base.js', module.id)
.then(function(CSSPluginBase) {
return new CSSPluginBase(function compile(source, address) {
return {
css: source,
map: null,
moduleSource: null,
moduleFormat: null
};
});
});
}
exports.cssPlugin = true;
exports.fetch = function(load, fetch) {
if (!this.builder)
return '';
return fetch(load);
};
exports.translate = function(load, opts) {
if (!this.builder)
return '';
var loader = this;
return getBuilder(loader).then(function(builder) {
return builder.translate.call(loader, load, opts);
});
};
exports.instantiate = function(load, opts) {
if (!this.builder)
return;
var loader = this;
return getBuilder(loader).then(function(builder) {
return builder.instantiate.call(loader, load, opts);
});
};
exports.bundle = function(loads, compileOpts, outputOpts) {
var loader = this;
return getBuilder(loader).then(function(builder) {
return builder.bundle.call(loader, loads, compileOpts, outputOpts);
});
};
exports.listAssets = function(loads, opts) {
var loader = this;
return getBuilder(loader).then(function(builder) {
return builder.listAssets.call(loader, loads, opts);
});
};
}
// Because IE8?
function filter(arrayLike, func) {
var arr = []
forEach(arrayLike, function(item){
if(func(item))
arr.push(item);
});
return arr;
}
// Because IE8?
function forEach(arrayLike, func){
for (var i = 0; i < arrayLike.length; i++) {
func(arrayLike[i])
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Vue 3 example</title>
<meta charSet="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<style media="only screen">
html, body{
background-color: #F3F5F8
}
html, body, #app {
height: 100%;
width: 100%;
margin: 0;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
}
html {
position: absolute;
top: 0;
left: 0;
padding: 0;
overflow: auto;
}
body {
padding: 1rem;
overflow: auto;
}
</style>
<link rel="stylesheet" href="styles.css"/>
</head>
<body>
<div id="app">
<my-component>Loading Vue 3 example…</my-component>
</div>
<script src="data.js">
</script>
<script>
var appLocation = './';
var boilerplatePath = '';
var systemJsMap = {
"@ag-grid-community/styles": "https://cdn.jsdelivr.net/npm/@ag-grid-community/styles@29.1.0",
"@ag-grid-community/vue3": "https://cdn.jsdelivr.net/npm/@ag-grid-community/vue3@29.1.0/",
"ag-grid-community": "https://cdn.jsdelivr.net/npm/ag-grid-community@29.1.0",
"ag-grid-enterprise": "https://cdn.jsdelivr.net/npm/ag-grid-enterprise@29.1.0/",
"ag-grid-vue3": "https://cdn.jsdelivr.net/npm/ag-grid-vue3@29.1.0/"
};
var systemJsPaths = {
"@ag-grid-community/client-side-row-model": "https://cdn.jsdelivr.net/npm/@ag-grid-community/client-side-row-model@29.1.0/dist/client-side-row-model.cjs.min.js",
"@ag-grid-community/core": "https://cdn.jsdelivr.net/npm/@ag-grid-community/core@29.1.0/dist/core.cjs.min.js",
"@ag-grid-community/csv-export": "https://cdn.jsdelivr.net/npm/@ag-grid-community/csv-export@29.1.0/dist/csv-export.cjs.min.js",
"@ag-grid-community/infinite-row-model": "https://cdn.jsdelivr.net/npm/@ag-grid-community/infinite-row-model@29.1.0/dist/infinite-row-model.cjs.min.js",
"@ag-grid-enterprise/charts": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/charts@29.1.0/dist/charts.cjs.min.js",
"@ag-grid-enterprise/clipboard": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/clipboard@29.1.0/dist/clipboard.cjs.min.js",
"@ag-grid-enterprise/column-tool-panel": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/column-tool-panel@29.1.0/dist/column-tool-panel.cjs.min.js",
"@ag-grid-enterprise/core": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/core@29.1.0/dist/core.cjs.min.js",
"@ag-grid-enterprise/excel-export": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/excel-export@29.1.0/dist/excel-export.cjs.min.js",
"@ag-grid-enterprise/filter-tool-panel": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/filter-tool-panel@29.1.0/dist/filter-tool-panel.cjs.min.js",
"@ag-grid-enterprise/master-detail": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/master-detail@29.1.0/dist/master-detail.cjs.min.js",
"@ag-grid-enterprise/menu": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/menu@29.1.0/dist/menu.cjs.min.js",
"@ag-grid-enterprise/multi-filter": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/multi-filter@29.1.0/dist/multi-filter.cjs.min.js",
"@ag-grid-enterprise/range-selection": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/range-selection@29.1.0/dist/range-selection.cjs.min.js",
"@ag-grid-enterprise/rich-select": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/rich-select@29.1.0/dist/rich-select.cjs.min.js",
"@ag-grid-enterprise/row-grouping": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/row-grouping@29.1.0/dist/row-grouping.cjs.min.js",
"@ag-grid-enterprise/server-side-row-model": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/server-side-row-model@29.1.0/dist/server-side-row-model.cjs.min.js",
"@ag-grid-enterprise/set-filter": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/set-filter@29.1.0/dist/set-filter.cjs.min.js",
"@ag-grid-enterprise/side-bar": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/side-bar@29.1.0/dist/side-bar.cjs.min.js",
"@ag-grid-enterprise/sparklines": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/sparklines@29.1.0/dist/sparklines.cjs.min.js",
"@ag-grid-enterprise/status-bar": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/status-bar@29.1.0/dist/status-bar.cjs.min.js",
"@ag-grid-enterprise/viewport-row-model": "https://cdn.jsdelivr.net/npm/@ag-grid-enterprise/viewport-row-model@29.1.0/dist/viewport-row-model.cjs.min.js"
};
</script>
<script src="https://cdn.jsdelivr.net/npm/systemjs@0.19.47/dist/system.js">
</script>
<script src="systemjs.config.js">
</script>
<script>System.import('./main.js').catch(function(err) { console.error(err); });</script>
</body>
</html>