├── jQuery ├── .stylelintignore ├── .eslintignore ├── .prettierignore ├── .stylelintrc.json ├── .vscode │ └── settings.json ├── favicon.ico ├── bs-config.json ├── .prettierrc.json ├── src │ ├── index.css │ ├── index.html │ ├── data.js │ └── index.js ├── .eslintrc.js ├── package.json └── README.md ├── Angular ├── src │ ├── assets │ │ └── .gitkeep │ ├── styles.scss │ ├── favicon.ico │ ├── app │ │ ├── app.component.scss │ │ ├── app-routing.module.ts │ │ ├── app.module.ts │ │ ├── app.component.spec.ts │ │ ├── app.component.ts │ │ ├── app.component.html │ │ └── app.service.ts │ ├── main.ts │ └── index.html ├── .eslintignore ├── .vscode │ ├── settings.json │ ├── extensions.json │ ├── launch.json │ └── tasks.json ├── .prettierignore ├── .stylelintrc.json ├── .prettierrc.json ├── tsconfig.app.json ├── tsconfig.spec.json ├── .editorconfig ├── ngcc.config.js ├── .eslintrc.js ├── .gitignore ├── tsconfig.json ├── README.md ├── package.json └── angular.json ├── CODEOWNERS ├── React ├── src │ ├── vite-env.d.ts │ ├── App.css │ ├── setupTests.ts │ ├── App.test.tsx │ ├── main.tsx │ ├── EditorOptions.ts │ ├── index.css │ ├── LabelTemplate.tsx │ ├── LabelNotesTemplate.tsx │ ├── assets │ │ └── react.svg │ ├── data.ts │ └── App.tsx ├── .eslintignore ├── .stylelintrc.json ├── public │ ├── robots.txt │ ├── favicon.ico │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── vite.svg ├── .vscode │ └── settings.json ├── vite.config.ts ├── tsconfig.json ├── vitest.config.ts ├── .gitignore ├── index.html ├── tsconfig.app.json ├── tsconfig.node.json ├── .eslintrc.cjs ├── package.json └── README.md ├── Vue ├── .eslintignore ├── .stylelintrc.json ├── .prettierrc.json ├── .vscode │ ├── extensions.json │ └── settings.json ├── public │ ├── favicon.ico │ └── orig_index.html ├── shims-vue.d.ts ├── tsconfig.vitest.json ├── env.d.ts ├── src │ ├── assets │ │ └── main.css │ ├── main.ts │ ├── LabelTemplate.vue │ ├── LabelNotesTemplate.vue │ ├── data.ts │ └── App.vue ├── tsconfig.config.json ├── tsconfig.json ├── tsconfig.app.json ├── index.html ├── .gitignore ├── vite.config.ts ├── .eslintrc.cjs ├── package.json └── README.md ├── ASP.NET Core ├── Views │ ├── _ViewStart.cshtml │ ├── _ViewImports.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ └── _Layout.cshtml │ └── Home │ │ └── Index.cshtml ├── wwwroot │ └── css │ │ └── Site.css ├── appsettings.Development.json ├── appsettings.json ├── package.json ├── Controllers │ ├── HomeController.cs │ └── SampleDataController.cs ├── Extensions │ └── Extensions.cs ├── ASP.NET Core.sln ├── Program.cs ├── ASP.NET Core.csproj ├── Models │ ├── Employee.cs │ └── EmployeeStore.cs ├── gulpfile.js └── Readme.md ├── config.json ├── dx-datagrid-custom-editing-form.png ├── .gitattributes ├── .lycheeignore ├── LICENSE ├── .github └── workflows │ ├── vale.yml │ ├── typescript.yml │ └── lint.yml ├── README.md ├── .gitignore └── test-example.ps1 /jQuery/.stylelintignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Angular/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Angular/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @DevExpressExampleBot -------------------------------------------------------------------------------- /jQuery/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | -------------------------------------------------------------------------------- /jQuery/.prettierignore: -------------------------------------------------------------------------------- 1 | *.js 2 | *.css 3 | .github 4 | -------------------------------------------------------------------------------- /React/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /Vue/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | dist/* 3 | .eslintrc.cjs 4 | -------------------------------------------------------------------------------- /React/src/App.css: -------------------------------------------------------------------------------- 1 | .main { 2 | margin: 50px; 3 | width: 90vw; 4 | } -------------------------------------------------------------------------------- /ASP.NET Core/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "autoGenerateVb": false, 3 | "runOnWeb": true 4 | } 5 | -------------------------------------------------------------------------------- /React/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | build/* 3 | .eslintrc.js 4 | dist/assets/* -------------------------------------------------------------------------------- /React/.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint-config-devextreme/stylelintrc" 3 | } 4 | -------------------------------------------------------------------------------- /Vue/.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint-config-devextreme/stylelintrc" 3 | } 4 | -------------------------------------------------------------------------------- /jQuery/.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint-config-devextreme/stylelintrc" 3 | } 4 | -------------------------------------------------------------------------------- /React/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /Vue/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "endOfLine": "auto", 3 | "embeddedLanguageFormatting": "auto" 4 | } -------------------------------------------------------------------------------- /Angular/src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /Vue/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"] 3 | } 4 | -------------------------------------------------------------------------------- /jQuery/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /React/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /Vue/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /Angular/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /jQuery/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevExpress-Examples/devextreme-datagrid-custom-editing-form/HEAD/jQuery/favicon.ico -------------------------------------------------------------------------------- /jQuery/bs-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "port": 5050, 3 | "startPath": "src/index.html", 4 | "files": ["./src/**/*.{html,css,js}"] 5 | } 6 | -------------------------------------------------------------------------------- /ASP.NET Core/wwwroot/css/Site.css: -------------------------------------------------------------------------------- 1 | .demo-container { 2 | margin: 50px; 3 | width: 90vw; 4 | } 5 | body { 6 | margin: 8px; 7 | } 8 | -------------------------------------------------------------------------------- /Angular/.prettierignore: -------------------------------------------------------------------------------- 1 | *.js 2 | *.mjs 3 | *.ts 4 | *.vue 5 | *.css 6 | *.scss 7 | *.md 8 | *.json 9 | .github 10 | dist/ 11 | **/dist/ -------------------------------------------------------------------------------- /Angular/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevExpress-Examples/devextreme-datagrid-custom-editing-form/HEAD/Angular/src/favicon.ico -------------------------------------------------------------------------------- /React/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevExpress-Examples/devextreme-datagrid-custom-editing-form/HEAD/React/public/favicon.ico -------------------------------------------------------------------------------- /React/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevExpress-Examples/devextreme-datagrid-custom-editing-form/HEAD/React/public/logo192.png -------------------------------------------------------------------------------- /React/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevExpress-Examples/devextreme-datagrid-custom-editing-form/HEAD/React/public/logo512.png -------------------------------------------------------------------------------- /Vue/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevExpress-Examples/devextreme-datagrid-custom-editing-form/HEAD/Vue/public/favicon.ico -------------------------------------------------------------------------------- /jQuery/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "htmlWhitespaceSensitivity": "strict", 4 | "printWidth": 200, 5 | "overrides": [] 6 | } 7 | -------------------------------------------------------------------------------- /Angular/.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "stylelint-config-standard-scss", 4 | "eslint-config-devextreme/stylelintrc" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /dx-datagrid-custom-editing-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevExpress-Examples/devextreme-datagrid-custom-editing-form/HEAD/dx-datagrid-custom-editing-form.png -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | 3 | VB/* linguist-vendored 4 | scripts linguist-vendored 5 | *.css linguist-detectable=false 6 | *.aff linguist-detectable=false 7 | -------------------------------------------------------------------------------- /Angular/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846 3 | "recommendations": ["angular.ng-template"] 4 | } 5 | -------------------------------------------------------------------------------- /Angular/src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | .default-style { 2 | margin: 50px; 3 | width: 90vw; 4 | } 5 | 6 | ::ng-deep .dx-scrollview-bottom-pocket { 7 | display: none; 8 | } 9 | -------------------------------------------------------------------------------- /ASP.NET Core/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using ASP_NET_Core 2 | @namespace ASP_NET_Core.Models 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | @using DevExtreme.AspNet.Mvc 5 | -------------------------------------------------------------------------------- /Vue/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import type { DefineComponent } from 'vue'; 3 | const component: DefineComponent<{}, {}, any>; 4 | export default component; 5 | } 6 | -------------------------------------------------------------------------------- /React/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import React from '@vitejs/plugin-react'; 3 | 4 | // https://vite.dev/config/ 5 | export default defineConfig({ 6 | plugins: [React()], 7 | }); 8 | -------------------------------------------------------------------------------- /Vue/tsconfig.vitest.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.app.json", 3 | "exclude": [], 4 | "compilerOptions": { 5 | "composite": true, 6 | "lib": [], 7 | "types": ["node", "jsdom"] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Vue/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | import type { DefineComponent } from 'vue'; 5 | const component: DefineComponent<{}, {}, any>; 6 | export default component; 7 | } 8 | -------------------------------------------------------------------------------- /React/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "compilerOptions": { 4 | "strict": true 5 | }, 6 | "references": [ 7 | { "path": "./tsconfig.app.json" }, 8 | { "path": "./tsconfig.node.json" } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /ASP.NET Core/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /React/vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config'; 2 | 3 | export default defineConfig({ 4 | test: { 5 | environment: 'jsdom', 6 | globals: true, 7 | setupFiles: './src/setupTests.ts', 8 | }, 9 | }); 10 | -------------------------------------------------------------------------------- /Vue/src/assets/main.css: -------------------------------------------------------------------------------- 1 | .main { 2 | font-family: Avenir, Helvetica, Arial, sans-serif; 3 | -webkit-font-smoothing: antialiased; 4 | -moz-osx-font-smoothing: grayscale; 5 | color: #2c3e50; 6 | margin: 50px 50px; 7 | width: 90vh; 8 | } -------------------------------------------------------------------------------- /Vue/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue'; 2 | import App from './App.vue'; 3 | 4 | import 'devextreme/dist/css/dx.light.css'; 5 | import './assets/main.css'; 6 | 7 | const app = createApp(App); 8 | 9 | app.mount('#app'); 10 | -------------------------------------------------------------------------------- /.lycheeignore: -------------------------------------------------------------------------------- 1 | https://www.devexpress.com/support/examples/survey.xml?* 2 | https://supportcenter.devexpress.com/ticket/create 3 | http://localhost* 4 | https://localhost* 5 | https://docs.devexpress.com/* 6 | https://js.devexpress.com/*/Documentation/* -------------------------------------------------------------------------------- /ASP.NET Core/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /Vue/tsconfig.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.node.json", 3 | "include": ["vite.config.*", "vitest.config.*", "cypress.config.*", "playwright.config.*"], 4 | "compilerOptions": { 5 | "composite": true, 6 | "types": ["node"] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./tsconfig.config.json" 6 | }, 7 | { 8 | "path": "./tsconfig.app.json" 9 | }, 10 | { 11 | "path": "./tsconfig.vitest.json" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /React/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | 7 | -------------------------------------------------------------------------------- /Angular/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "htmlWhitespaceSensitivity": "strict", 4 | "printWidth": 200, 5 | "overrides": [{ 6 | "files": "**/*.component.html", 7 | "options": { 8 | "printWidth": 80 9 | } 10 | }] 11 | } 12 | -------------------------------------------------------------------------------- /Angular/src/main.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2 | 3 | import { AppModule } from './app/app.module'; 4 | 5 | platformBrowserDynamic().bootstrapModule(AppModule) 6 | // eslint-disable-next-line no-console 7 | .catch((err) => console.error(err)); 8 | -------------------------------------------------------------------------------- /React/src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /React/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App.tsx'; 5 | 6 | createRoot(document.getElementById('root') as HTMLElement).render( 7 | 8 | 9 | , 10 | ); 11 | -------------------------------------------------------------------------------- /jQuery/src/index.css: -------------------------------------------------------------------------------- 1 | .demo-container { 2 | margin: 50px; 3 | width: 90vh; 4 | } 5 | 6 | #helped-info { 7 | color: #42a5f5; 8 | } 9 | 10 | #tooltip-content { 11 | font-size: 14px; 12 | font-weight: bold; 13 | } 14 | 15 | #template-content { 16 | display: inline-flex; 17 | } 18 | -------------------------------------------------------------------------------- /Angular/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | const routes: Routes = []; 5 | 6 | @NgModule({ 7 | imports: [RouterModule.forRoot(routes)], 8 | exports: [RouterModule], 9 | }) 10 | export class AppRoutingModule { } 11 | -------------------------------------------------------------------------------- /Angular/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts" 10 | ], 11 | "include": [ 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /Vue/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.web.json", 3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue", "shims-vue.d.ts"], 4 | "exclude": ["src/**/__tests__/*"], 5 | "compilerOptions": { 6 | "composite": true, 7 | "baseUrl": ".", 8 | "paths": { 9 | "@/*": ["./src/*"] 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Angular/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "include": [ 11 | "src/**/*.spec.ts", 12 | "src/**/*.d.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /Angular/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /Angular/ngcc.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | packages: { 3 | 'devextreme-angular': { 4 | ignorableDeepImportMatchers: [ 5 | /devextreme\//, 6 | /jszip\// 7 | ] 8 | }, 9 | 'devextreme' : { 10 | ignorableDeepImportMatchers: [ 11 | /devextreme-quill\// 12 | ] 13 | } 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /React/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | /dist/* 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /Angular/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Angular 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ASP.NET Core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "name": "asp.net", 4 | "private": true, 5 | "dependencies": { 6 | "jquery": "3.7.1", 7 | "devextreme-dist": "25.1.3", 8 | "devextreme-aspnet-data": "^5.1.0", 9 | "bootstrap": "^5.3.7" 10 | }, 11 | "devDependencies": { 12 | "gulp": "4.0.2", 13 | "gulp-concat": "2.6.1", 14 | "rimraf": "5.0.7" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /React/src/EditorOptions.ts: -------------------------------------------------------------------------------- 1 | import { positions } from './data.js'; 2 | 3 | export const positionEditorOptions = { items: positions, searchEnabled: true }; 4 | export const notesEditorOptions = { height: 90, maxLength: 200 }; 5 | export const phoneEditorOptions = { 6 | mask: '+1 (X00) 000-0000', 7 | maskRules: { X: /[02-9]/ }, 8 | maskInvalidMessage: 'The phone must have a correct USA phone format', 9 | }; 10 | -------------------------------------------------------------------------------- /Vue/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite App 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /React/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, 4 | Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; 5 | -webkit-font-smoothing: antialiased; 6 | -moz-osx-font-smoothing: grayscale; 7 | } 8 | 9 | code { 10 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; 11 | } 12 | -------------------------------------------------------------------------------- /React/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Angular/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ['devextreme/spell-check'], 4 | overrides: [{ 5 | files: ['*.ts', '*.html'], 6 | extends: ['devextreme/angular'], 7 | env: { 8 | browser: true, 9 | es6: true 10 | }, 11 | parserOptions: { 12 | project: './tsconfig.json', 13 | tsconfigRootDir: __dirname, 14 | 'createDefaultProgram': true, 15 | 'ecmaVersion': 6, 16 | }, 17 | }] 18 | }; 19 | -------------------------------------------------------------------------------- /Vue/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | /cypress/videos/ 18 | /cypress/screenshots/ 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | !.vscode/settings.json 24 | .idea 25 | *.suo 26 | *.ntvs* 27 | *.njsproj 28 | *.sln 29 | *.sw? 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This code example is provided "as is" without warranty of any kind. Developer Express Inc ("DevExpress") disclaims all warranties, 2 | either express or implied, including the warranties of merchantability and fitness for a particular purpose. 3 | 4 | For licensing terms and conditions of DevExpress product(s) required for, or associated with the use of this code example, 5 | please refer to the applicable End-User License Agreement at https://www.devexpress.com/Support/licensingfaq.xml -------------------------------------------------------------------------------- /Vue/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url'; 2 | 3 | import { defineConfig } from 'vite'; 4 | import vue from '@vitejs/plugin-vue'; 5 | import vueJsx from '@vitejs/plugin-vue-jsx'; 6 | 7 | // https://vitejs.dev/config/ 8 | export default defineConfig({ 9 | plugins: [vue(), vueJsx()], 10 | resolve: { 11 | alias: { 12 | '@': fileURLToPath(new URL('./src', import.meta.url)), 13 | 'devextreme/ui': 'devextreme/esm/ui', 14 | }, 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /ASP.NET Core/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 |

An error occurred while the server was processing your request.

2 | 3 |

4 | To display detailed information about the error, set the ASPNETCORE_ENVIRONMENT environment variable to Development and restart the app. 5 |

6 |

7 | The Development environment should not be enabled for deployed applications because it provides users access to exceptions that can contain sensitive information. 8 |

-------------------------------------------------------------------------------- /Vue/src/LabelTemplate.vue: -------------------------------------------------------------------------------- 1 | 6 | 26 | -------------------------------------------------------------------------------- /jQuery/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ['devextreme/spell-check'], 4 | overrides: [{ 5 | files: ['*.js'], 6 | extends: ['devextreme/jquery'], 7 | env: { 8 | jquery: true, 9 | }, 10 | parser: '@babel/eslint-parser', 11 | parserOptions: { 12 | 'sourceType': 'module', 13 | 'ecmaVersion': 2018, 14 | 'requireConfigFile': false, 15 | }, 16 | globals: { 17 | System: true, 18 | DevExpress: true, 19 | }, 20 | }], 21 | }; 22 | -------------------------------------------------------------------------------- /Angular/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 3 | "version": "0.2.0", 4 | "configurations": [ 5 | { 6 | "name": "ng serve", 7 | "type": "pwa-chrome", 8 | "request": "launch", 9 | "preLaunchTask": "npm: start", 10 | "url": "http://localhost:4200/" 11 | }, 12 | { 13 | "name": "ng test", 14 | "type": "chrome", 15 | "request": "launch", 16 | "preLaunchTask": "npm: test", 17 | "url": "http://localhost:9876/debug.html" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /ASP.NET Core/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace ASP_NET_Core.Controllers 8 | { 9 | public class HomeController : Controller 10 | { 11 | public IActionResult Index() 12 | { 13 | return View(); 14 | } 15 | 16 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 17 | public IActionResult Error() { 18 | return View(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Vue/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ['devextreme/spell-check'], 4 | overrides: [{ 5 | files: ['*.ts', '*.vue'], 6 | extends: [ 7 | '@vue/eslint-config-typescript', 8 | 'devextreme/vue' 9 | ], 10 | env: { es6: true }, 11 | parserOptions: { 12 | project: './tsconfig.json', 13 | tsconfigRootDir: __dirname, 14 | 'createDefaultProgram': true, 15 | 'ecmaVersion': 2020, 16 | }, 17 | globals: { 18 | System: false, 19 | AzureGateway: false, 20 | AzureFileSystem: false, 21 | }, 22 | }] 23 | }; 24 | -------------------------------------------------------------------------------- /React/src/LabelTemplate.tsx: -------------------------------------------------------------------------------- 1 | interface LabelTemplateData { 2 | [key: string]: any; 3 | text?: string; 4 | } 5 | 6 | // eslint-disable-next-line no-unused-vars 7 | function LabelTemplate(iconName: string): (data: LabelTemplateData) => JSX.Element { 8 | function Template(data: LabelTemplateData): JSX.Element { 9 | return ( 10 |
11 | 12 | {data.text} 13 |
14 | ); 15 | } 16 | (Template as any).displayName = `LabelTemplate(${iconName})`; 17 | return Template; 18 | } 19 | 20 | export default LabelTemplate; 21 | -------------------------------------------------------------------------------- /React/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /ASP.NET Core/Extensions/Extensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc.ModelBinding; 2 | using System.Collections.Generic; 3 | using System; 4 | 5 | namespace ASP_NET_Core.Extensions 6 | { 7 | static class Extensions { 8 | public static string GetFullErrorMessage(this ModelStateDictionary modelState) { 9 | var messages = new List(); 10 | 11 | foreach (var entry in modelState) { 12 | foreach (var error in entry.Value.Errors) 13 | messages.Add(error.ErrorMessage); 14 | } 15 | 16 | return String.Join(" ", messages); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Vue/public/orig_index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Vue App 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /React/src/LabelNotesTemplate.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Tooltip } from 'devextreme-react/tooltip'; 3 | 4 | function LabelNotesTemplate(data: any): JSX.Element { 5 | return ( 6 | 7 |
8 | 9 | Additional 10 |
11 | { data.text } 12 |
13 | 14 | 19 |
This field must not exceed 200 characters
20 |
21 |
22 | ); 23 | } 24 | 25 | export default LabelNotesTemplate; 26 | -------------------------------------------------------------------------------- /Angular/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # Compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | /bazel-out 8 | 9 | # Node 10 | /node_modules 11 | npm-debug.log 12 | yarn-error.log 13 | 14 | # IDEs and editors 15 | .idea/ 16 | .project 17 | .classpath 18 | .c9/ 19 | *.launch 20 | .settings/ 21 | *.sublime-workspace 22 | 23 | # Visual Studio Code 24 | .vscode/* 25 | !.vscode/settings.json 26 | !.vscode/tasks.json 27 | !.vscode/launch.json 28 | !.vscode/extensions.json 29 | .history/* 30 | 31 | # Miscellaneous 32 | /.angular/cache 33 | .sass-cache/ 34 | /connect.lock 35 | /coverage 36 | /libpeerconnection.log 37 | testem.log 38 | /typings 39 | 40 | # System files 41 | .DS_Store 42 | Thumbs.db 43 | -------------------------------------------------------------------------------- /React/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", 5 | "target": "ES2020", 6 | "useDefineForClassFields": true, 7 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 8 | "module": "ESNext", 9 | "skipLibCheck": true, 10 | /* Bundler mode */ 11 | "moduleResolution": "bundler", 12 | "allowImportingTsExtensions": true, 13 | "verbatimModuleSyntax": true, 14 | "moduleDetection": "force", 15 | "noEmit": true, 16 | "jsx": "react-jsx", 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "strictNullChecks": true, 21 | "noUnusedLocals": true, 22 | "noUnusedParameters": true, 23 | "erasableSyntaxOnly": true, 24 | "noFallthroughCasesInSwitch": true, 25 | "noUncheckedSideEffectImports": true 26 | }, 27 | "include": ["src"] 28 | } 29 | -------------------------------------------------------------------------------- /React/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 5 | "target": "ES2022", 6 | "lib": ["ES2023"], 7 | "module": "ESNext", 8 | "types": ["node", "estree"], 9 | "skipLibCheck": true, 10 | 11 | /* Bundler mode */ 12 | "moduleResolution": "bundler", 13 | "allowImportingTsExtensions": true, 14 | "verbatimModuleSyntax": true, 15 | "moduleDetection": "force", 16 | "noEmit": true, 17 | 18 | /* Linting */ 19 | "strict": true, 20 | "strictNullChecks": true, 21 | "noUnusedLocals": true, 22 | "noUnusedParameters": true, 23 | "erasableSyntaxOnly": true, 24 | "noFallthroughCasesInSwitch": true, 25 | "noUncheckedSideEffectImports": true 26 | }, 27 | "include": ["vite.config.ts","vitest.config.ts", "*.test.tsx"], 28 | } 29 | -------------------------------------------------------------------------------- /Angular/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { 4 | DxPopupModule, 5 | DxSelectBoxModule, 6 | DxTextAreaModule, 7 | DxFormModule, 8 | DxTooltipModule, 9 | DxDataGridModule, 10 | DxTemplateModule, 11 | DxButtonModule, 12 | } from 'devextreme-angular'; 13 | import { AppRoutingModule } from './app-routing.module'; 14 | import { AppComponent } from './app.component'; 15 | 16 | @NgModule({ 17 | declarations: [ 18 | AppComponent, 19 | ], 20 | imports: [ 21 | BrowserModule, 22 | AppRoutingModule, 23 | DxPopupModule, 24 | DxSelectBoxModule, 25 | DxTextAreaModule, 26 | DxFormModule, 27 | DxTooltipModule, 28 | DxDataGridModule, 29 | DxTemplateModule, 30 | DxButtonModule, 31 | ], 32 | providers: [], 33 | bootstrap: [AppComponent], 34 | }) 35 | export class AppModule { } 36 | -------------------------------------------------------------------------------- /.github/workflows/vale.yml: -------------------------------------------------------------------------------- 1 | name: vale-validation 2 | on: 3 | pull_request: 4 | paths: 5 | - README.md 6 | - readme.md 7 | - Readme.md 8 | 9 | jobs: 10 | vale: 11 | name: runner / vale 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: clone repo 15 | uses: actions/checkout@v4 16 | - name: clone vale-styles repo 17 | uses: actions/checkout@v4 18 | with: 19 | repository: DevExpress/vale-styles 20 | path: vale-styles 21 | ssh-key: ${{ secrets.VALE_STYLES_ACCESS_KEY }} 22 | - name: copy vale rules to the root repo 23 | run: shopt -s dotglob && cp -r ./vale-styles/vale/* . 24 | - name: vale linter check 25 | uses: DevExpress/vale-action@reviewdog 26 | with: 27 | files: '["README.md", "readme.md", "Readme.md"]' 28 | fail_on_error: true 29 | filter_mode: nofilter 30 | reporter: github-check 31 | -------------------------------------------------------------------------------- /jQuery/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | DevExtreme jQuery app 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /ASP.NET Core/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | ASP_NET_Core 12 | 13 | 14 | @* Uncomment to use the HtmlEditor control *@ 15 | @* *@ 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | @RenderBody() 25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /jQuery/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dx-jquery", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "start": "npm run lite", 6 | "build": "npm run lint", 7 | "lite": "lite-server -c ./bs-config.json", 8 | "lint-html": "prettier --check src/*", 9 | "lint-js": "eslint --ext .js .", 10 | "lint-css": "stylelint src/**/*.css --allow-empty-input", 11 | "lint": "npm-run-all -p -c lint-js lint-css lint-html" 12 | }, 13 | "devDependencies": { 14 | "@babel/core": "^7.22.1", 15 | "@babel/eslint-parser": "^7.21.8", 16 | "eslint": "^8.41.0", 17 | "eslint-config-devextreme": "1.1.4", 18 | "eslint-plugin-no-only-tests": "^3.1.0", 19 | "htmlhint": "^1.1.4", 20 | "lite-server": "^2.6.1", 21 | "npm-run-all": "^4.1.5", 22 | "prettier": "2.8.8", 23 | "stylelint": "^15.6.1", 24 | "stylelint-config-standard": "^33.0.0" 25 | }, 26 | "dependencies": { 27 | "browser-sync": "^3.0.2", 28 | "devextreme": "25.1.3", 29 | "devextreme-dist": "25.1.3", 30 | "jquery": "^3.7.1" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Angular/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "baseUrl": "./", 6 | "outDir": "./dist/out-tsc", 7 | "forceConsistentCasingInFileNames": false, 8 | "strict": true, 9 | "noImplicitOverride": true, 10 | "noPropertyAccessFromIndexSignature": true, 11 | "noImplicitReturns": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "sourceMap": true, 14 | "declaration": false, 15 | "downlevelIteration": true, 16 | "experimentalDecorators": true, 17 | "moduleResolution": "node", 18 | "importHelpers": true, 19 | "target": "ES2022", 20 | "module": "ES2022", 21 | "useDefineForClassFields": false, 22 | "lib": [ 23 | "ES2022", 24 | "dom" 25 | ] 26 | }, 27 | "angularCompilerOptions": { 28 | "enableI18nLegacyMessageIdFormat": false, 29 | "strictInjectionParameters": true, 30 | "strictInputAccessModifiers": true, 31 | "strictTemplates": true 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Vue/src/LabelNotesTemplate.vue: -------------------------------------------------------------------------------- 1 | 19 | 35 | 36 | 50 | -------------------------------------------------------------------------------- /Angular/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558 3 | "version": "2.0.0", 4 | "tasks": [ 5 | { 6 | "type": "npm", 7 | "script": "start", 8 | "isBackground": true, 9 | "problemMatcher": { 10 | "owner": "typescript", 11 | "pattern": "$tsc", 12 | "background": { 13 | "activeOnStart": true, 14 | "beginsPattern": { 15 | "regexp": "(.*?)" 16 | }, 17 | "endsPattern": { 18 | "regexp": "bundle generation complete" 19 | } 20 | } 21 | } 22 | }, 23 | { 24 | "type": "npm", 25 | "script": "test", 26 | "isBackground": true, 27 | "problemMatcher": { 28 | "owner": "typescript", 29 | "pattern": "$tsc", 30 | "background": { 31 | "activeOnStart": true, 32 | "beginsPattern": { 33 | "regexp": "(.*?)" 34 | }, 35 | "endsPattern": { 36 | "regexp": "bundle generation complete" 37 | } 38 | } 39 | } 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /ASP.NET Core/ASP.NET Core.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30330.147 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ASP.NET Core", "ASP.NET Core.csproj", "{435CB7A8-3168-4BD2-815F-E54F708AF968}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {435CB7A8-3168-4BD2-815F-E54F708AF968}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {435CB7A8-3168-4BD2-815F-E54F708AF968}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {435CB7A8-3168-4BD2-815F-E54F708AF968}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {435CB7A8-3168-4BD2-815F-E54F708AF968}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {08AFB133-D1F6-4FE9-A66A-586B96B002D0} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /ASP.NET Core/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using Microsoft.Extensions.Hosting; 4 | 5 | namespace ASP_NET_Core { 6 | public class Program { 7 | public static void Main(string[] args) { 8 | var builder = WebApplication.CreateBuilder(args); 9 | 10 | // Add services to the container. 11 | builder.Services 12 | .AddControllersWithViews() 13 | .AddJsonOptions(options => options.JsonSerializerOptions.PropertyNamingPolicy = null); 14 | 15 | var app = builder.Build(); 16 | 17 | // Configure the HTTP request pipeline. 18 | if (app.Environment.IsDevelopment()) { 19 | app.UseDeveloperExceptionPage(); 20 | } else { 21 | app.UseExceptionHandler("/Home/Error"); 22 | } 23 | 24 | app.UseStaticFiles(); 25 | 26 | app.UseRouting(); 27 | 28 | app.UseAuthorization(); 29 | 30 | app.MapControllerRoute( 31 | name: "default", 32 | pattern: "{controller=Home}/{action=Index}/{id?}" 33 | ); 34 | 35 | app.Run(); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /Angular/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | import { RouterTestingModule } from '@angular/router/testing'; 3 | import { AppComponent } from './app.component'; 4 | 5 | describe('AppComponent', () => { 6 | beforeEach(async () => { 7 | await TestBed.configureTestingModule({ 8 | imports: [ 9 | RouterTestingModule, 10 | ], 11 | declarations: [ 12 | AppComponent, 13 | ], 14 | }).compileComponents(); 15 | }); 16 | 17 | it('should create the app', () => { 18 | const fixture = TestBed.createComponent(AppComponent); 19 | const app = fixture.componentInstance; 20 | expect(app).toBeTruthy(); 21 | }); 22 | 23 | it('should have as title \'angular-test\'', () => { 24 | const fixture = TestBed.createComponent(AppComponent); 25 | const app = fixture.componentInstance; 26 | expect(app.title).toEqual('angular-test'); 27 | }); 28 | 29 | it('should render title', () => { 30 | const fixture = TestBed.createComponent(AppComponent); 31 | fixture.detectChanges(); 32 | const compiled = fixture.nativeElement as HTMLElement; 33 | expect(compiled.querySelector('.content span')?.textContent).toContain('angular-test app is running!'); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /React/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ['devextreme/spell-check'], 4 | overrides: [{ 5 | files: ['*.ts', '*.tsx'], 6 | extends: ['devextreme/react'], 7 | env: { 8 | browser: true, 9 | es6: true 10 | }, 11 | parserOptions: { 12 | project: './tsconfig.json', 13 | tsconfigRootDir: __dirname, 14 | 'createDefaultProgram': true, 15 | ecmaVersion: 2022, 16 | sourceType: 'module', 17 | }, 18 | rules: { 19 | "react/react-in-jsx-scope": "off", 20 | "import/no-extraneous-dependencies": ["error", { 21 | "devDependencies": [ 22 | "**/vitest.config.ts", // allow vitest in config file 23 | "**/vite.config.ts", // allow vite in config file 24 | "**/*.test.tsx", // allow test files if needed 25 | "**/setupTests.ts", // allow setup tests file 26 | ] 27 | }] 28 | }, 29 | globals: { 30 | System: false, 31 | AzureGateway: false, 32 | AzureFileSystem: false, 33 | }, 34 | settings: { 35 | react: { 36 | createClass: 'createReactClass', 37 | 'pragma': 'React', 38 | version: '18.2', 39 | }, 40 | propWrapperFunctions: [ 41 | 'forbidExtraProps', 42 | ], 43 | }, 44 | }] 45 | }; -------------------------------------------------------------------------------- /Vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-project", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "run-p type-check build-only", 8 | "preview": "vite preview", 9 | "test:unit": "vitest --environment jsdom --root src/", 10 | "build-only": "vite build", 11 | "type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false", 12 | "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .eslintignore" 13 | }, 14 | "dependencies": { 15 | "devextreme": "25.1.3", 16 | "devextreme-vue": "25.1.3", 17 | "vue": "^3.2.45", 18 | "vue-router": "^4.1.6" 19 | }, 20 | "devDependencies": { 21 | "@rushstack/eslint-patch": "^1.1.4", 22 | "@types/jsdom": "^20.0.1", 23 | "@types/node": "^18.11.12", 24 | "@vitejs/plugin-vue": "^4.0.0", 25 | "@vitejs/plugin-vue-jsx": "^3.0.0", 26 | "@vue/eslint-config-prettier": "^7.0.0", 27 | "@vue/eslint-config-typescript": "^11.0.0", 28 | "@vue/test-utils": "^2.2.6", 29 | "@vue/tsconfig": "^0.1.3", 30 | "eslint": "^8.22.0", 31 | "eslint-config-devextreme": "1.1.6", 32 | "eslint-plugin-no-only-tests": "^3.1.0", 33 | "eslint-plugin-vue": "^9.3.0", 34 | "jsdom": "^20.0.3", 35 | "npm-run-all": "^4.1.5", 36 | "prettier": "^2.7.1", 37 | "typescript": "~4.7.4", 38 | "vite": "^4.0.0", 39 | "vitest": "^0.25.6", 40 | "vue-tsc": "^1.0.12" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /React/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ASP.NET Core/ASP.NET Core.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /React/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc -b && vite build", 9 | "test": "vitest", 10 | "test:watch": "vitest --watch", 11 | "lint-ts": "eslint .", 12 | "lint-css": "stylelint src/**/*.css --allow-empty-input", 13 | "lint": "npm-run-all -p -c lint-ts lint-css", 14 | "preview": "vite preview" 15 | }, 16 | "dependencies": { 17 | "devextreme": "25.1.3", 18 | "devextreme-react": "25.1.3", 19 | "react": "^18.2.0", 20 | "react-dom": "^18.2.0" 21 | }, 22 | "devDependencies": { 23 | "@babel/plugin-proposal-private-property-in-object": "^7.21.11", 24 | "@testing-library/jest-dom": "^5.16.5", 25 | "@testing-library/react": "^14.1.2", 26 | "@testing-library/user-event": "^14.4.3", 27 | "@types/react": "^18.2.47", 28 | "@types/react-dom": "^18.2.17", 29 | "@vitejs/plugin-react": "^4.4.1", 30 | "@vitest/coverage-v8": "^1.5.0", 31 | "eslint": "^8.35.0", 32 | "eslint-config-devextreme": "1.1.4", 33 | "eslint-plugin-no-only-tests": "2.6.0", 34 | "eslint-plugin-react": "7.31.10", 35 | "eslint-plugin-react-hooks": "^5.2.0", 36 | "eslint-plugin-react-perf": "^3.3.1", 37 | "globals": "^16.0.0", 38 | "jsdom": "^24.0.0", 39 | "npm-run-all": "^4.1.5", 40 | "stylelint": "^15.6.1", 41 | "stylelint-config-standard": "^33.0.0", 42 | "ts-node": "10.9.2", 43 | "typescript": "~5.8.2", 44 | "typescript-eslint": "^8.18.2", 45 | "vite": "^6.3.5", 46 | "vitest": "^1.5.0" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /jQuery/README.md: -------------------------------------------------------------------------------- 1 | # jQuery DevExtreme Example 2 | 3 | ## Installation 4 | 5 | Download the example and use NPM to install required libraries. 6 | 7 | ``` 8 | npm install 9 | ``` 10 | 11 | This project includes: 12 | 13 | - DevExtreme 25.1.3 14 | - jQuery 3.7.1 15 | - lite-server for development 16 | - ESLint, Stylelint, and Prettier for code quality 17 | 18 | ## Code 19 | 20 | Take a look at the following files of this example to see the required code: 21 | 22 | **Source Files:** 23 | 24 | - `src/index.html` - Main HTML file with DevExtreme component setup 25 | - `src/index.js` - JavaScript code with DevExtreme component initialization 26 | - `src/index.css` - Custom styles for the application 27 | 28 | **Configuration Files:** 29 | 30 | - `package.json` - NPM dependencies and scripts 31 | - `bs-config.json` - Lite-server configuration 32 | - `favicon.ico` - Application icon 33 | 34 | ## Development server 35 | 36 | Run the `npm start` command to run the development server. The application will be available at: 37 | 38 | ``` 39 | http://localhost:5050/src/index.html 40 | ``` 41 | 42 | ## Linting and Code Quality 43 | 44 | This project includes several code quality tools: 45 | 46 | - `npm run lint` - Run all linting checks 47 | - `npm run lint-js` - ESLint for JavaScript files 48 | - `npm run lint-css` - Stylelint for CSS files 49 | - `npm run lint-html` - Prettier for HTML formatting 50 | 51 | ## Further help 52 | 53 | You can learn more about jQuery API in the [jQuery documentation](https://api.jquery.com/). 54 | 55 | To get more help on DevExtreme submit an issue in the [Support Center](https://supportcenter.devexpress.com/ticket/create) 56 | -------------------------------------------------------------------------------- /Angular/README.md: -------------------------------------------------------------------------------- 1 | # Angular DevExtreme Example 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 18.0.4 and includes DevExtreme Angular components version 25.1.3. 4 | 5 | ## Development server 6 | 7 | Run `npm start` or `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 12 | 13 | ## Build 14 | 15 | Run `npm run build` or `ng build` to build the project. The build artifacts will be stored in the `dist/Angular/` directory. 16 | 17 | ## Running unit tests 18 | 19 | Run `npm test` or `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Linting 22 | 23 | Run `npm run lint` to execute linting checks for TypeScript, CSS/SCSS, and HTML formatting. 24 | - `npm run lint-ts` - ESLint for TypeScript files 25 | - `npm run lint-css` - Stylelint for CSS/SCSS files 26 | - `npm run lint-html` - Prettier for HTML formatting 27 | 28 | ## Running end-to-end tests 29 | 30 | Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. 31 | 32 | ## Further help 33 | 34 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. 35 | To get more help on DevExtreme submit an issue on [GitHub](https://github.com/DevExpress/devextreme/issues) or [Support Center](https://supportcenter.devexpress.com/ticket/create) 36 | -------------------------------------------------------------------------------- /ASP.NET Core/Controllers/SampleDataController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Net.Http; 6 | using System.Xml.Linq; 7 | using ASP.NET_Core.Models; 8 | using ASP_NET_Core.Models; 9 | using DevExtreme.AspNet.Data; 10 | using DevExtreme.AspNet.Mvc; 11 | using Microsoft.AspNetCore.Mvc; 12 | using Newtonsoft.Json; 13 | using ASP_NET_Core.Extensions; 14 | 15 | namespace ASP_NET_Core.Controllers { 16 | 17 | [Route("api/[controller]")] 18 | public class SampleDataController : Controller { 19 | 20 | [HttpGet] 21 | public object Get(DataSourceLoadOptions loadOptions) { 22 | return DataSourceLoader.Load(EmployeeStore.Employees, loadOptions); 23 | } 24 | [HttpPost] 25 | public IActionResult Add(string values) { 26 | var newEmployee = new Employee(); 27 | JsonConvert.PopulateObject(values, newEmployee); 28 | 29 | if (!TryValidateModel(newEmployee)) 30 | return BadRequest(ModelState.GetFullErrorMessage()); 31 | 32 | EmployeeStore.Employees.Add(newEmployee); 33 | 34 | return Ok(); 35 | } 36 | 37 | [HttpPut] 38 | public IActionResult Update(int key, string values) { 39 | var employee = EmployeeStore.Employees.First(a => a.ID == key); 40 | JsonConvert.PopulateObject(values, employee); 41 | 42 | if (!TryValidateModel(employee)) 43 | return BadRequest(ModelState.GetFullErrorMessage()); 44 | 45 | return Ok(); 46 | } 47 | 48 | [HttpDelete] 49 | public void Delete(int key) { 50 | var employee = EmployeeStore.Employees.First(a => a.ID == key); 51 | EmployeeStore.Employees.Remove(employee); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /Angular/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-test", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "watch": "ng build --watch --configuration development", 9 | "test": "ng test", 10 | "lint-html": "prettier --check .", 11 | "lint-ts": "eslint --ext .ts .", 12 | "lint-css": "stylelint src/**/*.{css,scss} --allow-empty-input", 13 | "lint": "npm-run-all -p -c lint-ts lint-css lint-html" 14 | }, 15 | "private": true, 16 | "dependencies": { 17 | "@angular/animations": "^18.0.3", 18 | "@angular/common": "^18.0.3", 19 | "@angular/compiler": "^18.0.3", 20 | "@angular/core": "^18.0.3", 21 | "@angular/forms": "^18.0.3", 22 | "@angular/platform-browser": "^18.0.3", 23 | "@angular/platform-browser-dynamic": "^18.0.3", 24 | "@angular/router": "^18.0.3", 25 | "devextreme": "25.1.3", 26 | "devextreme-angular": "25.1.3", 27 | "rxjs": "~7.8.0", 28 | "tslib": "^2.3.0", 29 | "zone.js": "~0.14.7" 30 | }, 31 | "devDependencies": { 32 | "@angular-devkit/build-angular": "^18.0.4", 33 | "@angular/cli": "~18.0.4", 34 | "@angular/compiler-cli": "^18.0.3", 35 | "@types/jasmine": "~4.3.0", 36 | "eslint": "^8.39.0", 37 | "eslint-config-devextreme": "1.1.4", 38 | "eslint-plugin-no-only-tests": "^3.1.0", 39 | "jasmine-core": "~4.5.0", 40 | "karma": "~6.4.0", 41 | "karma-chrome-launcher": "~3.1.0", 42 | "karma-coverage": "~2.2.0", 43 | "karma-jasmine": "~5.1.0", 44 | "karma-jasmine-html-reporter": "~2.0.0", 45 | "npm-run-all": "^4.1.5", 46 | "prettier": "2.8.8", 47 | "stylelint": "^15.6.1", 48 | "stylelint-config-standard": "^33.0.0", 49 | "stylelint-config-standard-scss": "^9.0.0", 50 | "stylelint-scss": "^5.0.0", 51 | "typescript": "~5.4.5" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ASP.NET Core/Models/Employee.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Xml.Linq; 5 | using System; 6 | 7 | namespace ASP_NET_Core.Models { 8 | public class Employee 9 | { 10 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "ID")] 11 | public int ID { get; set; } 12 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "FirstName")] 13 | [Required(ErrorMessage = "First Name is required.")] 14 | public string FirstName { get; set; } 15 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "LastName")] 16 | [Required(ErrorMessage = "Last Name is required.")] 17 | public string LastName { get; set; } 18 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "Prefix")] 19 | public string Prefix { get; set; } 20 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "Position")] 21 | public string Position { get; set; } 22 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "BirthDate")] 23 | [Required(ErrorMessage = "Birth Date is required.")] 24 | public DateTime? BirthDate { get; set; } 25 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "HireDate")] 26 | public DateTime? HireDate { get; set; } 27 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "Notes")] 28 | public string Notes { get; set; } 29 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "Address")] 30 | public string Address { get; set; } 31 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "Phone")] 32 | [Required(ErrorMessage = "Phone Number is required.")] 33 | public string Phone { get; set; } 34 | [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "Email")] 35 | [EmailAddress(ErrorMessage = "Email is incorrect.")] 36 | public string Email { get; set; } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /.github/workflows/typescript.yml: -------------------------------------------------------------------------------- 1 | name: TS compilation 2 | 3 | concurrency: 4 | group: wf-${{github.event.pull_request.number || github.sha}}-${{github.workflow}} 5 | cancel-in-progress: true 6 | 7 | on: 8 | pull_request: 9 | push: 10 | branches: 11 | - "[0-9][0-9].[0-9].[0-9]*" 12 | 13 | jobs: 14 | Angular: 15 | runs-on: ubuntu-latest 16 | timeout-minutes: 60 17 | steps: 18 | - name: Get sources 19 | uses: actions/checkout@v3 20 | 21 | - name: Use Node.js 22 | uses: actions/setup-node@v3 23 | 24 | - name: Restore npm cache 25 | uses: actions/cache@v3 26 | with: 27 | path: ./Angular/node_modules 28 | key: ${{ runner.os }}-node-modules-${{ hashFiles('**/package-lock.json') }} 29 | restore-keys: ${{ runner.os }}-node-modules 30 | 31 | - name: Run npm install 32 | working-directory: Angular 33 | run: npm install --no-audit --no-fund 34 | 35 | - name: TSC Angular 36 | working-directory: Angular 37 | run: npm run build 38 | 39 | React: 40 | runs-on: ubuntu-latest 41 | timeout-minutes: 60 42 | steps: 43 | - name: Get sources 44 | uses: actions/checkout@v3 45 | 46 | - name: Use Node.js 47 | uses: actions/setup-node@v4 48 | with: 49 | node-version: '20' 50 | 51 | - name: Restore npm cache 52 | uses: actions/cache@v3 53 | with: 54 | path: ./React/node_modules 55 | key: ${{ runner.os }}-node-modules-${{ hashFiles('**/package-lock.json') }} 56 | restore-keys: ${{ runner.os }}-node-modules 57 | 58 | - name: Run npm install 59 | working-directory: React 60 | run: npm install --no-audit --no-fund 61 | 62 | - name: TSC React 63 | working-directory: React 64 | run: npm run build 65 | 66 | Vue: 67 | runs-on: ubuntu-latest 68 | timeout-minutes: 60 69 | steps: 70 | - name: Get sources 71 | uses: actions/checkout@v3 72 | 73 | - name: Use Node.js 74 | uses: actions/setup-node@v3 75 | 76 | - name: Restore npm cache 77 | uses: actions/cache@v3 78 | with: 79 | path: ./Vue/node_modules 80 | key: ${{ runner.os }}-node-modules-${{ hashFiles('**/package-lock.json') }} 81 | restore-keys: ${{ runner.os }}-node-modules 82 | 83 | - name: Run npm install 84 | working-directory: Vue 85 | run: npm install --no-audit --no-fund 86 | 87 | - name: TSC Vue 88 | working-directory: Vue 89 | run: npm run type-check 90 | -------------------------------------------------------------------------------- /Angular/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ViewChild } from '@angular/core'; 2 | import { DxDataGridComponent } from 'devextreme-angular'; 3 | 4 | import validationEngine from 'devextreme/ui/validation_engine'; 5 | 6 | import ArrayStore from 'devextreme/data/array_store'; 7 | import { DxDataGridTypes } from 'devextreme-angular/ui/data-grid'; 8 | import { Employee, Service } from './app.service'; 9 | 10 | interface PositionEditorOptions { 11 | items: string[]; 12 | searchEnabled: boolean; 13 | } 14 | 15 | @Component({ 16 | selector: 'app-root', 17 | templateUrl: './app.component.html', 18 | styleUrls: ['./app.component.scss'], 19 | providers: [Employee, Service], 20 | }) 21 | 22 | export class AppComponent { 23 | @ViewChild('grid', { static: false }) grid!: DxDataGridComponent; 24 | 25 | employees: Employee[]; 26 | 27 | employeeStore: ArrayStore; 28 | 29 | formData: Employee = {} as Employee; 30 | 31 | isNewRecord = true; 32 | 33 | visible = false; 34 | 35 | positionEditorOptions: PositionEditorOptions; 36 | 37 | readonly notesEditorOptions = { height: 90, maxLength: 200 }; 38 | 39 | readonly phoneEditorOptions = { 40 | mask: '+1 (X00) 000-0000', 41 | maskRules: { X: /[02-9]/ }, 42 | maskInvalidMessage: 'The phone must have a correct USA phone format', 43 | }; 44 | 45 | readonly labelTemplates = [ 46 | { name: 'name', icon: 'dx-icon-user' }, 47 | { name: 'position', icon: 'dx-icon-info' }, 48 | { name: 'date', icon: 'dx-icon-event' }, 49 | { name: 'address', icon: 'dx-icon-home' }, 50 | { name: 'phone', icon: 'dx-icon-tel' }, 51 | { name: 'email', icon: 'dx-icon-email' }, 52 | ]; 53 | 54 | readonly validationGroupName = 'gridForm'; 55 | 56 | constructor(service: Service) { 57 | this.employees = service.getEmployees(); 58 | 59 | this.employeeStore = new ArrayStore({ 60 | data: this.employees, 61 | key: 'ID', 62 | }); 63 | 64 | this.positionEditorOptions = { items: service.getPositions(), searchEnabled: true }; 65 | } 66 | 67 | showPopup = (isNewRecord: boolean, formData: Employee): void => { 68 | this.formData = formData; 69 | this.isNewRecord = isNewRecord; 70 | this.visible = true; 71 | }; 72 | 73 | hidePopup = (): void => { 74 | this.visible = false; 75 | }; 76 | 77 | confirmChanges = (): void => { 78 | const result = validationEngine.validateGroup(this.validationGroupName); 79 | 80 | if (!result.isValid) return; 81 | 82 | if (this.isNewRecord) { 83 | this.employeeStore.insert(this.formData).catch(() => {}); 84 | } else { 85 | this.employeeStore.update(this.formData.ID, this.formData).catch(() => {}); 86 | } 87 | 88 | this.grid.instance.refresh(true).catch(() => {}); 89 | this.hidePopup(); 90 | }; 91 | 92 | addRow = (): void => { 93 | this.showPopup(true, {} as Employee); 94 | }; 95 | 96 | editRow = (e: DxDataGridTypes.ColumnButtonClickEvent): void => { 97 | this.showPopup(false, { ...e.row?.data }); 98 | }; 99 | } 100 | -------------------------------------------------------------------------------- /Vue/README.md: -------------------------------------------------------------------------------- 1 | # Vue 3 + TypeScript + Vite + DevExtreme 2 | 3 | This template should help get you started developing with Vue 3 in Vite and DevExtreme components. 4 | 5 | This project includes: 6 | - Vue 3.2.45 7 | - TypeScript 4.7.4 8 | - Vite for fast development and building 9 | - DevExtreme Vue 25.1.3 10 | - Vue Router 4.1.6 11 | - Vitest for testing 12 | - ESLint and Prettier for code quality 13 | 14 | ## Recommended IDE Setup 15 | 16 | For best TypeScript support in VS Code, see the official Vue guide: [Using Vue with TypeScript in VS Code](https://vuejs.org/guide/typescript/overview#using-vue-with-typescript). 17 | 18 | ## Type Support for `.vue` Imports in TS 19 | 20 | TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. For editor integration, see the official Vue guide: [Using Vue with TypeScript in VS Code](https://vuejs.org/guide/typescript/overview#using-vue-with-typescript). 21 | 22 | 23 | > **Note:** 24 | > To type-check your project, use: 25 | > ```sh 26 | > npm run type-check 27 | > ``` 28 | > This uses `vue-tsc` to provide type checking for `.vue` files, as recommended in the [official Vue TypeScript guide](https://vuejs.org/guide/typescript/overview.html). 29 | 30 | ## Customize configuration 31 | 32 | See [Vite Configuration Reference](https://vite.dev/config/). 33 | 34 | ## Project Setup 35 | 36 | ```sh 37 | npm install 38 | ``` 39 | 40 | ## Code Structure 41 | 42 | **Source Files:** 43 | - `src/App.vue` - Main Vue application component with router 44 | - `src/main.ts` - Application entry point 45 | - `src/components/HomeContent.vue` - Example component with DevExtreme Button 46 | - `src/components/__tests__/` - Component tests 47 | - `src/views/HomeView.vue` - Home page view 48 | - `src/router/index.ts` - Vue Router configuration 49 | - `src/assets/` - Static assets 50 | 51 | **Configuration Files:** 52 | - `vite.config.ts` - Vite configuration with Vue and DevExtreme optimizations 53 | - `package.json` - Dependencies and scripts 54 | - `tsconfig.json` - TypeScript configuration 55 | - `tsconfig.vitest.json` - Vitest-specific TypeScript configuration 56 | 57 | ### Compile and Hot-Reload for Development 58 | 59 | ```sh 60 | npm run dev 61 | ``` 62 | 63 | The application will be available at `http://localhost:5173/` 64 | 65 | ### Type-Check, Compile and Minify for Production 66 | 67 | ```sh 68 | npm run build 69 | ``` 70 | 71 | ### Run Unit Tests with [Vitest](https://vitest.dev/) 72 | 73 | ```sh 74 | npm run test:unit 75 | ``` 76 | 77 | ### Lint with [ESLint](https://eslint.org/) 78 | 79 | ```sh 80 | npm run lint 81 | ``` 82 | ### Further help 83 | 84 | You can learn more about Vue in the [Vue documentation](https://vuejs.org/guide/introduction.html). 85 | You can learn more about Vite in the [Vite documentation](https://vite.dev/). 86 | You can learn more about DevExtreme Vue components in the [DevExtreme Vue documentation](https://js.devexpress.com/Vue/). 87 | 88 | To get more help on DevExtreme submit an issue on [GitHub](https://github.com/DevExpress/devextreme/issues) or [Support Center](https://supportcenter.devexpress.com/ticket/create) -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | concurrency: 4 | group: wf-${{github.event.pull_request.number || github.sha}}-${{github.workflow}} 5 | cancel-in-progress: true 6 | 7 | on: 8 | pull_request: 9 | push: 10 | branches: 11 | - "[0-9][0-9].[0-9].[0-9]*" 12 | 13 | jobs: 14 | Angular: 15 | runs-on: ubuntu-latest 16 | timeout-minutes: 60 17 | steps: 18 | - name: Get sources 19 | uses: actions/checkout@v3 20 | 21 | - name: Use Node.js 22 | uses: actions/setup-node@v3 23 | 24 | - name: Restore npm cache 25 | uses: actions/cache@v3 26 | with: 27 | path: ./Angular/node_modules 28 | key: ${{ runner.os }}-node-modules-${{ hashFiles('**/package-lock.json') }} 29 | restore-keys: ${{ runner.os }}-node-modules 30 | 31 | - name: Run npm install 32 | working-directory: Angular 33 | run: npm install --no-audit --no-fund 34 | 35 | - name: Lint Angular 36 | working-directory: Angular 37 | env: 38 | DEBUG: eslint:cli-engine 39 | run: npm run lint 40 | 41 | jQuery: 42 | runs-on: ubuntu-latest 43 | timeout-minutes: 60 44 | steps: 45 | - name: Get sources 46 | uses: actions/checkout@v3 47 | 48 | - name: Use Node.js 49 | uses: actions/setup-node@v3 50 | 51 | - name: Restore npm cache 52 | uses: actions/cache@v3 53 | with: 54 | path: ./jQuery/node_modules 55 | key: ${{ runner.os }}-node-modules-${{ hashFiles('**/package-lock.json') }} 56 | restore-keys: ${{ runner.os }}-node-modules 57 | 58 | - name: Run npm install 59 | working-directory: jQuery 60 | run: npm install --no-audit --no-fund 61 | 62 | - name: Lint jQuery 63 | working-directory: jQuery 64 | env: 65 | DEBUG: eslint:cli-engine 66 | run: npm run lint 67 | 68 | React: 69 | runs-on: ubuntu-latest 70 | timeout-minutes: 60 71 | steps: 72 | - name: Get sources 73 | uses: actions/checkout@v3 74 | 75 | - name: Use Node.js 76 | uses: actions/setup-node@v4 77 | with: 78 | node-version: '20' 79 | 80 | - name: Restore npm cache 81 | uses: actions/cache@v3 82 | with: 83 | path: ./React/node_modules 84 | key: ${{ runner.os }}-node-modules-${{ hashFiles('**/package-lock.json') }} 85 | restore-keys: ${{ runner.os }}-node-modules 86 | 87 | - name: Run npm install 88 | working-directory: React 89 | run: npm install --no-audit --no-fund 90 | 91 | - name: Lint React 92 | working-directory: React 93 | env: 94 | DEBUG: eslint:cli-engine 95 | run: npm run lint 96 | 97 | Vue: 98 | runs-on: ubuntu-latest 99 | timeout-minutes: 60 100 | steps: 101 | - name: Get sources 102 | uses: actions/checkout@v3 103 | 104 | - name: Use Node.js 105 | uses: actions/setup-node@v3 106 | 107 | - name: Restore npm cache 108 | uses: actions/cache@v3 109 | with: 110 | path: ./Vue/node_modules 111 | key: ${{ runner.os }}-node-modules-${{ hashFiles('**/package-lock.json') }} 112 | restore-keys: ${{ runner.os }}-node-modules 113 | 114 | - name: Run npm install 115 | working-directory: Vue 116 | run: npm install --no-audit --no-fund 117 | 118 | - name: Lint Vue 119 | working-directory: Vue 120 | env: 121 | DEBUG: eslint:cli-engine 122 | run: npm run lint 123 | -------------------------------------------------------------------------------- /Angular/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "Angular": { 7 | "projectType": "application", 8 | "schematics": { 9 | "@schematics/angular:component": { 10 | "style": "scss" 11 | } 12 | }, 13 | "root": "", 14 | "sourceRoot": "src", 15 | "prefix": "app", 16 | "architect": { 17 | "build": { 18 | "builder": "@angular-devkit/build-angular:browser", 19 | "options": { 20 | "outputPath": "dist/Angular", 21 | "index": "src/index.html", 22 | "main": "src/main.ts", 23 | "polyfills": [ 24 | "zone.js" 25 | ], 26 | "tsConfig": "tsconfig.app.json", 27 | "inlineStyleLanguage": "scss", 28 | "assets": [ 29 | "src/favicon.ico", 30 | "src/assets" 31 | ], 32 | "styles": [ 33 | "node_modules/devextreme/dist/css/dx.material.blue.light.compact.css", 34 | "src/styles.scss" 35 | ], 36 | "scripts": [] 37 | }, 38 | "configurations": { 39 | "production": { 40 | "budgets": [ 41 | { 42 | "type": "initial", 43 | "maximumWarning": "4mb", 44 | "maximumError": "4mb" 45 | }, 46 | { 47 | "type": "anyComponentStyle", 48 | "maximumWarning": "2kb", 49 | "maximumError": "4kb" 50 | } 51 | ], 52 | "outputHashing": "all" 53 | }, 54 | "development": { 55 | "buildOptimizer": false, 56 | "optimization": false, 57 | "vendorChunk": true, 58 | "extractLicenses": false, 59 | "sourceMap": true, 60 | "namedChunks": true 61 | } 62 | }, 63 | "defaultConfiguration": "production" 64 | }, 65 | "serve": { 66 | "builder": "@angular-devkit/build-angular:dev-server", 67 | "configurations": { 68 | "production": { 69 | "buildTarget": "Angular:build:production" 70 | }, 71 | "development": { 72 | "buildTarget": "Angular:build:development" 73 | } 74 | }, 75 | "defaultConfiguration": "development" 76 | }, 77 | "extract-i18n": { 78 | "builder": "@angular-devkit/build-angular:extract-i18n", 79 | "options": { 80 | "buildTarget": "Angular:build" 81 | } 82 | }, 83 | "test": { 84 | "builder": "@angular-devkit/build-angular:karma", 85 | "options": { 86 | "polyfills": [ 87 | "zone.js", 88 | "zone.js/testing" 89 | ], 90 | "tsConfig": "tsconfig.spec.json", 91 | "inlineStyleLanguage": "scss", 92 | "assets": [ 93 | "src/favicon.ico", 94 | "src/assets" 95 | ], 96 | "styles": [ 97 | "src/styles.scss" 98 | ], 99 | "scripts": [] 100 | } 101 | } 102 | } 103 | } 104 | }, 105 | "cli": { 106 | "analytics": "4497732b-a111-4449-ba60-83332c3ecf94" 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ![](https://img.shields.io/endpoint?url=https://codecentral.devexpress.com/api/v1/VersionRange/263296064/25.1.3%2B) 3 | [![](https://img.shields.io/badge/Open_in_DevExpress_Support_Center-FF7200?style=flat-square&logo=DevExpress&logoColor=white)](https://supportcenter.devexpress.com/ticket/details/T888862) 4 | [![](https://img.shields.io/badge/📖_How_to_use_DevExpress_Examples-e9f6fc?style=flat-square)](https://docs.devexpress.com/GeneralInformation/403183) 5 | [![](https://img.shields.io/badge/💬_Leave_Feedback-feecdd?style=flat-square)](#does-this-example-address-your-development-requirementsobjectives) 6 | 7 | 8 | # DevExtreme DataGrid – Create a custom Pop-up Edit Form using Popup and Form components 9 | 10 | Our DataGrid component ships with a built-in Pop-up Edit Form (for data editing purposes). To create a custom pop-up form, simply use our [Popup](https://js.devexpress.com/Documentation/ApiReference/UI_Components/dxPopup/) and [Form](https://js.devexpress.com/Documentation/ApiReference/UI_Components/dxForm/) UI components as follows: 11 | 12 | Implement a DataGrid callback function that displays the Popup when a user clicks the built-in "Add row" button. Add a Form to the Popup [contentTemplate](https://js.devexpress.com/Documentation/ApiReference/UI_Components/dxPopup/Configuration/#contentTemplate) and specify desired Popup [toolbar buttons](https://js.devexpress.com/Documentation/ApiReference/UI_Components/dxPopup/Configuration/toolbarItems/). Next, call a function that updates the DataGrid data source once users enter/modify Form values and submit changes (by pressing the "Confirm" button). 13 | 14 |
DataGrid for DevExtreme - How to implement a custom editing form using the Popup and Form components
15 | 16 | ## Files to Review 17 | 18 | - **jQuery** 19 | - [index.html](jQuery/src/index.html) 20 | - [index.js](jQuery/src/index.js) 21 | - **Angular** 22 | - [app.component.html](Angular/src/app/app.component.html) 23 | - [app.component.ts](Angular/src/app/app.component.ts) 24 | - **Vue** 25 | - [App.vue](Vue/src/App.vue) 26 | - **React** 27 | - [App.tsx](React/src/App.tsx) 28 | - **ASP.NET Core** 29 | - [Index.cshtml](ASP.NET%20Core/Views/Home/Index.cshtml) 30 | 31 | ## Documentation 32 | 33 | - [Getting Started with DataGrid](https://js.devexpress.com/Documentation/Guide/UI_Components/DataGrid/Getting_Started_with_DataGrid/) 34 | - [DataGrid Popup Mode](https://js.devexpress.com/jQuery/Documentation/Guide/UI_Components/DataGrid/Editing/#User_Interaction/Popup_Mode) 35 | - [DataGrid - API Reference](https://js.devexpress.com/Documentation/ApiReference/UI_Components/dxDataGrid/) 36 | - [Popup - API Reference](https://js.devexpress.com/Documentation/ApiReference/UI_Components/dxPopup/) 37 | - [Form - API Reference](https://js.devexpress.com/Documentation/ApiReference/UI_Components/dxForm/) 38 | 39 | ## Does this example address your development requirements/objectives? 40 | 41 | [](https://www.devexpress.com/support/examples/survey.xml?utm_source=github&utm_campaign=devextreme-datagrid-custom-editing-form&~~~was_helpful=yes) [](https://www.devexpress.com/support/examples/survey.xml?utm_source=github&utm_campaign=devextreme-datagrid-custom-editing-form&~~~was_helpful=no) 42 | 43 | (you will be redirected to DevExpress.com to submit your response) 44 | 45 | -------------------------------------------------------------------------------- /ASP.NET Core/gulpfile.js: -------------------------------------------------------------------------------- 1 | /// 2 | const gulp = require("gulp"), 3 | rimraf = require("rimraf"), 4 | concat = require("gulp-concat"); 5 | 6 | 7 | const paths = { 8 | webroot: "./wwwroot/" 9 | }; 10 | 11 | paths.concatJsDest = paths.webroot + "js/vendor.js"; 12 | paths.concatCssDest = paths.webroot + "css/vendor.css"; 13 | paths.fonts = paths.webroot + "css/fonts"; 14 | paths.icons = paths.webroot + "css/icons"; 15 | 16 | let defaultScripts = [ 17 | "node_modules/jquery/dist/jquery.min.js", 18 | "node_modules/bootstrap/dist/js/bootstrap.min.js"], 19 | exportScripts = [ 20 | "node_modules/jszip/dist/jszip.min.js", 21 | "node_modules/exceljs/dist/exceljs.min.js", 22 | "node_modules/file-saver/FileSaver.min.js" 23 | ], 24 | quillScripts = ["node_modules/devextreme-quill/dist/dx-quill.min.js", 25 | "node_modules/turndown/dist/turndown.js", 26 | "node_modules/showdown/dist/showdown.js" 27 | ], 28 | diagramScript = ["node_modules/devexpress-diagram/dist/dx-diagram.min.js"], 29 | ganttScript = ["node_modules/devexpress-gantt/dist/dx-gantt.min.js"], 30 | dxtScripts = [ 31 | "node_modules/devextreme-dist/js/dx.all.js", 32 | "node_modules/devextreme-dist/js/dx.aspnet.mvc.js", 33 | "node_modules/devextreme-aspnet-data/js/dx.aspnet.data.js"]; 34 | 35 | 36 | let dxtStyles = [ 37 | "node_modules/bootstrap/dist/css/bootstrap.css", 38 | "node_modules/devextreme-dist/css/dx.common.css", 39 | "node_modules/devextreme-dist/css/dx.material.blue.light.compact.css"], 40 | ganttStyles = ["node_modules/devexpress-gantt/dist/dx-gantt.min.css"], 41 | diagramStyles = ["node_modules/devexpress-diagram/dist/dx-diagram.min.css"]; 42 | 43 | 44 | /* default configuration */ 45 | 46 | let styles = dxtStyles; 47 | let scripts = [...defaultScripts, ...dxtScripts]; 48 | 49 | /* // Gantt 50 | scripts = [...defaultScripts, ...ganttScript, ...dxtScripts]; 51 | styles = [...styles, ...ganttStyles]; 52 | */ 53 | 54 | /* // Diagram 55 | scripts = [...defaultScripts, ...diagramScript, ...dxtScripts]; 56 | styles = [...styles, ...diagramStyles]; 57 | */ 58 | 59 | /* // HtmlEditor 60 | scripts = [...defaultScripts, ...quillScripts, dxtScripts]; 61 | */ 62 | 63 | /* // Export 64 | scripts = [...exportScripts, ...scripts]; 65 | */ 66 | 67 | /* // Full bundle 68 | 69 | scripts = [...exportScripts, ...defaultScripts, ...ganttScript, ...diagramScript, ...quillScripts, ...dxtScripts]; 70 | styles = [...dxtStyles, ...diagramStyles, ...ganttStyles]; 71 | 72 | */ 73 | 74 | 75 | gulp.task("clean:js", function (cb) { 76 | rimraf(paths.concatJsDest, cb); 77 | }); 78 | 79 | gulp.task("clean:css", function (cb) { 80 | rimraf(paths.concatCssDest, cb); 81 | }); 82 | gulp.task("clean:icons", function (cb) { 83 | rimraf(paths.icons, cb); 84 | }); 85 | gulp.task("clean:fonts", function (cb) { 86 | rimraf(paths.fonts, cb); 87 | }); 88 | 89 | gulp.task("clean", gulp.series(["clean:js", "clean:css", "clean:icons", "clean:fonts"])); 90 | 91 | 92 | gulp.task("add:js", function () { 93 | 94 | return gulp.src(scripts, { base: "." }) 95 | .pipe(concat(paths.concatJsDest)) 96 | .pipe(gulp.dest(".")); 97 | }); 98 | 99 | gulp.task("add:css", function () { 100 | return gulp.src(styles) 101 | .pipe(concat(paths.concatCssDest)) 102 | .pipe(gulp.dest(".")); 103 | }); 104 | 105 | gulp.task("add:icons", function () { 106 | return gulp.src(["node_modules/devextreme-dist/css/icons/*"]).pipe(gulp.dest(paths.icons)); 107 | }) 108 | gulp.task("add:fonts", function () { 109 | return gulp.src(["node_modules/devextreme-dist/css/fonts/*"]).pipe(gulp.dest(paths.fonts)); 110 | }) 111 | 112 | gulp.task("add-resources", gulp.series(["add:js", "add:css", "add:icons", "add:fonts"])); -------------------------------------------------------------------------------- /React/src/assets/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /React/README.md: -------------------------------------------------------------------------------- 1 | # React + TypeScript + Vite + DevExtreme 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR, ESLint rules, and DevExtreme components. 4 | 5 | This project includes: 6 | - React 18.2.0 7 | - TypeScript 5.8.2 8 | - Vite for fast development and building 9 | - DevExtreme React 25.1.3 10 | - Vitest for testing 11 | - ESLint and Stylelint for code quality 12 | 13 | Currently, two official plugins are available: 14 | 15 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh 16 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 17 | 18 | ## Getting Started 19 | 20 | ### Installation 21 | 22 | ```bash 23 | npm install 24 | ``` 25 | 26 | ### Development 27 | 28 | Start the development server: 29 | ```bash 30 | npm run dev 31 | ``` 32 | 33 | The application will be available at `http://localhost:5173/` 34 | 35 | ### Building 36 | 37 | Build the project for production: 38 | ```bash 39 | npm run build 40 | ``` 41 | 42 | ### Testing 43 | 44 | Run tests: 45 | ```bash 46 | npm test 47 | npm run test:watch # Run tests in watch mode 48 | ``` 49 | 50 | ### Linting 51 | 52 | Run linting checks: 53 | ```bash 54 | npm run lint # Run all linting checks 55 | npm run lint-ts # ESLint for TypeScript files 56 | npm run lint-css # Stylelint for CSS files 57 | ``` 58 | 59 | ## Code Structure 60 | 61 | **Source Files:** 62 | - `src/App.tsx` - Main React component with DevExtreme Button example 63 | - `src/App.test.tsx` - Tests for the main component 64 | - `src/main.tsx` - Application entry point 65 | - `src/App.css` - Component styles 66 | - `src/index.css` - Global styles 67 | - `src/setupTests.ts` - Test setup configuration 68 | - `src/vite-env.d.ts` - Vite environment type definitions 69 | 70 | **Configuration Files:** 71 | - `vite.config.ts` - Vite configuration 72 | - `package.json` - Dependencies and scripts 73 | - `tsconfig.json` - TypeScript configuration 74 | - `vitest.config.ts` - Vitest testing configuration 75 | 76 | ## Expanding the ESLint configuration 77 | 78 | If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: 79 | 80 | ```js 81 | export default tseslint.config({ 82 | extends: [ 83 | // Remove ...tseslint.configs.recommended and replace with this 84 | ...tseslint.configs.recommendedTypeChecked, 85 | // Alternatively, use this for stricter rules 86 | ...tseslint.configs.strictTypeChecked, 87 | // Optionally, add this for stylistic rules 88 | ...tseslint.configs.stylisticTypeChecked, 89 | ], 90 | languageOptions: { 91 | // other options... 92 | parserOptions: { 93 | project: ['./tsconfig.node.json', './tsconfig.app.json'], 94 | tsconfigRootDir: import.meta.dirname, 95 | }, 96 | }, 97 | }) 98 | ``` 99 | 100 | You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: 101 | 102 | ```js 103 | // eslint.config.js 104 | import reactX from 'eslint-plugin-react-x' 105 | import reactDom from 'eslint-plugin-react-dom' 106 | 107 | export default tseslint.config({ 108 | plugins: { 109 | // Add the react-x and react-dom plugins 110 | 'react-x': reactX, 111 | 'react-dom': reactDom, 112 | }, 113 | rules: { 114 | // other rules... 115 | // Enable its recommended typescript rules 116 | ...reactX.configs['recommended-typescript'].rules, 117 | ...reactDom.configs.recommended.rules, 118 | }, 119 | }) 120 | ``` 121 | 122 | ## Further help 123 | 124 | You can learn more about React in the [React documentation](https://react.dev/learn). 125 | You can learn more about Vite in the [Vite documentation](https://vite.dev/). 126 | You can learn more about DevExtreme React components in the [DevExtreme React documentation](https://js.devexpress.com/React/). 127 | 128 | To get more help on DevExtreme submit an issue in the [Support Center](https://supportcenter.devexpress.com/ticket/create) -------------------------------------------------------------------------------- /ASP.NET Core/Readme.md: -------------------------------------------------------------------------------- 1 | # ASP.NET Core DevExtreme Example 2 | 3 | ## Installation 4 | 5 | Download the example and use Visual Studio 2022 (or later) or Visual Studio Code to open the project. This project targets .NET 8.0. 6 | 7 | ## Client-side resources and bundling 8 | 9 | This project uses [NPM](https://www.npmjs.com/) and [Gulp.js](https://gulpjs.com/) to install client-side libraries. The project restores NPM packages before the first build. Then, Gulp bundles required scripts and CSS files into the resulting package during the first and every next build. 10 | 11 | The project includes: 12 | - DevExtreme 24.2.3 13 | - DevExtreme.AspNet.Core 24.2.* 14 | - DevExtreme.AspNet.Data 5.* 15 | - jQuery 3.7.1 16 | - Bootstrap 5.3.3 17 | 18 | The resulted bundles will be located in the `wwwroot` folder: 19 | * `css/vendor.css` - a file with all CSS styles. 20 | * `css/icons` and `css/fonts` - folders that contain fonts and icons for DevExtreme themes. 21 | * `js/vendor.js` - a file that contains all scripts. 22 | 23 | The default bundle includes jQuery, Bootstrap, and DevExtreme. 24 | 25 | ### Add more 3rd-party libraries for additional features/components 26 | 27 | The main logic is located in the the `gulpfile.js` file at the root application level. The file contains two tasks: 28 | 29 | * the `add-resources` task 30 | 31 | * copies JavaScript files located in the `scripts` array and adds them to `vendor.js`. The script bundle is moved to `wwwroot\js`. 32 | * copies CSS styles located in the `styles` array and merges them into the `vendor.css` bundle. Then, this bundle is moved to `wwwroot\css` 33 | * copies DevExtreme `fonts` and `icons` folders from NPM to `wwwroot\css` 34 | 35 | * the `clean` task removes all previously created files (`vendor.js` and `vendor.css`) and folders (`icons` and `fonts`) 36 | 37 | If you need to include more features, you can uncomment one of the following sections: 38 | 39 | * Gantt - scripts and styles for [dxGantt](https://js.devexpress.com/DevExtreme/Guide/UI_Components/Gantt/Getting_Started_with_Gantt/). 40 | * Diagram - scripts and styles for [dxDiagram](https://js.devexpress.com/DevExtreme/Guide/UI_Components/Diagram/Getting_Started_with_Diagram/). 41 | * Export - scripts and styles for the exporting feature: [Export Data to Excel](https://js.devexpress.com/DevExtreme/Guide/UI_Components/DataGrid/Getting_Started_with_DataGrid/#Export_Data). 42 | * HtmlEditor - scripts and styles for [dxHtmlEditor](https://js.devexpress.com/DevExtreme/Guide/UI_Components/HtmlEditor/Overview/). 43 | * Full Bundle - scripts and styles for all above mentioned features/components. 44 | 45 | ## Code 46 | 47 | Take a look at the following files of this example to see the required code: 48 | 49 | **Controllers:** 50 | - `Controllers/HomeController.cs` - Main controller with Index action 51 | - `Controllers/SampleDataController.cs` - API controller for sample data 52 | 53 | **Models:** 54 | - `Models/SampleData.cs` - Sample data model 55 | - `Models/SampleOrder.cs` - Sample order model 56 | 57 | **Views:** 58 | - `Views/Home/Index.cshtml` - Main page with DevExtreme components 59 | - `Views/Shared/_Layout.cshtml` - Layout template 60 | - `Views/_ViewImports.cshtml` - Global imports 61 | - `Views/_ViewStart.cshtml` - View start configuration 62 | 63 | **Configuration:** 64 | - `Program.cs` - Application entry point 65 | - `Startup.cs` - Service configuration 66 | - `gulpfile.js` - Build automation 67 | - `package.json` - NPM dependencies 68 | - `ASP.NET Core.csproj` - Project file 69 | 70 | ## Development server 71 | 72 | Use the Visual Studio `Run (F5)` command or `dotnet run` command to run the project. The application will be available at `https://localhost:5001` (HTTPS) or `http://localhost:5000` (HTTP). 73 | 74 | ## Further help 75 | 76 | You can learn more about the ASP.NET Core components' syntax in our documentation: [Concepts](https://docs.devexpress.com/AspNetCore/400574/devextreme-based-controls/concepts/razor-syntax) 77 | The client-side API is based on jQuery [jQuery documentation](https://api.jquery.com/) and described in the following topics: 78 | * [Get and Set Properties](https://js.devexpress.com/DevExtreme/Guide/jQuery_Components/Component_Configuration_Syntax/#Get_and_Set_Properties) 79 | * [Call Methods](https://js.devexpress.com/DevExtreme/Guide/jQuery_Components/Component_Configuration_Syntax/#Call_Methods) 80 | * [Get a UI Component Instance](https://js.devexpress.com/DevExtreme/Guide/jQuery_Components/Component_Configuration_Syntax/#Get_a_UI_Component_Instance) 81 | 82 | To get more help on DevExtreme submit an issue in the [Support Center](https://supportcenter.devexpress.com/ticket/create) 83 | 84 | 85 | -------------------------------------------------------------------------------- /jQuery/src/data.js: -------------------------------------------------------------------------------- 1 | const employees = [{ 2 | ID: 1, 3 | FirstName: 'John', 4 | LastName: 'Heart', 5 | Prefix: 'Mr.', 6 | Position: 'CEO', 7 | BirthDate: '1964/03/16', 8 | HireDate: '1995/01/15', 9 | Notes: 'John has been in the Audio/Video industry since 1990. He has led DevAv as its CEO since 2003.\r\n\r\nWhen not working hard as the CEO, John loves to golf and bowl. He once bowled a perfect game of 300.', 10 | Address: '351 S Hill St.', 11 | Phone: '16102458448', 12 | Email: 'rohitm@hotmail.com', 13 | }, { 14 | ID: 2, 15 | FirstName: 'Olivia', 16 | LastName: 'Peyton', 17 | Prefix: 'Mrs.', 18 | Position: 'Sales Assistant', 19 | BirthDate: '1981/06/03', 20 | HireDate: '2012/05/14', 21 | Notes: 'Olivia loves to sell. She has been selling DevAV products since 2012. \r\n\r\nOlivia was homecoming queen in high school. She is expecting her first child in 6 months. Good Luck Olivia.', 22 | Address: '807 W Paseo Del Mar', 23 | Phone: '16102347905', 24 | Email: 'spadkins@optonline.net', 25 | }, { 26 | ID: 3, 27 | FirstName: 'Robert', 28 | LastName: 'Reagan', 29 | Prefix: 'Mr.', 30 | Position: 'CMO', 31 | BirthDate: '1974/09/07', 32 | HireDate: '2002/11/08', 33 | Notes: 'Robert was recently voted the CMO of the year by CMO Magazine. He is a proud member of the DevAV Management Team.\r\n\r\nRobert is a championship BBQ chef, so when you get the chance ask him for his secret recipe.', 34 | Address: '4 Westmoreland Pl.', 35 | Phone: '14845219762', 36 | Email: 'naoya@comcast.net', 37 | }, { 38 | ID: 4, 39 | FirstName: 'Greta', 40 | LastName: 'Sims', 41 | Prefix: 'Ms.', 42 | Position: 'HR Manager', 43 | BirthDate: '1977/11/22', 44 | HireDate: '1998/04/23', 45 | Notes: "Greta has been DevAV's HR Manager since 2003. She joined DevAV from Sonee Corp.\r\n\r\nGreta is currently training for the NYC marathon. Her best marathon time is 4 hours. Go Greta.", 46 | Address: '1700 S Grandview Dr.', 47 | Phone: '14844578858', 48 | Email: 'tattooman@optonline.net', 49 | }, { 50 | ID: 5, 51 | FirstName: 'Brett', 52 | LastName: 'Wade', 53 | Prefix: 'Mr.', 54 | Position: 'IT Manager', 55 | BirthDate: '1968/12/01', 56 | HireDate: '2009/03/06', 57 | Notes: 'Brett came to DevAv from Microsoft and has led our IT department since 2012.\r\n\r\nWhen he is not working hard for DevAV, he coaches Little League (he was a high school pitcher).', 58 | Address: '1120 Old Mill Rd.', 59 | Phone: '18143008837', 60 | Email: 'haddawy@mac.com', 61 | }, { 62 | ID: 6, 63 | FirstName: 'Sandra', 64 | LastName: 'Johnson', 65 | Prefix: 'Mrs.', 66 | Position: 'Controller', 67 | BirthDate: '1974/11/15', 68 | HireDate: '2005/05/11', 69 | Notes: "Sandra is a CPA and has been our controller since 2008. She loves to interact with staff so if you've not met her, be certain to say hi.\r\n\r\nSandra has 2 daughters both of whom are accomplished gymnasts.", 70 | Address: '4600 N Virginia Rd.', 71 | Phone: '15852826538', 72 | Email: 'gordonjcp@gmail.com', 73 | }, { 74 | ID: 7, 75 | FirstName: 'Kevin', 76 | LastName: 'Carter', 77 | Prefix: 'Mr.', 78 | Position: 'Shipping Manager', 79 | BirthDate: '1978/01/09', 80 | HireDate: '2009/08/11', 81 | Notes: 'Kevin is our hard-working shipping manager and has been helping that department work like clockwork for 18 months.\r\n\r\nWhen not in the office, he is usually on the basketball court playing pick-up games.', 82 | Address: '424 N Main St.', 83 | Phone: '14844760152', 84 | Email: 'chance@verizon.net', 85 | }, { 86 | ID: 8, 87 | FirstName: 'Cynthia', 88 | LastName: 'Stanwick', 89 | Prefix: 'Ms.', 90 | Position: 'HR Manager', 91 | BirthDate: '1985/06/05', 92 | HireDate: '2008/03/24', 93 | Notes: 'Cindy joined us in 2008 and has been in the HR department for 2 years. \r\n\r\nShe was recently awarded employee of the month. Way to go Cindy!', 94 | Address: '2211 Bonita Dr.', 95 | Phone: '14842989304', 96 | Email: 'kevinm@verizon.net', 97 | }, { 98 | ID: 9, 99 | FirstName: 'Kent', 100 | LastName: 'Samuelson', 101 | Prefix: 'Dr.', 102 | Position: 'Support Manager', 103 | BirthDate: '1972/09/11', 104 | HireDate: '2009/04/22', 105 | Notes: 'As our ombudsman, Kent is on the front-lines solving customer problems and helping our partners address issues out in the field. He is a classically trained musician and is a member of the Chamber Orchestra.', 106 | Address: '12100 Mora Dr', 107 | Phone: '14844731660', 108 | Email: 'arebenti@outlook.com', 109 | }, { 110 | ID: 10, 111 | FirstName: 'Taylor', 112 | LastName: 'Riley', 113 | Prefix: 'Mr.', 114 | Position: 'Sales Manager', 115 | BirthDate: '1982/08/14', 116 | HireDate: '2012/04/14', 117 | Notes: "If you are like the rest of us at DevAV, then you've probably reached out for help from Taylor. He does a great job as a member of our IT department.", 118 | Address: '7776 Torreyson Dr', 119 | Phone: '14842989306', 120 | Email: 'amichalo@live.com', 121 | }]; 122 | 123 | const positions = [ 124 | 'HR Manager', 125 | 'IT Manager', 126 | 'CEO', 127 | 'Controller', 128 | 'Sales Manager', 129 | 'Support Manager', 130 | 'Shipping Manager', 131 | 'Sales Assistant', 132 | 'CMO', 133 | ]; 134 | -------------------------------------------------------------------------------- /React/src/data.ts: -------------------------------------------------------------------------------- 1 | export const employees = [{ 2 | ID: 1, 3 | FirstName: 'John', 4 | LastName: 'Heart', 5 | Prefix: 'Mr.', 6 | Position: 'CEO', 7 | BirthDate: '1964/03/16', 8 | HireDate: '1995/01/15', 9 | Notes: 'John has been in the Audio/Video industry since 1990. He has led DevAv as its CEO since 2003.\r\n\r\nWhen not working hard as the CEO, John loves to golf and bowl. He once bowled a perfect game of 300.', 10 | Address: '351 S Hill St.', 11 | Phone: '16102458448', 12 | Email: 'rohitm@hotmail.com', 13 | }, { 14 | ID: 2, 15 | FirstName: 'Olivia', 16 | LastName: 'Peyton', 17 | Prefix: 'Mrs.', 18 | Position: 'Sales Assistant', 19 | BirthDate: '1981/06/03', 20 | HireDate: '2012/05/14', 21 | Notes: 'Olivia loves to sell. She has been selling DevAV products since 2012. \r\n\r\nOlivia was homecoming queen in high school. She is expecting her first child in 6 months. Good Luck Olivia.', 22 | Address: '807 W Paseo Del Mar', 23 | Phone: '16102347905', 24 | Email: 'spadkins@optonline.net', 25 | }, { 26 | ID: 3, 27 | FirstName: 'Robert', 28 | LastName: 'Reagan', 29 | Prefix: 'Mr.', 30 | Position: 'CMO', 31 | BirthDate: '1974/09/07', 32 | HireDate: '2002/11/08', 33 | Notes: 'Robert was recently voted the CMO of the year by CMO Magazine. He is a proud member of the DevAV Management Team.\r\n\r\nRobert is a championship BBQ chef, so when you get the chance ask him for his secret recipe.', 34 | Address: '4 Westmoreland Pl.', 35 | Phone: '14845219762', 36 | Email: 'naoya@comcast.net', 37 | }, { 38 | ID: 4, 39 | FirstName: 'Greta', 40 | LastName: 'Sims', 41 | Prefix: 'Ms.', 42 | Position: 'HR Manager', 43 | BirthDate: '1977/11/22', 44 | HireDate: '1998/04/23', 45 | Notes: 'Greta has been DevAV\'s HR Manager since 2003. She joined DevAV from Sonee Corp.\r\n\r\nGreta is currently training for the NYC marathon. Her best marathon time is 4 hours. Go Greta.', 46 | Address: '1700 S Grandview Dr.', 47 | Phone: '14844578858', 48 | Email: 'tattooman@optonline.net', 49 | }, { 50 | ID: 5, 51 | FirstName: 'Brett', 52 | LastName: 'Wade', 53 | Prefix: 'Mr.', 54 | Position: 'IT Manager', 55 | BirthDate: '1968/12/01', 56 | HireDate: '2009/03/06', 57 | Notes: 'Brett came to DevAv from Microsoft and has led our IT department since 2012.\r\n\r\nWhen he is not working hard for DevAV, he coaches Little League (he was a high school pitcher).', 58 | Address: '1120 Old Mill Rd.', 59 | Phone: '18143008837', 60 | Email: 'haddawy@mac.com', 61 | }, { 62 | ID: 6, 63 | FirstName: 'Sandra', 64 | LastName: 'Johnson', 65 | Prefix: 'Mrs.', 66 | Position: 'Controller', 67 | BirthDate: '1974/11/15', 68 | HireDate: '2005/05/11', 69 | Notes: 'Sandra is a CPA and has been our controller since 2008. She loves to interact with staff so if you\'ve not met her, be certain to say hi.\r\n\r\nSandra has 2 daughters both of whom are accomplished gymnasts.', 70 | Address: '4600 N Virginia Rd.', 71 | Phone: '15852826538', 72 | Email: 'gordonjcp@gmail.com', 73 | }, { 74 | ID: 7, 75 | FirstName: 'Kevin', 76 | LastName: 'Carter', 77 | Prefix: 'Mr.', 78 | Position: 'Shipping Manager', 79 | BirthDate: '1978/01/09', 80 | HireDate: '2009/08/11', 81 | Notes: 'Kevin is our hard-working shipping manager and has been helping that department work like clockwork for 18 months.\r\n\r\nWhen not in the office, he is usually on the basketball court playing pick-up games.', 82 | Address: '424 N Main St.', 83 | Phone: '14844760152', 84 | Email: 'chance@verizon.net', 85 | }, { 86 | ID: 8, 87 | FirstName: 'Cynthia', 88 | LastName: 'Stanwick', 89 | Prefix: 'Ms.', 90 | Position: 'HR Manager', 91 | BirthDate: '1985/06/05', 92 | HireDate: '2008/03/24', 93 | Notes: 'Cindy joined us in 2008 and has been in the HR department for 2 years. \r\n\r\nShe was recently awarded employee of the month. Way to go Cindy!', 94 | Address: '2211 Bonita Dr.', 95 | Phone: '14842989304', 96 | Email: 'kevinm@verizon.net', 97 | }, { 98 | ID: 9, 99 | FirstName: 'Kent', 100 | LastName: 'Samuelson', 101 | Prefix: 'Dr.', 102 | Position: 'Support Manager', 103 | BirthDate: '1972/09/11', 104 | HireDate: '2009/04/22', 105 | Notes: 'As our ombudsman, Kent is on the front-lines solving customer problems and helping our partners address issues out in the field. He is a classically trained musician and is a member of the Chamber Orchestra.', 106 | Address: '12100 Mora Dr', 107 | Phone: '14844731660', 108 | Email: 'arebenti@outlook.com', 109 | }, { 110 | ID: 10, 111 | FirstName: 'Taylor', 112 | LastName: 'Riley', 113 | Prefix: 'Mr.', 114 | Position: 'Sales Manager', 115 | BirthDate: '1982/08/14', 116 | HireDate: '2012/04/14', 117 | Notes: 'If you are like the rest of us at DevAV, then you\'ve probably reached out for help from Taylor. He does a great job as a member of our IT department.', 118 | Address: '7776 Torreyson Dr', 119 | Phone: '14842989306', 120 | Email: 'amichalo@live.com', 121 | }]; 122 | 123 | export const positions = [ 124 | 'HR Manager', 125 | 'IT Manager', 126 | 'CEO', 127 | 'Controller', 128 | 'Sales Manager', 129 | 'Support Manager', 130 | 'Shipping Manager', 131 | 'Sales Assistant', 132 | 'CMO', 133 | ]; 134 | -------------------------------------------------------------------------------- /Angular/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 7 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 |
31 |
32 |
33 | 34 | 42 | 52 | 53 | 62 | 63 | 64 |
65 | 66 | 67 | 68 | 72 | 73 | 74 | 79 | 80 | 81 | 82 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 97 | 98 | 99 | 100 | 101 | 102 | 108 | 109 | 110 | 111 | 115 | 116 | 117 | 118 | 122 | 123 | 124 | 125 | 126 | 127 |
128 |
{{ data.text }}
129 |
130 |
131 | 132 |
133 |
134 | 135 | Additional 136 |
137 | {{ data.text }} 138 |
139 | 140 | 145 |
146 |
147 | This field must not exceed 200 characters 148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 | -------------------------------------------------------------------------------- /Vue/src/data.ts: -------------------------------------------------------------------------------- 1 | export interface Employee { 2 | ID: number; 3 | FirstName: string; 4 | LastName: string; 5 | Prefix: string; 6 | Position: string; 7 | BirthDate: string; 8 | HireDate: string; 9 | Notes: string; 10 | Address: string; 11 | Phone: string; 12 | Email: string; 13 | } 14 | 15 | export const employees: Employee[] = [{ 16 | ID: 1, 17 | FirstName: 'John', 18 | LastName: 'Heart', 19 | Prefix: 'Mr.', 20 | Position: 'CEO', 21 | BirthDate: '1964/03/16', 22 | HireDate: '1995/01/15', 23 | Notes: 'John has been in the Audio/Video industry since 1990. He has led DevAv as its CEO since 2003.\r\n\r\nWhen not working hard as the CEO, John loves to golf and bowl. He once bowled a perfect game of 300.', 24 | Address: '351 S Hill St.', 25 | Phone: '16102458448', 26 | Email: 'rohitm@hotmail.com', 27 | }, { 28 | ID: 2, 29 | FirstName: 'Olivia', 30 | LastName: 'Peyton', 31 | Prefix: 'Mrs.', 32 | Position: 'Sales Assistant', 33 | BirthDate: '1981/06/03', 34 | HireDate: '2012/05/14', 35 | Notes: 'Olivia loves to sell. She has been selling DevAV products since 2012. \r\n\r\nOlivia was homecoming queen in high school. She is expecting her first child in 6 months. Good Luck Olivia.', 36 | Address: '807 W Paseo Del Mar', 37 | Phone: '16102347905', 38 | Email: 'spadkins@optonline.net', 39 | }, { 40 | ID: 3, 41 | FirstName: 'Robert', 42 | LastName: 'Reagan', 43 | Prefix: 'Mr.', 44 | Position: 'CMO', 45 | BirthDate: '1974/09/07', 46 | HireDate: '2002/11/08', 47 | Notes: 'Robert was recently voted the CMO of the year by CMO Magazine. He is a proud member of the DevAV Management Team.\r\n\r\nRobert is a championship BBQ chef, so when you get the chance ask him for his secret recipe.', 48 | Address: '4 Westmoreland Pl.', 49 | Phone: '14845219762', 50 | Email: 'naoya@comcast.net', 51 | }, { 52 | ID: 4, 53 | FirstName: 'Greta', 54 | LastName: 'Sims', 55 | Prefix: 'Ms.', 56 | Position: 'HR Manager', 57 | BirthDate: '1977/11/22', 58 | HireDate: '1998/04/23', 59 | Notes: "Greta has been DevAV's HR Manager since 2003. She joined DevAV from Sonee Corp.\r\n\r\nGreta is currently training for the NYC marathon. Her best marathon time is 4 hours. Go Greta.", 60 | Address: '1700 S Grandview Dr.', 61 | Phone: '14844578858', 62 | Email: 'tattooman@optonline.net', 63 | }, { 64 | ID: 5, 65 | FirstName: 'Brett', 66 | LastName: 'Wade', 67 | Prefix: 'Mr.', 68 | Position: 'IT Manager', 69 | BirthDate: '1968/12/01', 70 | HireDate: '2009/03/06', 71 | Notes: 'Brett came to DevAv from Microsoft and has led our IT department since 2012.\r\n\r\nWhen he is not working hard for DevAV, he coaches Little League (he was a high school pitcher).', 72 | Address: '1120 Old Mill Rd.', 73 | Phone: '18143008837', 74 | Email: 'haddawy@mac.com', 75 | }, { 76 | ID: 6, 77 | FirstName: 'Sandra', 78 | LastName: 'Johnson', 79 | Prefix: 'Mrs.', 80 | Position: 'Controller', 81 | BirthDate: '1974/11/15', 82 | HireDate: '2005/05/11', 83 | Notes: "Sandra is a CPA and has been our controller since 2008. She loves to interact with staff so if you've not met her, be certain to say hi.\r\n\r\nSandra has 2 daughters both of whom are accomplished gymnasts.", 84 | Address: '4600 N Virginia Rd.', 85 | Phone: '15852826538', 86 | Email: 'gordonjcp@gmail.com', 87 | }, { 88 | ID: 7, 89 | FirstName: 'Kevin', 90 | LastName: 'Carter', 91 | Prefix: 'Mr.', 92 | Position: 'Shipping Manager', 93 | BirthDate: '1978/01/09', 94 | HireDate: '2009/08/11', 95 | Notes: 'Kevin is our hard-working shipping manager and has been helping that department work like clockwork for 18 months.\r\n\r\nWhen not in the office, he is usually on the basketball court playing pick-up games.', 96 | Address: '424 N Main St.', 97 | Phone: '14844760152', 98 | Email: 'chance@verizon.net', 99 | }, { 100 | ID: 8, 101 | FirstName: 'Cynthia', 102 | LastName: 'Stanwick', 103 | Prefix: 'Ms.', 104 | Position: 'HR Manager', 105 | BirthDate: '1985/06/05', 106 | HireDate: '2008/03/24', 107 | Notes: 'Cindy joined us in 2008 and has been in the HR department for 2 years. \r\n\r\nShe was recently awarded employee of the month. Way to go Cindy!', 108 | Address: '2211 Bonita Dr.', 109 | Phone: '14842989304', 110 | Email: 'kevinm@verizon.net', 111 | }, { 112 | ID: 9, 113 | FirstName: 'Kent', 114 | LastName: 'Samuelson', 115 | Prefix: 'Dr.', 116 | Position: 'Support Manager', 117 | BirthDate: '1972/09/11', 118 | HireDate: '2009/04/22', 119 | Notes: 'As our ombudsman, Kent is on the front-lines solving customer problems and helping our partners address issues out in the field. He is a classically trained musician and is a member of the Chamber Orchestra.', 120 | Address: '12100 Mora Dr', 121 | Phone: '14844731660', 122 | Email: 'arebenti@outlook.com', 123 | }, { 124 | ID: 10, 125 | FirstName: 'Taylor', 126 | LastName: 'Riley', 127 | Prefix: 'Mr.', 128 | Position: 'Sales Manager', 129 | BirthDate: '1982/08/14', 130 | HireDate: '2012/04/14', 131 | Notes: "If you are like the rest of us at DevAV, then you've probably reached out for help from Taylor. He does a great job as a member of our IT department.", 132 | Address: '7776 Torreyson Dr', 133 | Phone: '14842989306', 134 | Email: 'amichalo@live.com', 135 | }]; 136 | 137 | export const positions = [ 138 | 'HR Manager', 139 | 'IT Manager', 140 | 'CEO', 141 | 'Controller', 142 | 'Sales Manager', 143 | 'Support Manager', 144 | 'Shipping Manager', 145 | 'Sales Assistant', 146 | 'CMO', 147 | ]; 148 | -------------------------------------------------------------------------------- /Angular/src/app/app.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | export class Employee { 4 | ID!: number; 5 | 6 | FirstName!: string; 7 | 8 | LastName!: string; 9 | 10 | Prefix!: string; 11 | 12 | Position!: string; 13 | 14 | BirthDate!: string; 15 | 16 | HireDate!: string; 17 | 18 | Notes!: string; 19 | 20 | Address!: string; 21 | 22 | Phone!: string; 23 | 24 | Email!: string; 25 | } 26 | 27 | const employees: Employee[] = [{ 28 | ID: 1, 29 | FirstName: 'John', 30 | LastName: 'Heart', 31 | Prefix: 'Mr.', 32 | Position: 'CEO', 33 | BirthDate: '1964/03/16', 34 | HireDate: '1995/01/15', 35 | Notes: 'John has been in the Audio/Video industry since 1990. He has led DevAv as its CEO since 2003.\r\n\r\nWhen not working hard as the CEO, John loves to golf and bowl. He once bowled a perfect game of 300.', 36 | Address: '351 S Hill St.', 37 | Phone: '16102458448', 38 | Email: 'rohitm@hotmail.com', 39 | }, { 40 | ID: 2, 41 | FirstName: 'Olivia', 42 | LastName: 'Peyton', 43 | Prefix: 'Mrs.', 44 | Position: 'Sales Assistant', 45 | BirthDate: '1981/06/03', 46 | HireDate: '2012/05/14', 47 | Notes: 'Olivia loves to sell. She has been selling DevAV products since 2012. \r\n\r\nOlivia was homecoming queen in high school. She is expecting her first child in 6 months. Good Luck Olivia.', 48 | Address: '807 W Paseo Del Mar', 49 | Phone: '16102347905', 50 | Email: 'spadkins@optonline.net', 51 | }, { 52 | ID: 3, 53 | FirstName: 'Robert', 54 | LastName: 'Reagan', 55 | Prefix: 'Mr.', 56 | Position: 'CMO', 57 | BirthDate: '1974/09/07', 58 | HireDate: '2002/11/08', 59 | Notes: 'Robert was recently voted the CMO of the year by CMO Magazine. He is a proud member of the DevAV Management Team.\r\n\r\nRobert is a championship BBQ chef, so when you get the chance ask him for his secret recipe.', 60 | Address: '4 Westmoreland Pl.', 61 | Phone: '14845219762', 62 | Email: 'naoya@comcast.net', 63 | }, { 64 | ID: 4, 65 | FirstName: 'Greta', 66 | LastName: 'Sims', 67 | Prefix: 'Ms.', 68 | Position: 'HR Manager', 69 | BirthDate: '1977/11/22', 70 | HireDate: '1998/04/23', 71 | Notes: 'Greta has been DevAV\'s HR Manager since 2003. She joined DevAV from Sonee Corp.\r\n\r\nGreta is currently training for the NYC marathon. Her best marathon time is 4 hours. Go Greta.', 72 | Address: '1700 S Grandview Dr.', 73 | Phone: '14844578858', 74 | Email: 'tattooman@optonline.net', 75 | }, { 76 | ID: 5, 77 | FirstName: 'Brett', 78 | LastName: 'Wade', 79 | Prefix: 'Mr.', 80 | Position: 'IT Manager', 81 | BirthDate: '1968/12/01', 82 | HireDate: '2009/03/06', 83 | Notes: 'Brett came to DevAv from Microsoft and has led our IT department since 2012.\r\n\r\nWhen he is not working hard for DevAV, he coaches Little League (he was a high school pitcher).', 84 | Address: '1120 Old Mill Rd.', 85 | Phone: '18143008837', 86 | Email: 'haddawy@mac.com', 87 | }, { 88 | ID: 6, 89 | FirstName: 'Sandra', 90 | LastName: 'Johnson', 91 | Prefix: 'Mrs.', 92 | Position: 'Controller', 93 | BirthDate: '1974/11/15', 94 | HireDate: '2005/05/11', 95 | Notes: 'Sandra is a CPA and has been our controller since 2008. She loves to interact with staff so if you\'ve not met her, be certain to say hi.\r\n\r\nSandra has 2 daughters both of whom are accomplished gymnasts.', 96 | Address: '4600 N Virginia Rd.', 97 | Phone: '15852826538', 98 | Email: 'gordonjcp@gmail.com', 99 | }, { 100 | ID: 7, 101 | FirstName: 'Kevin', 102 | LastName: 'Carter', 103 | Prefix: 'Mr.', 104 | Position: 'Shipping Manager', 105 | BirthDate: '1978/01/09', 106 | HireDate: '2009/08/11', 107 | Notes: 'Kevin is our hard-working shipping manager and has been helping that department work like clockwork for 18 months.\r\n\r\nWhen not in the office, he is usually on the basketball court playing pick-up games.', 108 | Address: '424 N Main St.', 109 | Phone: '14844760152', 110 | Email: 'chance@verizon.net', 111 | }, { 112 | ID: 8, 113 | FirstName: 'Cynthia', 114 | LastName: 'Stanwick', 115 | Prefix: 'Ms.', 116 | Position: 'HR Manager', 117 | BirthDate: '1985/06/05', 118 | HireDate: '2008/03/24', 119 | Notes: 'Cindy joined us in 2008 and has been in the HR department for 2 years. \r\n\r\nShe was recently awarded employee of the month. Way to go Cindy!', 120 | Address: '2211 Bonita Dr.', 121 | Phone: '14842989304', 122 | Email: 'kevinm@verizon.net', 123 | }, { 124 | ID: 9, 125 | FirstName: 'Kent', 126 | LastName: 'Samuelson', 127 | Prefix: 'Dr.', 128 | Position: 'Support Manager', 129 | BirthDate: '1972/09/11', 130 | HireDate: '2009/04/22', 131 | Notes: 'As our ombudsman, Kent is on the front-lines solving customer problems and helping our partners address issues out in the field. He is a classically trained musician and is a member of the Chamber Orchestra.', 132 | Address: '12100 Mora Dr', 133 | Phone: '14844731660', 134 | Email: 'arebenti@outlook.com', 135 | }, { 136 | ID: 10, 137 | FirstName: 'Taylor', 138 | LastName: 'Riley', 139 | Prefix: 'Mr.', 140 | Position: 'Sales Manager', 141 | BirthDate: '1982/08/14', 142 | HireDate: '2012/04/14', 143 | Notes: 'If you are like the rest of us at DevAV, then you\'ve probably reached out for help from Taylor. He does a great job as a member of our IT department.', 144 | Address: '7776 Torreyson Dr', 145 | Phone: '14842989306', 146 | Email: 'amichalo@live.com', 147 | }]; 148 | 149 | const positions: string[] = [ 150 | 'HR Manager', 151 | 'IT Manager', 152 | 'CEO', 153 | 'Controller', 154 | 'Sales Manager', 155 | 'Support Manager', 156 | 'Shipping Manager', 157 | 'Sales Assistant', 158 | 'CMO', 159 | ]; 160 | 161 | @Injectable() 162 | export class Service { 163 | getEmployees(): Employee[] { 164 | return employees; 165 | } 166 | 167 | getPositions(): string[] { 168 | return positions; 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # Benchmark Results 46 | BenchmarkDotNet.Artifacts/ 47 | 48 | # .NET Core 49 | project.lock.json 50 | project.fragment.lock.json 51 | artifacts/ 52 | **/Properties/launchSettings.json 53 | 54 | *_i.c 55 | *_p.c 56 | *_i.h 57 | *.ilk 58 | *.meta 59 | *.obj 60 | *.pch 61 | *.pdb 62 | *.pgc 63 | *.pgd 64 | *.rsp 65 | *.sbr 66 | *.tlb 67 | *.tli 68 | *.tlh 69 | *.tmp 70 | *.tmp_proj 71 | *.log 72 | *.vspscc 73 | *.vssscc 74 | .builds 75 | *.pidb 76 | *.svclog 77 | *.scc 78 | 79 | # Chutzpah Test files 80 | _Chutzpah* 81 | 82 | # Visual C++ cache files 83 | ipch/ 84 | *.aps 85 | *.ncb 86 | *.opendb 87 | *.opensdf 88 | *.sdf 89 | *.cachefile 90 | *.VC.db 91 | *.VC.VC.opendb 92 | 93 | # Visual Studio profiler 94 | *.psess 95 | *.vsp 96 | *.vspx 97 | *.sap 98 | 99 | # TFS 2012 Local Workspace 100 | $tf/ 101 | 102 | # Guidance Automation Toolkit 103 | *.gpState 104 | 105 | # ReSharper is a .NET coding add-in 106 | _ReSharper*/ 107 | *.[Rr]e[Ss]harper 108 | *.DotSettings.user 109 | 110 | # JustCode is a .NET coding add-in 111 | .JustCode 112 | 113 | # TeamCity is a build add-in 114 | _TeamCity* 115 | 116 | # DotCover is a Code Coverage Tool 117 | *.dotCover 118 | 119 | # AxoCover is a Code Coverage Tool 120 | .axoCover/* 121 | !.axoCover/settings.json 122 | 123 | # Visual Studio code coverage results 124 | *.coverage 125 | *.coveragexml 126 | 127 | # NCrunch 128 | _NCrunch_* 129 | .*crunch*.local.xml 130 | nCrunchTemp_* 131 | 132 | # MightyMoose 133 | *.mm.* 134 | AutoTest.Net/ 135 | 136 | # Web workbench (sass) 137 | .sass-cache/ 138 | 139 | # Installshield output folder 140 | [Ee]xpress/ 141 | 142 | # DocProject is a documentation generator add-in 143 | DocProject/buildhelp/ 144 | DocProject/Help/*.HxT 145 | DocProject/Help/*.HxC 146 | DocProject/Help/*.hhc 147 | DocProject/Help/*.hhk 148 | DocProject/Help/*.hhp 149 | DocProject/Help/Html2 150 | DocProject/Help/html 151 | 152 | # Click-Once directory 153 | publish/ 154 | 155 | # Publish Web Output 156 | *.[Pp]ublish.xml 157 | *.azurePubxml 158 | # Note: Comment the next line if you want to checkin your web deploy settings, 159 | # but database connection strings (with potential passwords) will be unencrypted 160 | *.pubxml 161 | *.publishproj 162 | 163 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 164 | # checkin your Azure Web App publish settings, but sensitive information contained 165 | # in these scripts will be unencrypted 166 | PublishScripts/ 167 | 168 | # NuGet Packages 169 | *.nupkg 170 | # The packages folder can be ignored because of Package Restore 171 | **/packages/* 172 | # except build/, which is used as an MSBuild target. 173 | !**/packages/build/ 174 | # Uncomment if necessary however generally it will be regenerated when needed 175 | #!**/packages/repositories.config 176 | # NuGet v3's project.json files produces more ignorable files 177 | *.nuget.props 178 | *.nuget.targets 179 | 180 | # Microsoft Azure Build Output 181 | csx/ 182 | *.build.csdef 183 | 184 | # Microsoft Azure Emulator 185 | ecf/ 186 | rcf/ 187 | 188 | # Windows Store app package directories and files 189 | AppPackages/ 190 | BundleArtifacts/ 191 | Package.StoreAssociation.xml 192 | _pkginfo.txt 193 | *.appx 194 | 195 | # Visual Studio cache files 196 | # files ending in .cache can be ignored 197 | *.[Cc]ache 198 | # but keep track of directories ending in .cache 199 | !*.[Cc]ache/ 200 | 201 | # Others 202 | ClientBin/ 203 | ~$* 204 | *~ 205 | *.dbmdl 206 | *.dbproj.schemaview 207 | *.jfm 208 | *.pfx 209 | *.publishsettings 210 | orleans.codegen.cs 211 | 212 | # Since there are multiple workflows, uncomment next line to ignore bower_components 213 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 214 | #bower_components/ 215 | 216 | # RIA/Silverlight projects 217 | Generated_Code/ 218 | 219 | # Backup & report files from converting an old project file 220 | # to a newer Visual Studio version. Backup files are not needed, 221 | # because we have git ;-) 222 | _UpgradeReport_Files/ 223 | Backup*/ 224 | UpgradeLog*.XML 225 | UpgradeLog*.htm 226 | 227 | # SQL Server files 228 | *.mdf 229 | *.ldf 230 | *.ndf 231 | 232 | # Business Intelligence projects 233 | *.rdl.data 234 | *.bim.layout 235 | *.bim_*.settings 236 | 237 | # Microsoft Fakes 238 | FakesAssemblies/ 239 | 240 | # GhostDoc plugin setting file 241 | *.GhostDoc.xml 242 | 243 | # Node.js Tools for Visual Studio 244 | .ntvs_analysis.dat 245 | node_modules/ 246 | 247 | # Typescript v1 declaration files 248 | typings/ 249 | 250 | # Visual Studio 6 build log 251 | *.plg 252 | 253 | # Visual Studio 6 workspace options file 254 | *.opt 255 | 256 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 257 | *.vbw 258 | 259 | # Visual Studio LightSwitch build output 260 | **/*.HTMLClient/GeneratedArtifacts 261 | **/*.DesktopClient/GeneratedArtifacts 262 | **/*.DesktopClient/ModelManifest.xml 263 | **/*.Server/GeneratedArtifacts 264 | **/*.Server/ModelManifest.xml 265 | _Pvt_Extensions 266 | 267 | # Paket dependency manager 268 | .paket/paket.exe 269 | paket-files/ 270 | 271 | # FAKE - F# Make 272 | .fake/ 273 | 274 | # JetBrains Rider 275 | .idea/ 276 | *.sln.iml 277 | 278 | # CodeRush 279 | .cr/ 280 | 281 | # Python Tools for Visual Studio (PTVS) 282 | __pycache__/ 283 | *.pyc 284 | 285 | # Cake - Uncomment if you are using it 286 | # tools/** 287 | # !tools/packages.config 288 | 289 | # Tabs Studio 290 | *.tss 291 | 292 | # Telerik's JustMock configuration file 293 | *.jmconfig 294 | 295 | # BizTalk build output 296 | *.btp.cs 297 | *.btm.cs 298 | *.odx.cs 299 | *.xsd.cs 300 | 301 | #ExampleRangeTester artifacts 302 | TesterMetadata.xml 303 | 304 | # Backup files 305 | *.bak 306 | 307 | */wwwroot/* 308 | 309 | !*/wwwroot/css/Site.css 310 | *.DS_Store 311 | -------------------------------------------------------------------------------- /ASP.NET Core/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using ASP_NET_Core.Models 2 | @{ 3 | string[] positions = new string[] {"HR Manager", "IT Manager", "CEO", "Controller", 4 | "Sales Manager", "Support Manager", "Shipping Manager", "Sales Assistant", "CMO" 5 | }; 6 | } 7 |

Custom Edit Form

8 | 9 | @( 10 | Html.DevExtreme().DataGrid() 11 | .ID("grid") 12 | .ShowBorders(true) 13 | .DataSource(d => d.Mvc().Controller("SampleData").Key("ID") 14 | .LoadAction("Get") 15 | .DeleteAction("Delete") 16 | .UpdateAction("Update") 17 | .InsertAction("Add") 18 | ) 19 | .ShowColumnLines(true) 20 | .ShowRowLines(true) 21 | .RepaintChangesOnly(true) 22 | .Editing(editing => editing 23 | .Mode(GridEditMode.Popup) 24 | .AllowAdding(true) 25 | .AllowDeleting(true) 26 | .AllowUpdating(true) 27 | .UseIcons(true) 28 | ) 29 | .Columns(columns => { 30 | columns.AddFor(m => m.FirstName); 31 | columns.AddFor(m => m.LastName); 32 | columns.AddFor(m => m.BirthDate); 33 | columns.AddFor(m => m.Position).Width(170); 34 | columns.AddFor(m => m.HireDate); 35 | columns.AddFor(m => m.Address); 36 | columns.Add().Type(GridCommandColumnType.Buttons).Buttons(buttons => { 37 | buttons.Add().Name(GridColumnButtonName.Edit).OnClick("editClick"); 38 | buttons.Add().Name(GridColumnButtonName.Delete); 39 | }); 40 | }) 41 | .Toolbar(toolbar => toolbar.Items(items => { 42 | items.Add().Widget(w => w.Button().Icon("plus").OnClick("addClick")); 43 | })) 44 | ) 45 | 46 | @(Html.DevExtreme().Popup() 47 | .ID("popup") 48 | .DeferRendering(false) 49 | .HideOnOutsideClick(true) 50 | .Height("auto") 51 | .ContentTemplate(new TemplateName("popup-template")) 52 | .ToolbarItems(toolbar => { 53 | toolbar.Add() 54 | .Location(ToolbarItemLocation.After) 55 | .Toolbar(Toolbar.Bottom) 56 | .Widget(w => w.Button() 57 | .Text("Confirm") 58 | .Type(ButtonType.Success) 59 | .OnClick("confirmClick") 60 | ); 61 | toolbar.Add() 62 | .Location(ToolbarItemLocation.After) 63 | .Toolbar(Toolbar.Bottom) 64 | .Widget(w => w.Button() 65 | .Text("Cancel") 66 | .Type(ButtonType.Danger) 67 | .OnClick("cancelClick") 68 | ); 69 | }) 70 | ) 71 | @using (Html.DevExtreme().NamedTemplate("popup-template")) { 72 | @( 73 | Html.DevExtreme().Form() 74 | .ID("form") 75 | .ShowColonAfterLabel(true) 76 | .ValidationGroup(new JS("validationGroupName")) 77 | .Items(items => { 78 | items.AddGroup().ColCount(2).Items(group => { 79 | group.AddSimpleFor(m => m.FirstName) 80 | .Label(label => label.Template(new JS("(data) => labelTemplate(data, 'user')"))); 81 | group.AddSimpleFor(m => m.Position) 82 | .Editor(editor => editor.SelectBox().SearchEnabled(true).Items(positions)) 83 | .Label(label => label.Template(new JS("(data) => labelTemplate(data, 'info')"))); 84 | group.AddSimpleFor(m => m.LastName) 85 | .Label(label => label.Template(new JS("(data) => labelTemplate(data, 'user')"))); 86 | group.AddSimpleFor(m => m.Address) 87 | .Label(label => label.Template(new JS("(data) => labelTemplate(data, 'home')"))); 88 | group.AddSimpleFor(m => m.BirthDate) 89 | .Label(label => label.Template(new JS("(data) => labelTemplate(data, 'event')"))); 90 | group.AddSimpleFor(m => m.HireDate) 91 | .Label(label => label.Template(new JS("(data) => labelTemplate(data, 'event')"))); 92 | group.AddSimpleFor(m => m.Notes) 93 | .ColSpan(2) 94 | .Editor(editor => editor.TextArea().MaxLength(200).Height(90)) 95 | .Label(label => label.Template(new TemplateName("notes-label-template"))); 96 | group.AddSimpleFor(m => m.Phone) 97 | .Editor(editor => editor.TextBox() 98 | .Mask("+1 (X00) 000-0000") 99 | .MaskRules(new JS("{ X: /[02-9]/ }")) 100 | .MaskInvalidMessage("The phone must have a correct USA phone format") 101 | ) 102 | .Label(label => label.Template(new JS("(data) => labelTemplate(data, 'tel')"))); 103 | group.AddSimpleFor(m => m.Email) 104 | .Label(label => label.Template(new JS("(data) => labelTemplate(data, 'email')"))); 105 | }); 106 | }) 107 | ); 108 | } 109 | @using (Html.DevExtreme().NamedTemplate("notes-label-template")) { 110 |
111 | 112 | Additional
<%- text %> 113 |
114 | @(Html.DevExtreme().Tooltip() 115 | .ShowEvent("mouseenter") 116 | .HideEvent("mouseleave") 117 | .Target("#helpedInfo") 118 | .ContentTemplate(@ 119 |
This field must not exceed 200 characters
120 |
) 121 | ) 122 | } 123 | -------------------------------------------------------------------------------- /jQuery/src/index.js: -------------------------------------------------------------------------------- 1 | $(() => { 2 | const validationRules = { 3 | firstName: [{ type: 'required', message: 'First Name is required.' }], 4 | lastName: [{ type: 'required', message: 'Last Name is required.' }], 5 | phone: [{ type: 'required', message: 'Phone number is required.' }], 6 | email: [{ type: 'email', message: 'Email is incorrect.' }], 7 | birthDate: [ 8 | { 9 | type: 'required', 10 | message: 'Birth Date is required.', 11 | invalidDateMessage: 12 | 'The date must have the following format: mm/dd/yyyy', 13 | }, 14 | ], 15 | }; 16 | 17 | const grid = $('#grid').dxDataGrid({ 18 | showBorders: true, 19 | showColumnLines: true, 20 | showRowLines: true, 21 | repaintChangesOnly: true, 22 | dataSource: new DevExpress.data.DataSource({ 23 | store: { 24 | type: 'array', 25 | data: employees, 26 | key: 'ID', 27 | }, 28 | }), 29 | editing: { 30 | allowUpdating: true, 31 | allowAdding: true, 32 | allowDeleting: true, 33 | useIcons: true, 34 | mode: 'popup', 35 | }, 36 | columns: [ 37 | { dataField: 'FirstName', dataType: 'string' }, 38 | { dataField: 'LastName', dataType: 'string' }, 39 | { dataField: 'BirthDate', dataType: 'date' }, 40 | { dataField: 'Position', dataType: 'string', width: 170 }, 41 | { dataField: 'HireDate', dataType: 'date' }, 42 | { dataField: 'Address', dataType: 'string' }, 43 | { 44 | type: 'buttons', 45 | buttons: [ 46 | { 47 | name: 'edit', 48 | onClick: (e) => { 49 | showPopup(false, { ...e.row.data }); 50 | }, 51 | }, 52 | 'delete', 53 | ], 54 | }, 55 | ], 56 | toolbar: { 57 | items: [ 58 | { 59 | widget: 'dxButton', 60 | options: { 61 | icon: 'plus', 62 | onClick: () => { 63 | showPopup(true, {}); 64 | }, 65 | }, 66 | }, 67 | ], 68 | }, 69 | }).dxDataGrid('instance'); 70 | 71 | const validationGroupName = 'gridForm'; 72 | 73 | const createPopupTemplate = (formData) => () => { 74 | const labelTemplate = (iconName) => (data) => $(`
${data.text}
`); 75 | return $('
').dxForm({ 76 | formData, 77 | validationGroup: validationGroupName, 78 | showColonAfterLabel: true, 79 | items: [{ 80 | itemType: 'group', 81 | colCount: 2, 82 | items: [ 83 | { 84 | dataField: 'FirstName', 85 | validationRules: validationRules.firstName, 86 | label: { 87 | template: labelTemplate('user'), 88 | }, 89 | }, 90 | { 91 | dataField: 'Position', 92 | editorType: 'dxSelectBox', 93 | editorOptions: { 94 | items: positions, 95 | searchEnabled: true, 96 | }, 97 | label: { 98 | template: labelTemplate('info'), 99 | }, 100 | }, 101 | { 102 | dataField: 'LastName', 103 | validationRules: validationRules.lastName, 104 | label: { 105 | template: labelTemplate('user'), 106 | }, 107 | }, 108 | { 109 | dataField: 'Address', 110 | label: { 111 | template: labelTemplate('home'), 112 | }, 113 | }, 114 | { 115 | dataField: 'BirthDate', 116 | editorType: 'dxDateBox', 117 | validationRules: validationRules.birthDate, 118 | label: { 119 | template: labelTemplate('event'), 120 | }, 121 | }, 122 | { 123 | dataField: 'HireDate', 124 | editorType: 'dxDateBox', 125 | label: { 126 | template: labelTemplate('event'), 127 | }, 128 | }, 129 | { 130 | colSpan: 2, 131 | dataField: 'Notes', 132 | editorType: 'dxTextArea', 133 | editorOptions: { 134 | height: 90, 135 | maxLength: 200, 136 | }, 137 | label: { 138 | template: (data, element) => { 139 | const lineBreak = '
'; 140 | const infoIcon = ''; 141 | const labelText = `Additional${lineBreak}${data.text}`; 142 | 143 | element.append( 144 | `
${infoIcon}${labelText}
`, 145 | ); 146 | 147 | $('
').dxTooltip({ 148 | target: '#helped-info', 149 | showEvent: 'mouseenter', 150 | hideEvent: 'mouseleave', 151 | contentTemplate(args) { 152 | args.html( 153 | '
This field must not exceed 200 characters
', 154 | ); 155 | }, 156 | }).appendTo(element); 157 | }, 158 | }, 159 | }, 160 | { 161 | dataField: 'Phone', 162 | validationRules: validationRules.phone, 163 | editorOptions: { 164 | mask: '+1 (X00) 000-0000', 165 | maskRules: { X: /[02-9]/ }, 166 | maskInvalidMessage: 167 | 'The phone must have a correct USA phone format', 168 | }, 169 | label: { 170 | template: labelTemplate('tel'), 171 | }, 172 | }, 173 | { 174 | dataField: 'Email', 175 | validationRules: validationRules.email, 176 | label: { 177 | template: labelTemplate('email'), 178 | }, 179 | }, 180 | ], 181 | }], 182 | }); 183 | }; 184 | 185 | const popup = $('#popup').dxPopup({ 186 | hideOnOutsideClick: true, 187 | height: 'auto', 188 | }).dxPopup('instance'); 189 | 190 | const confirmItem = { 191 | widget: 'dxButton', 192 | location: 'after', 193 | toolbar: 'bottom', 194 | options: { 195 | text: 'Confirm', 196 | type: 'success', 197 | }, 198 | }; 199 | 200 | const cancelItem = { 201 | widget: 'dxButton', 202 | location: 'after', 203 | toolbar: 'bottom', 204 | options: { 205 | text: 'Cancel', 206 | onClick: () => { 207 | popup.hide(); 208 | }, 209 | }, 210 | }; 211 | 212 | const showPopup = (isNewRecord, data) => { 213 | const contentTemplate = createPopupTemplate(data); 214 | popup.option({ 215 | title: isNewRecord ? 'Add' : 'Edit', 216 | contentTemplate, 217 | toolbarItems: [ 218 | { 219 | ...confirmItem, 220 | onClick: () => { 221 | const result = DevExpress.validationEngine.validateGroup(validationGroupName); 222 | if (!result.isValid) return; 223 | const gridSource = grid.getDataSource(); 224 | const gridStore = gridSource.store(); 225 | if (isNewRecord) gridStore.insert(data); 226 | else gridStore.update(data.ID, data); 227 | grid.refresh(true); 228 | popup.hide(); 229 | }, 230 | }, 231 | cancelItem, 232 | ], 233 | visible: true, 234 | }); 235 | }; 236 | }); 237 | -------------------------------------------------------------------------------- /ASP.NET Core/Models/EmployeeStore.cs: -------------------------------------------------------------------------------- 1 | using ASP_NET_Core.Models; 2 | using DevExtreme.AspNet.Mvc; 3 | using System.Collections.Generic; 4 | using System.Net; 5 | using System.Numerics; 6 | 7 | namespace ASP.NET_Core.Models 8 | { 9 | static class EmployeeStore { 10 | public static List Employees = new List() { 11 | new Employee() { 12 | ID = 1, 13 | FirstName = "John", 14 | LastName = "Heart", 15 | Prefix = "Mr.", 16 | Position = "CEO", 17 | BirthDate = System.DateTime.Parse("1964/03/16"), 18 | HireDate = System.DateTime.Parse("1995/01/15"), 19 | Notes = "John has been in the Audio/Video industry since 1990. He has led DevAv as its CEO since 2003.\r\n\r\nWhen not working hard as the CEO, John loves to golf and bowl. He once bowled a perfect game of 300.", 20 | Address = "351 S Hill St.", 21 | Phone = "16102458448", 22 | Email = "rohitm@hotmail.com", 23 | }, new Employee() { 24 | ID = 2, 25 | FirstName = "Olivia", 26 | LastName = "Peyton", 27 | Prefix = "Mrs.", 28 | Position = "Sales Assistant", 29 | BirthDate = System.DateTime.Parse("1981/06/03"), 30 | HireDate = System.DateTime.Parse("2012/05/14"), 31 | Notes = "Olivia loves to sell. She has been selling DevAV products since 2012. \r\n\r\nOlivia was homecoming queen in high school. She is expecting her first child in 6 months. Good Luck Olivia.", 32 | Address = "807 W Paseo Del Mar", 33 | Phone = "16102347905", 34 | Email = "spadkins@optonline.net", 35 | }, new Employee() { 36 | ID = 3, 37 | FirstName = "Robert", 38 | LastName = "Reagan", 39 | Prefix = "Mr.", 40 | Position = "CMO", 41 | BirthDate = System.DateTime.Parse("1974/09/07"), 42 | HireDate = System.DateTime.Parse("2002/11/08"), 43 | Notes = "Robert was recently voted the CMO of the year by CMO Magazine. He is a proud member of the DevAV Management Team.\r\n\r\nRobert is a championship BBQ chef, so when you get the chance ask him for his secret recipe.", 44 | Address = "4 Westmoreland Pl.", 45 | Phone = "14845219762", 46 | Email = "naoya@comcast.net", 47 | }, new Employee() { 48 | ID = 4, 49 | FirstName = "Greta", 50 | LastName = "Sims", 51 | Prefix = "Ms.", 52 | Position = "HR Manager", 53 | BirthDate = System.DateTime.Parse("1977/11/22"), 54 | HireDate = System.DateTime.Parse("1998/04/23"), 55 | Notes = "Greta has been DevAV's HR Manager since 2003. She joined DevAV from Sonee Corp.\r\n\r\nGreta is currently training for the NYC marathon. Her best marathon time is 4 hours. Go Greta.", 56 | Address = "1700 S Grandview Dr.", 57 | Phone = "14844578858", 58 | Email = "tattooman@optonline.net", 59 | }, new Employee() { 60 | ID = 5, 61 | FirstName = "Brett", 62 | LastName = "Wade", 63 | Prefix = "Mr.", 64 | Position = "IT Manager", 65 | BirthDate = System.DateTime.Parse("1968/12/01"), 66 | HireDate = System.DateTime.Parse("2009/03/06"), 67 | Notes = "Brett came to DevAv from Microsoft and has led our IT department since 2012.\r\n\r\nWhen he is not working hard for DevAV, he coaches Little League (he was a high school pitcher).", 68 | Address = "1120 Old Mill Rd.", 69 | Phone = "18143008837", 70 | Email = "haddawy@mac.com", 71 | }, new Employee() { 72 | ID = 6, 73 | FirstName = "Sandra", 74 | LastName = "Johnson", 75 | Prefix = "Mrs.", 76 | Position = "Controller", 77 | BirthDate = System.DateTime.Parse("1974/11/15"), 78 | HireDate = System.DateTime.Parse("2005/05/11"), 79 | Notes = "Sandra is a CPA and has been our controller since 2008. She loves to interact with staff so if you've not met her, be certain to say hi.\r\n\r\nSandra has 2 daughters both of whom are accomplished gymnasts.", 80 | Address = "4600 N Virginia Rd.", 81 | Phone = "15852826538", 82 | Email = "gordonjcp@gmail.com", 83 | }, new Employee() { 84 | ID = 7, 85 | FirstName = "Kevin", 86 | LastName = "Carter", 87 | Prefix = "Mr.", 88 | Position = "Shipping Manager", 89 | BirthDate = System.DateTime.Parse("1978/01/09"), 90 | HireDate = System.DateTime.Parse("2009/08/11"), 91 | Notes = "Kevin is our hard-working shipping manager and has been helping that department work like clockwork for 18 months.\r\n\r\nWhen not in the office, he is usually on the basketball court playing pick-up games.", 92 | Address = "424 N Main St.", 93 | Phone = "14844760152", 94 | Email = "chance@verizon.net", 95 | }, new Employee() { 96 | ID = 8, 97 | FirstName = "Cynthia", 98 | LastName = "Stanwick", 99 | Prefix = "Ms.", 100 | Position = "HR Manager", 101 | BirthDate = System.DateTime.Parse("1985/06/05"), 102 | HireDate = System.DateTime.Parse("2008/03/24"), 103 | Notes = "Cindy joined us in 2008 and has been in the HR department for 2 years. \r\n\r\nShe was recently awarded employee of the month. Way to go Cindy!", 104 | Address = "2211 Bonita Dr.", 105 | Phone = "14842989304", 106 | Email = "kevinm@verizon.net", 107 | }, new Employee() { 108 | ID = 9, 109 | FirstName = "Kent", 110 | LastName = "Samuelson", 111 | Prefix = "Dr.", 112 | Position = "Support Manager", 113 | BirthDate = System.DateTime.Parse("1972/09/11"), 114 | HireDate = System.DateTime.Parse("2009/04/22"), 115 | Notes = "As our ombudsman, Kent is on the front-lines solving customer problems and helping our partners address issues out in the field. He is a classically trained musician and is a member of the Chamber Orchestra.", 116 | Address = "12100 Mora Dr", 117 | Phone = "14844731660", 118 | Email = "arebenti@outlook.com", 119 | }, new Employee() { 120 | ID = 10, 121 | FirstName = "Taylor", 122 | LastName = "Riley", 123 | Prefix = "Mr.", 124 | Position = "Sales Manager", 125 | BirthDate = System.DateTime.Parse("1982/08/14"), 126 | HireDate = System.DateTime.Parse("2012/04/14"), 127 | Notes = "If you are like the rest of us at DevAV, then you've probably reached out for help from Taylor. He does a great job as a member of our IT department.", 128 | Address = "7776 Torreyson Dr", 129 | Phone = "14842989306", 130 | Email = "amichalo@live.com", 131 | } 132 | }; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /React/src/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { 2 | useCallback, useState, useMemo, useRef, 3 | } from 'react'; 4 | 5 | import 'devextreme/dist/css/dx.light.css'; 6 | import './App.css'; 7 | 8 | import DataGrid, { 9 | Column, Editing, Button as ColumnButton, Toolbar, Item as GridToolbarItem, type DataGridRef, 10 | } from 'devextreme-react/data-grid'; 11 | import Popup, { ToolbarItem } from 'devextreme-react/popup'; 12 | import Form, { 13 | Item, GroupItem, Label, RequiredRule, EmailRule, 14 | } from 'devextreme-react/form'; 15 | import validationEngine from 'devextreme/ui/validation_engine'; 16 | import Button from 'devextreme-react/button'; 17 | import ArrayStore from 'devextreme/data/array_store'; 18 | import notify from 'devextreme/ui/notify'; 19 | import LabelTemplate from './LabelTemplate.tsx'; 20 | import LabelNotesTemplate from './LabelNotesTemplate.tsx'; 21 | import 'devextreme-react/text-area'; 22 | 23 | import { employees } from './data.ts'; 24 | 25 | import { 26 | positionEditorOptions, 27 | notesEditorOptions, 28 | phoneEditorOptions, 29 | } from './EditorOptions.ts'; 30 | 31 | const employeeStore = new ArrayStore({ 32 | data: employees, 33 | key: 'ID', 34 | }); 35 | 36 | const validationGroupName = 'gridForm'; 37 | interface Employee { 38 | ID: number; 39 | FirstName: string; 40 | LastName: string; 41 | Prefix: string; 42 | Position: string; 43 | BirthDate: string; 44 | HireDate: string; 45 | Notes: string; 46 | Address: string; 47 | Phone: string; 48 | Email: string; 49 | } 50 | 51 | interface PopupState { 52 | isNewRecord: boolean; 53 | formData: Partial; 54 | visible: boolean; 55 | } 56 | 57 | function App(): JSX.Element { 58 | const gridRef = useRef(null); 59 | const [{ isNewRecord, formData, visible }, setPopupState] = useState({ isNewRecord: false, formData: {} as Partial, visible: false }); 60 | 61 | const dataSource = useMemo(() => ({ store: employeeStore }), []); 62 | 63 | const hidePopup = useCallback(() => { 64 | setPopupState((prev) => ({ ...prev, visible: false })); 65 | }, []); 66 | 67 | const showPopup = useCallback((isNew: boolean, data: Partial) => { 68 | setPopupState({ isNewRecord: isNew, formData: data, visible: true }); 69 | }, []); 70 | 71 | // eslint-disable-next-line @typescript-eslint/space-before-function-paren, space-before-function-paren 72 | const confirmChanges = useCallback(async () => { 73 | const result = validationEngine.validateGroup(validationGroupName); 74 | if (!result.isValid) return; 75 | 76 | try { 77 | if (isNewRecord) { 78 | await employeeStore.insert(formData as Employee); 79 | } else if (formData.ID !== undefined) { 80 | await employeeStore.update(formData.ID, formData as Employee); 81 | } 82 | const instance = gridRef.current?.instance(); 83 | if (instance) { 84 | await instance.refresh(true); 85 | } 86 | notify(isNewRecord ? 'Employee added' : 'Employee updated', 'success', 2000); 87 | } catch (err) { 88 | notify('Save failed', 'error', 3000); 89 | } finally { 90 | hidePopup(); 91 | } 92 | }, [isNewRecord, formData, hidePopup]); 93 | 94 | const confirmBtnOptions = useMemo(() => ({ 95 | text: isNewRecord ? 'Add' : 'Save', 96 | type: 'success', 97 | onClick: confirmChanges, 98 | }), [isNewRecord, confirmChanges]); 99 | 100 | const editRow = useCallback((e: any) => { 101 | showPopup(false, { ...e.row.data }); 102 | }, [showPopup]); 103 | 104 | const addRow = useCallback(() => { 105 | showPopup(true, {}); 106 | }, [showPopup]); 107 | 108 | const cancelBtnOptions = useMemo(() => ({ 109 | text: 'Cancel', 110 | onClick: hidePopup, 111 | }), [hidePopup]); 112 | 113 | return ( 114 | 115 | 121 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 |