Custom Inline Editor

This example shows how you can implement custom editors in a data view.

This example shows how you can implement custom editors in a data view. The built-in editors you see in the previous example only appear for basic data types. Sometimes you may need to handle complex data types or edit the logic. In this example, three editor types are created in the source code: NameEditor: Presents fields for first, middle, and last name and then saves them to a single name field. RadioButtonEditor: Presents a radio button control that gives the users two choices, Male or Female for the Gender field. TextAreaEditor: Presents a large text area with Save and Cancel buttons so users can enter long text strings. Try double-clicking on the different columns to see the different types of editor types that were created for this example.
<!DOCTYPE html> <html lang="en"> <head> <base href="/dataviewsjs/demos/en/sample/Features/Editing/CustomInlineEditor/purejs/" /> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="keywords" content="editing, editor, data editor, data editing" /> <meta name="description" content="This example shows how you can implement custom editors in a data view." /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Custom Inline Editor | Features | MESCIUS DataViewsJS JavaScript Demos</title> <link href="/dataviewsjs/demos/node_modules/normalize.css/normalize.css" rel="stylesheet" type="text/css" /> <link href="/dataviewsjs/demos/static/css/base.css" rel="stylesheet" type="text/css" /> <link href="/dataviewsjs/demos/static/dataviews/gc.dataviews.core.min.css" rel="stylesheet" type="text/css" /> <link href="/dataviewsjs/demos/static/dataviews/gc.dataviews.grid.min.css" rel="stylesheet" type="text/css" /> <link href="styles.css" rel="stylesheet" type="text/css" /> <script src="/dataviewsjs/demos/static/js/app-polyfills.min.js" type="text/javascript"></script> <script type="text/javascript"> window.process = { env: { NODE_ENV: 'production', USE_NPM: false, USE_CDN: false, SITE_ROOT: '/dataviewsjs/demos', FRAMEWORK: 'purejs', DVJS_LICENSE_KEY: 'E348418822993781#B0EWvwY4dNNVQqJHUDpFROVWe5ZWNYFlVQFmRsJWRht4Z6lDO4Vla7YUaXhEWxd7Z5YXMuRnY7tWTQRHSlVnaYlXNhlEOpdkZ0FHWYJ5QKd6VXN5aR3ieGhUav9kZTBXWahkYBhEVutmZ72CbjdlZvV5TVdGdiplQsZXe95kUmNmZVF5cJ3mcypWNyx4UydESE3UblxGZyE7KQ94R4BjbUxUewsiaoREMxRDNllWREV6Voh4Q4dDZPRjWrIzUJl4TERXcQZWMHp4Sp9WaMZzN5o6StJmVDJXcwIVVmR6UMVGOlxUW8RmTxZDZTJWVN5GZqJHZuVDMkVGSW3WdxNzKCdDdSB7TzY7cqlnMU5GVyNzNP9WMyhDRvEEOFdkQORDM4dFVlFFWqFWSyMjNQJiOiMlIsISQyIkQ9YjQxIiOigkIsUTM7YjNxYTM0IicfJye&amp;Qf35VfikFVVljI0IyQiwiIxYHITp4c7VWaWFGdhRkI0IiTis7W0ICZyBlIsIiNxUTN6ADI8EDMxMjMwIjI0ICdyNkIsIyc59yc5l6YzVWbuoCLwpmLzVXajNXZt9iKs2WauMXdpN6cl5mLqwSbvNmLzVXajNXZt9iKsAnau26YuMXdpN6cl5mLqwSbvNmL6VGZ9RXajVGchJ7ZuoCLuNmLt36YukHdpNWZwFmcn9iKs46bj9Se4l6YlBXYydmLqwicr9ybj9Se4l6YlBXYydmLqwCcq9ybj9Se4l6YlBXYydmLqIiOiMXbEJCLiMVVJN4UF5kI0ISYONkIsUWdyRnOiwmdFJCLiEDO7MTO9IjM8gTM4gDNzIiOiQWSisnOiQkIsISP3EkVxBVUHFDMplzLlVUdGd7cI9UeIt4SshESzV7NvY7ZxlDOuNTb5tzLr', SJS_LICENSE_KEY: 'E518585142165236#B0wm4nx4QzdlTHRTSOFzcvVnaJdjSnNEeXdTMUtSUzk6bU94QuVXNwZVZjd4SzYjcadXRIVEMzEXTThkVyR7R85UayoHZZBTYQ5mZyh4Shd6VxFXazF4cBNGRG5WTvUGTsV4T6knQYRzKxxUdk9EarplU7d6VLF6KIR7bPJ5N6ZUMWZWaURGRKRDbLJDN5YjSN5mUoxmaxonSD56LEh7Y7RXenpmTvomevZlV9dkaysCO7hTRQFHcGRWQyc5LI9kQmB7QwR4Z7ZHOR3CSXp6SiFWYzFXeXZUSp94K8VDTkFjdwl4KptSYlRWcDxmNE5kS6kzdrkVcNJXROVGbLJkcTNGRzIER8tmd4YGNhh7dxAnMvIHRv46VtBXS4U5KvJ6dZJ6M5p4TxIjd9I5QSpXTTV6SDZXb7lzaL56ZiojITJCLikTQxUTQFV4NiojIIJCLyETO7UzM7kTO0IicfJye&amp;Qf35VfikkR9IkI0IyQiwiIyEjL6ByUKBCZhVmcwNlI0IiTis7W0ICZyBlIsISNwkTN6ADI8EDMxMjMwIjI0ICdyNkIsIyc59yc5l6YzVWbuoCLwpmLzVXajNXZt9iKs2WauMXdpN6cl5mLqwSbvNmLzVXajNXZt9iKsAnau26YuMXdpN6cl5mLqwSbvNmL6VGZ9RXajVGchJ7ZuoCLuNmLt36YukHdpNWZwFmcn9iKs46bj9Se4l6YlBXYydmLqwicr9ybj9Se4l6YlBXYydmLqwCcq9ybj9Se4l6YlBXYydmLqIiOiMXbEJCLiMVVJN4UF5kI0ISYONkIsUWdyRnOiwmdFJCLiYzMyUjNxIDNxUDO5gTM5IiOiQWSiwSfdtlOicGbmJCLlNHbhZmOiI7ckJye0ICbuFkI1pjIEJCLi4TPRtGOhtWWEFWd4IDOLRVRvx4SyMGcDhTW6n4ep', }, }; </script> <script src="/dataviewsjs/demos/node_modules/imask/dist/imask.min.js" type="text/javascript"></script> <script src="/dataviewsjs/demos/static/dataviews/gc.dataviews.common.min.js" type="text/javascript"></script> <script src="/dataviewsjs/demos/static/dataviews/gc.dataviews.core.min.js" type="text/javascript"></script> <script src="/dataviewsjs/demos/static/dataviews/gc.dataviews.grid.min.js" type="text/javascript"></script> <script src="/dataviewsjs/demos/static/js/license.js" type="text/javascript"></script> <script src="/dataviewsjs/demos/node_modules/systemjs/dist/system.js" type="text/javascript"></script> <script src="systemjs.config.js" type="text/javascript"></script> </head> <body class="theme-default"> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="grid" class="grid"></div> <script type="text/javascript"> System.import('./app.js'); </script> </body> </html>
import { data } from './data'; import { NameEditor, RadioButtonEditor, TextAreaEditor } from './editor'; export const cols = [ { id: 'id', caption: 'Id', dataField: 'id', width: 80, allowEditing: false, }, { id: 'name', caption: 'Name', dataField: 'name', width: 128, editor: NameEditor, }, { id: 'gender', caption: 'Gender', dataField: 'gender', width: 90, editor: RadioButtonEditor, }, { id: 'phone', caption: 'Phone', dataField: 'phone', width: 140, format: ({ value }) => { let i = 0; return '+#(###)###-##-##'.replace(/#/g, () => value.charAt(i++)); }, // sample of masked input editor: { type: 'text', create(input) { const mask = IMask(input, { mask: '+{7}(000)000-00-00', }); return { destroy() { mask.destroy(); }, serialize(value) { return value.replace(/[+\-()]/g, ''); }, }; }, }, }, { id: 'remark', caption: 'Remark', dataField: 'remark', width: '*', editor: TextAreaEditor, }, ]; const layout = new GC.DataViews.GridLayout({ allowEditing: true }); new GC.DataViews.DataView(document.getElementById('grid'), data, cols, layout);
const names = ['Alice Wang', 'Michael Zhang', 'Andrew Li', 'Tyler W. Stone', 'Daniel Qian', 'William B. Hans']; const remarks = 'This text area is used to write the evaluation for the student, about the learning achievement, general performance, and effort.'; const genders = ['male', 'female']; const phones = ['79031231200', '79137894512', '79033214599', '79039991122', '79037775500', '79033332222']; export const data = []; for (let i = 0; i < 100; i++) { data.push({ id: i, name: names[i % names.length], gender: genders[i % genders.length], phone: phones[i % phones.length], remark: remarks, }); }
export class NameEditor { constructor(options) { this.options = options; } init() { const options = this.options; const container = options.container; const rawValue = options.value; const rawNames = rawValue.split(' '); let firstName = ''; let lastName = ''; let middleName = ''; let hasMiddleName = false; switch (rawNames.length) { case 0: firstName = ''; lastName = ''; break; case 1: firstName = rawNames[0]; lastName = ''; break; case 2: firstName = rawNames[0]; lastName = rawNames[1]; break; default: firstName = rawNames[0]; lastName = rawNames[rawNames.length - 1]; middleName = rawNames.slice(1, rawNames.length - 1).join(' '); hasMiddleName = true; } this.defaultValue = rawValue; const input = ({ label, className, value }) => ` <div style="margin-bottom:6px"> <div><i>${label}:</i></div> <input type="text" class="${className}" style="width:120px" value="${value}"> </div>`; container.innerHTML = [ input({ label: 'First Name', className: 'firstname', value: firstName }), hasMiddleName ? input({ label: 'Middle Name', className: 'middlename', value: middleName }) : '', input({ label: 'Last Name', className: 'lastname', value: lastName }), ].join(''); this.firstNameInput = container.querySelector('input.firstname'); this.middleNameInput = container.querySelector('input.middlename'); this.lastNameInput = container.querySelector('input.lastname'); this.focus(); } focus() { this.firstNameInput.focus(); } serialize() { return this.middleNameInput ? `${this.firstNameInput.value} ${this.middleNameInput.value} ${this.lastNameInput.value}` : `${this.firstNameInput.value} ${this.lastNameInput.value}`; } } export class RadioButtonEditor { constructor(options) { this.options = options; } init() { const options = this.options; const value = options.value; const container = options.container; const list = ['male', 'female']; const html = list .map((val) => { const checked = val === value ? 'checked' : ''; return `<div class="flex"> <input type="radio" name="radioeditor" id="${val}" value="${val}"${checked}> <label style="font-weight:normal;padding: 4px;" for="${val}">${val}</label> </div>`; }) .join(''); container.innerHTML = html; } focus() { this.options.container.querySelector('input:checked').focus(); } serialize() { return this.options.container.querySelector('input:checked').value; } } export class TextAreaEditor { constructor(options) { this.options = options; } init() { const options = this.options; const container = options.container; container.innerHTML = `<textarea style="outline:0;width:100%;height:100%;border:0px;"></textarea> <div style="width:100%"> <button class="cancel">Cancel</button> <button class="save">Save</button> </div>`; this.textArea = container.children[0]; this.textArea.value = options.value; this.textArea.focus(); this.handleClick = this.handleClick.bind(this); this.handleKeyDown = this.handleKeyDown.bind(this); container.addEventListener('click', this.handleClick); container.addEventListener('keydown', this.handleKeyDown); } destroy() { const container = this.options.container; container.removeEventListener('click', this.handleClick); container.removeEventListener('keydown', this.handleKeyDown); } focus() { this.textArea.focus(); } serialize() { return this.textArea.value; } handleClick(event) { event.stopPropagation(); if (event.target && event.target.tagName.toLowerCase() === 'button') { if (event.target.className === 'save') { this.options.dataview.stopEditing(); } else if (event.target.className === 'cancel') { this.options.dataview.cancelEditing(); } } } handleKeyDown(event) { if (event.defaultPrevented || !document.activeElement) { return; } const key = event.key || event.keyCode; if (key === 'Enter' || key === 13) { if (document.activeElement.className === 'save') { event.stopPropagation(); this.options.dataview.stopEditing(); } else if (document.activeElement.className === 'cancel') { event.stopPropagation(); this.options.dataview.cancelEditing(); } } } }
.flex { display: flex; align-items: center; } .gc-grid .gc-inline-editing-area .gc-inline-editor-container[data-column=name] { padding: 3px; border-radius: 2px; border: 1px solid #0066ff; background-color: white; } .gc-grid .gc-inline-editing-area .gc-inline-editor-container[data-column=gender] { min-width: 90px; padding: 6px; border-radius: 2px; border: 1px solid #0066ff; } .gc-grid .gc-inline-editing-area .gc-inline-editor-container[data-column=phone] input { border-radius: 2px; border: 1px solid #0066ff; transition: none; } .gc-grid .gc-inline-editing-area .gc-inline-editor-container[data-column=phone] input:focus { border-color: #3385ff; border-width: 1px; box-shadow: none; } .gc-grid .gc-inline-editing-area .gc-inline-editor-container[data-column=remark] { padding: 3px; border-radius: 2px; border: 1px solid #0066ff; } .gc-grid .gc-inline-editing-area .gc-inline-editor-container[data-column=remark] button { float: right; width: 60px; margin-right: 0.4em; background: #f1f1f1; border: solid 1px #e0e0e0; } /*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkZlYXR1cmVzL0VkaXRpbmcvQ3VzdG9tSW5saW5lRWRpdG9yL3B1cmVqcy9zdHlsZXMuc2NzcyIsIkZlYXR1cmVzL0VkaXRpbmcvQ3VzdG9tSW5saW5lRWRpdG9yL3B1cmVqcy9zdHlsZXMuY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBO0VBQ0UsYUFBQTtFQUNBLG1CQUFBO0FDREY7O0FET007RUFDRSxZQUFBO0VBQ0Esa0JBQUE7RUFDQSx5QkFBQTtFQUNBLHVCQUFBO0FDSlI7QURPTTtFQUNFLGVBQUE7RUFDQSxZQUFBO0VBQ0Esa0JBQUE7RUFDQSx5QkFBQTtBQ0xSO0FEU1E7RUFDRSxrQkFBQTtFQUNBLHlCQUFBO0VBQ0EsZ0JBQUE7QUNQVjtBRFNVO0VBQ0UscUJBQUE7RUFDQSxpQkFBQTtFQUNBLGdCQUFBO0FDUFo7QURZTTtFQUNFLFlBQUE7RUFDQSxrQkFBQTtFQUNBLHlCQUFBO0FDVlI7QURZUTtFQUNFLFlBQUE7RUFDQSxXQUFBO0VBQ0EsbUJBQUE7RUFDQSxtQkFBQTtFQUNBLHlCQUFBO0FDVlYiLCJmaWxlIjoiRmVhdHVyZXMvRWRpdGluZy9DdXN0b21JbmxpbmVFZGl0b3IvcHVyZWpzL3N0eWxlcy5jc3MiLCJzb3VyY2VzQ29udGVudCI6WyIkYm9yZGVyLWNvbG9yOiAjMDA2NmZmO1xuXG4uZmxleCB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG59XG5cbi5nYy1ncmlkIHtcbiAgLmdjLWlubGluZS1lZGl0aW5nLWFyZWEge1xuICAgIC5nYy1pbmxpbmUtZWRpdG9yLWNvbnRhaW5lciB7XG4gICAgICAmW2RhdGEtY29sdW1uPSduYW1lJ10ge1xuICAgICAgICBwYWRkaW5nOiAzcHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgICAgICAgYm9yZGVyOiAxcHggc29saWQgJGJvcmRlci1jb2xvcjtcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XG4gICAgICB9XG5cbiAgICAgICZbZGF0YS1jb2x1bW49J2dlbmRlciddIHtcbiAgICAgICAgbWluLXdpZHRoOiA5MHB4O1xuICAgICAgICBwYWRkaW5nOiA2cHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgICAgICAgYm9yZGVyOiAxcHggc29saWQgJGJvcmRlci1jb2xvcjtcbiAgICAgIH1cblxuICAgICAgJltkYXRhLWNvbHVtbj0ncGhvbmUnXSB7XG4gICAgICAgIGlucHV0IHtcbiAgICAgICAgICBib3JkZXItcmFkaXVzOiAycHg7XG4gICAgICAgICAgYm9yZGVyOiAxcHggc29saWQgJGJvcmRlci1jb2xvcjtcbiAgICAgICAgICB0cmFuc2l0aW9uOiBub25lO1xuXG4gICAgICAgICAgJjpmb2N1cyB7XG4gICAgICAgICAgICBib3JkZXItY29sb3I6IGxpZ2h0ZW4oJGJvcmRlci1jb2xvciwgMTAlKTtcbiAgICAgICAgICAgIGJvcmRlci13aWR0aDogMXB4O1xuICAgICAgICAgICAgYm94LXNoYWRvdzogbm9uZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgJltkYXRhLWNvbHVtbj0ncmVtYXJrJ10ge1xuICAgICAgICBwYWRkaW5nOiAzcHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgICAgICAgYm9yZGVyOiAxcHggc29saWQgJGJvcmRlci1jb2xvcjtcblxuICAgICAgICBidXR0b24ge1xuICAgICAgICAgIGZsb2F0OiByaWdodDtcbiAgICAgICAgICB3aWR0aDogNjBweDtcbiAgICAgICAgICBtYXJnaW4tcmlnaHQ6IDAuNGVtO1xuICAgICAgICAgIGJhY2tncm91bmQ6ICNmMWYxZjE7XG4gICAgICAgICAgYm9yZGVyOiBzb2xpZCAxcHggI2UwZTBlMDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIiwiLmZsZXgge1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xufVxuXG4uZ2MtZ3JpZCAuZ2MtaW5saW5lLWVkaXRpbmctYXJlYSAuZ2MtaW5saW5lLWVkaXRvci1jb250YWluZXJbZGF0YS1jb2x1bW49bmFtZV0ge1xuICBwYWRkaW5nOiAzcHg7XG4gIGJvcmRlci1yYWRpdXM6IDJweDtcbiAgYm9yZGVyOiAxcHggc29saWQgIzAwNjZmZjtcbiAgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7XG59XG4uZ2MtZ3JpZCAuZ2MtaW5saW5lLWVkaXRpbmctYXJlYSAuZ2MtaW5saW5lLWVkaXRvci1jb250YWluZXJbZGF0YS1jb2x1bW49Z2VuZGVyXSB7XG4gIG1pbi13aWR0aDogOTBweDtcbiAgcGFkZGluZzogNnB4O1xuICBib3JkZXItcmFkaXVzOiAycHg7XG4gIGJvcmRlcjogMXB4IHNvbGlkICMwMDY2ZmY7XG59XG4uZ2MtZ3JpZCAuZ2MtaW5saW5lLWVkaXRpbmctYXJlYSAuZ2MtaW5saW5lLWVkaXRvci1jb250YWluZXJbZGF0YS1jb2x1bW49cGhvbmVdIGlucHV0IHtcbiAgYm9yZGVyLXJhZGl1czogMnB4O1xuICBib3JkZXI6IDFweCBzb2xpZCAjMDA2NmZmO1xuICB0cmFuc2l0aW9uOiBub25lO1xufVxuLmdjLWdyaWQgLmdjLWlubGluZS1lZGl0aW5nLWFyZWEgLmdjLWlubGluZS1lZGl0b3ItY29udGFpbmVyW2RhdGEtY29sdW1uPXBob25lXSBpbnB1dDpmb2N1cyB7XG4gIGJvcmRlci1jb2xvcjogIzMzODVmZjtcbiAgYm9yZGVyLXdpZHRoOiAxcHg7XG4gIGJveC1zaGFkb3c6IG5vbmU7XG59XG4uZ2MtZ3JpZCAuZ2MtaW5saW5lLWVkaXRpbmctYXJlYSAuZ2MtaW5saW5lLWVkaXRvci1jb250YWluZXJbZGF0YS1jb2x1bW49cmVtYXJrXSB7XG4gIHBhZGRpbmc6IDNweDtcbiAgYm9yZGVyLXJhZGl1czogMnB4O1xuICBib3JkZXI6IDFweCBzb2xpZCAjMDA2NmZmO1xufVxuLmdjLWdyaWQgLmdjLWlubGluZS1lZGl0aW5nLWFyZWEgLmdjLWlubGluZS1lZGl0b3ItY29udGFpbmVyW2RhdGEtY29sdW1uPXJlbWFya10gYnV0dG9uIHtcbiAgZmxvYXQ6IHJpZ2h0O1xuICB3aWR0aDogNjBweDtcbiAgbWFyZ2luLXJpZ2h0OiAwLjRlbTtcbiAgYmFja2dyb3VuZDogI2YxZjFmMTtcbiAgYm9yZGVyOiBzb2xpZCAxcHggI2UwZTBlMDtcbn0iXX0= */
(function () { const IS_PROD = window.process.env.NODE_ENV === 'production'; const USE_NPM = window.process.env.USE_NPM; const USE_CDN = window.process.env.USE_CDN; const SITE_ROOT = window.process.env.SITE_ROOT; const FRAMEWORK = window.process.env.FRAMEWORK; const ext = IS_PROD ? '.min.js' : '.js'; function js(name) { return name + ext; } function npm(t) { if (!t.file) { t.file = IS_PROD ? t.prod : t.dev; } const version = USE_CDN && t.version ? '@' + t.version : ''; const path = t.pkg + version + '/' + t.file; if (USE_CDN) { return 'https://unpkg.com/' + path; } return 'npm:' + path; } function dv(t) { if (USE_CDN || USE_NPM) { t.file = 'dist/' + t.file + '.min.js'; return npm(t); } return SITE_ROOT + '/static/dataviews/' + js(t.file); } const isTypeScript = FRAMEWORK === 'angular'; const babelConfig = { es2015: true, react: true, }; const meta = { js: { babelOptions: babelConfig, }, ts: { typescriptOptions: { tsconfig: true }, }, }; const map = { // gc.dataviews packages '@grapecity/dataviews.common': dv({pkg:'@grapecity/dataviews.common',file:'gc.dataviews.common',version:'1.8.17'}), '@grapecity/dataviews.core': dv({pkg:'@grapecity/dataviews.core',file:'gc.dataviews.core',version:'1.8.17'}), '@grapecity/dataviews.grid': dv({pkg:'@grapecity/dataviews.grid',file:'gc.dataviews.grid',version:'1.8.17'}), '@grapecity/dataviews.cardlayout': dv({pkg:'@grapecity/dataviews.cardlayout',file:'gc.dataviews.cardlayout',version:'1.8.17'}), '@grapecity/dataviews.masonry': dv({pkg:'@grapecity/dataviews.masonry',file:'gc.dataviews.masonry',version:'1.8.17'}), '@grapecity/dataviews.calendar': dv({pkg:'@grapecity/dataviews.calendar',file:'gc.dataviews.calendar',version:'1.8.17'}), '@grapecity/dataviews.timeline': dv({pkg:'@grapecity/dataviews.timeline',file:'gc.dataviews.timeline',version:'1.8.17'}), '@grapecity/dataviews.trellis': dv({pkg:'@grapecity/dataviews.trellis',file:'gc.dataviews.trellis',version:'1.8.17'}), '@grapecity/dataviews.gantt': dv({pkg:'@grapecity/dataviews.gantt',file:'gc.dataviews.gantt',version:'1.8.17'}), '@grapecity/dataviews.searchbox': dv({pkg:'@grapecity/dataviews.searchbox',file:'gc.dataviews.searchbox',version:'1.8.17'}), '@grapecity/dataviews.react': dv({pkg:'@grapecity/dataviews.react',file:'gc.dataviews.react',version:'1.8.17'}), '@grapecity/dataviews.vue': dv({pkg:'@grapecity/dataviews.vue',file:'gc.dataviews.vue',version:'1.8.17'}), '@grapecity/dataviews.angular': dv({pkg:'@grapecity/dataviews.angular',file:'gc.dataviews.angular',version:'1.8.17'}), '@grapecity/dataviews.csvexport': dv({pkg:'@grapecity/dataviews.angular',file:'gc.dataviews.csvexport',version:'1.8.17'}), // third-party libs react: npm({pkg:'react',prod:'umd/react.production.min.js',dev:'umd/react.development.js',version:'16.13.1'}), 'react-dom': npm({pkg:'react-dom',prod:'umd/react-dom.production.min.js',dev:'umd/react-dom.development.js',version:'16.13.1'}), 'react-router-dom': npm({pkg:'react-router-dom',prod:'umd/react-router-dom.min.js',dev:'umd/react-router-dom.js',version:'5.2.0'}), 'vue': npm({pkg:'vue',file:'dist/vue.js',version:'2.6.12'}), 'vue-router': npm({pkg:'vue-router',file:'dist/vue-router.js',version:'3.4.3'}), 'lodash': npm({pkg: 'lodash', file: js('lodash')}), 'zone.js': npm({pkg: 'zone.js', file: js('dist/zone')}), 'rxjs': npm({pkg: 'rxjs', file: js('bundles/rxjs.umd')}), 'rxjs/operators': npm({pkg:'rxjs-operators-bundle',prod:'dist/bundle.min.js',dev:'dist/bundle.js',version:'1.0.2'}), '@angular/core': npm({pkg: '@angular/core', file: js('bundles/core.umd')}), '@angular/common': npm({pkg: '@angular/common', file: js('bundles/common.umd')}), '@angular/compiler': npm({pkg: '@angular/compiler', file: js('bundles/compiler.umd')}), '@angular/platform-browser': npm({pkg: '@angular/platform-browser', file: js('bundles/platform-browser.umd')}), '@angular/platform-browser-dynamic': npm({pkg: '@angular/platform-browser-dynamic', file: js('bundles/platform-browser-dynamic.umd')}), '@angular/http': npm({pkg: '@angular/http', file: js('bundles/http.umd')}), '@angular/common/http': npm({pkg: '@angular/common', file: js('bundles/common-http.umd')}), '@angular/router': npm({pkg: '@angular/router', file: js('bundles/router.umd')}), '@angular/forms': npm({pkg: '@angular/forms', file: js('bundles/forms.umd')}), // systemjs plugins 'systemjs-plugin-json': npm({pkg:'systemjs-plugin-json',file:'json.js',version:'0.3.0'}), 'systemjs-plugin-css': npm({pkg:'systemjs-plugin-css',file:'css.js',version:'0.1.37'}), 'systemjs-plugin-babel': npm({pkg:'systemjs-plugin-babel',file:'plugin-babel.js',version:'0.0.25'}), 'systemjs-babel-build': npm({pkg:'systemjs-plugin-babel',file:'systemjs-babel-browser.js',version:'0.0.25'}), 'plugin-typescript': npm({pkg:'plugin-typescript',file:'lib/plugin.js',version:'8.0.0'}), 'typescript': npm({pkg:'typescript',file:'lib/typescript.js',version:'4.0.2'}), 'systemjs-vue-browser': npm({pkg:'systemjs-vue-browser',file:'index.js',version:'1.0.11'}), }; const config = { defaultJSExtensions: true, transpiler: isTypeScript ? 'plugin-typescript' : 'systemjs-plugin-babel', typescriptOptions: { tsconfig: true }, meta: { '*.json': {loader: 'systemjs-plugin-json'}, '*.css': {loader: 'systemjs-plugin-css'}, '*.vue': {loader: 'systemjs-vue-browser'}, '*.js': meta.js, '*.ts': meta.ts, 'app.js': { format: 'esm', babelOptions: babelConfig, }, 'typescript': { exports: 'ts', }, '@grapecity/dataviews.common': { format: 'amd', }, '@grapecity/dataviews.core': { format: 'amd', deps: [ '@grapecity/dataviews.common', ], }, '@grapecity/dataviews.grid': { format: 'amd', deps: [ '@grapecity/dataviews.common', '@grapecity/dataviews.core', ], }, '@grapecity/dataviews.cardlayout': { format: 'amd', deps: [ '@grapecity/dataviews.common', ], }, '@grapecity/dataviews.masonry': { format: 'amd', deps: [ '@grapecity/dataviews.common', ], }, '@grapecity/dataviews.calendar': { format: 'amd', deps: [ '@grapecity/dataviews.common', '@grapecity/dataviews.core', ], }, '@grapecity/dataviews.timeline': { format: 'amd', deps: [ '@grapecity/dataviews.common', ], }, '@grapecity/dataviews.trellis': { format: 'amd', deps: [ '@grapecity/dataviews.common', ], }, '@grapecity/dataviews.gantt': { format: 'amd', deps: [ '@grapecity/dataviews.common', ], }, '@grapecity/dataviews.searchbox': { format: 'amd', deps: [ '@grapecity/dataviews.common', ], }, '@grapecity/dataviews.react': { format: 'amd', deps: [ 'react', '@grapecity/dataviews.common', '@grapecity/dataviews.core' ], }, '@grapecity/dataviews.vue': { format: 'amd', deps: [ 'vue', '@grapecity/dataviews.common', '@grapecity/dataviews.core' ], }, '@grapecity/dataviews.angular': { format: 'amd', deps: [ '@angular/core', '@grapecity/dataviews.common', '@grapecity/dataviews.core' ], }, '@grapecity/dataviews.csvexport': { format: 'amd', deps: [ '@grapecity/dataviews.common' ], }, }, paths: { // paths serve as alias 'npm:': SITE_ROOT + '/node_modules/', }, // map tells the System loader where to look for things map: map, // packages tells the System loader how to load when no filename and/or no extension packages: { '.': { defaultExtension: isTypeScript ? 'ts' : 'js' }, node_modules: { defaultExtension: 'js' }, } }; // fast format detection to avoid detection by source code using regexp Object.keys(map).filter(function (key) { return !config.meta[key]; }).forEach(function (key) { const path = map[key]; if (path.indexOf('/umd') >= 0 || path.indexOf('.umd') >= 0) { config.meta[key] = { format: 'amd' }; } if (path.indexOf('/cjs') >= 0) { config.meta[key] = { format: 'cjs' }; } }); System.config(config); })(this);