├── 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 |
2 |
3 | {{ data.text }}
4 |
5 |
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 |
12 | We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
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 |
2 |
3 |
7 | Additional
{{ data.text }}
8 |
13 |
14 | This field must not exceed 200 characters
15 |
16 |
17 |
18 |
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 | 
3 | [](https://supportcenter.devexpress.com/ticket/details/T888862)
4 | [](https://docs.devexpress.com/GeneralInformation/403183)
5 | [](#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 |
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 |
143 |
144 |
145 |
146 | { visible ? (
147 |
154 |
160 |
166 |
167 |
206 |
207 | ) : null }
208 |
209 |
210 | );
211 | }
212 |
213 | export default App;
214 |
--------------------------------------------------------------------------------
/Vue/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
16 |
20 |
24 |
28 |
33 |
37 |
41 |
42 |
46 |
47 |
48 |
49 |
53 |
54 |
55 |
56 |
60 |
61 |
62 |
63 |
69 |
79 |
88 |
89 |
93 |
96 |
97 |
98 |
99 |
100 |
101 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
122 |
123 |
124 |
125 |
126 |
130 |
131 |
132 |
133 |
139 |
140 |
141 |
142 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
161 |
162 |
163 |
167 |
168 |
169 |
173 |
174 |
175 |
179 |
180 |
181 |
184 |
185 |
186 |
190 |
191 |
192 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
297 |
--------------------------------------------------------------------------------
/test-example.ps1:
--------------------------------------------------------------------------------
1 | # For local testing, you can pass buildVersion.
2 | # Example usage:
3 | # ./test-example.ps1 -buildVersion 23.1.13
4 | param (
5 | [string]$buildVersion = $Env:CodeCentralBuildVersion
6 | )
7 |
8 | # Masstest-specific parameter. Specifies the minor version (example: '21.1.5')
9 | $global:BUILD_VERSION = $buildVersion
10 |
11 | $global:ERROR_CODE = 0
12 | $global:FAILED_PROJECTS = @()
13 |
14 | function Test-NpmVersionExists {
15 | param ([string]$Pkg, [string]$Ver)
16 | npm view "$Pkg@$Ver" > $null 2>&1
17 | return ($LASTEXITCODE -eq 0)
18 | }
19 |
20 | function Get-ValidNpmVersion {
21 | param (
22 | [string]$PackageName,
23 | [string]$Version
24 | )
25 |
26 | Write-Host "Checking $PackageName@$Version..."
27 | if (Test-NpmVersionExists -Pkg $PackageName -Ver $Version) {
28 | Write-Host "$PackageName@$Version exists."
29 | return $Version
30 | }
31 |
32 | try {
33 | $v = [version]$Version
34 | $fallback = "$($v.Major).$($v.Minor)-stable"
35 | } catch {
36 | Write-Host "Invalid version format: $Version"
37 | return $null
38 | }
39 |
40 | Write-Host "$PackageName@$Version not found. Trying fallback: $PackageName@$fallback..."
41 | if (Test-NpmVersionExists -Pkg $PackageName -Ver $fallback) {
42 | Write-Host "$PackageName@$fallback exists (fallback)."
43 | return $fallback
44 | }
45 |
46 | Write-Host "Neither $PackageName@$Version nor @$fallback exist."
47 | return $null
48 | }
49 |
50 | function Install-Packages {
51 | param (
52 | [string]$folderName,
53 | [string[]]$packages,
54 | [string]$buildVersion
55 | )
56 |
57 | Write-Output "`nInstalling packages in folder: $folderName"
58 |
59 | foreach ($package in $packages) {
60 | $packageVersion = Get-ValidNpmVersion -PackageName $package -Version $buildVersion
61 | $packageWithVersion = "$package@$packageVersion"
62 | Write-Output "Installing $packageWithVersion..."
63 |
64 | npm install --save --save-exact --no-fund --loglevel=error --force $packageWithVersion
65 | if (-not $?) {
66 | Write-Error "`nERROR: Failed to install $packageWithVersion in $folderName"
67 | throw "Installation failed for $packageWithVersion in $folderName"
68 | }
69 | }
70 |
71 | Write-Output "`nAll packages installed successfully in $folderName"
72 | }
73 |
74 | function Build-Project {
75 | param (
76 | [string]$folderName
77 | )
78 | Write-Output "`nBuilding the project in folder: $folderName"
79 |
80 | npm run build
81 | if (-not $?) {
82 | Write-Error "`nERROR: Failed to build the project in $folderName"
83 | throw "Build failed in $folderName"
84 | }
85 | }
86 |
87 | function Process-JavaScriptProjects {
88 | param (
89 | [string]$buildVersion
90 | )
91 | Write-Output "`n--== Starting JavaScript Projects Processing ==--"
92 |
93 | [hashtable[]]$folders = @(
94 | @{ Name = "Angular"; Packages = @("devextreme", "devextreme-angular") },
95 | @{ Name = "React"; Packages = @("devextreme", "devextreme-react") },
96 | @{ Name = "Vue"; Packages = @("devextreme", "devextreme-vue") }
97 | )
98 |
99 | $jQueryEntry = @{
100 | Name = "jQuery";
101 | Packages = if ([version]$buildVersion -ge [version]23.1) {
102 | @("devextreme", "devextreme-dist")
103 | } else {
104 | @("devextreme")
105 | }
106 | }
107 |
108 | $folders = @($jQueryEntry) + $folders
109 |
110 | foreach ($folder in $folders) {
111 | $folderName = $folder.Name
112 | $packages = $folder.Packages
113 |
114 | if (-not (Test-Path $folderName)) {
115 | Write-Output "`nDirectory $folderName does not exist. Skipping..."
116 | continue
117 | }
118 |
119 | Write-Output "`nProcessing folder: $folderName"
120 | Push-Location $folderName
121 |
122 | try {
123 | Write-Output "`nRemoving node_modules & package-lock.json: $pwd"
124 | Remove-Item -Recurse -Force node_modules -ErrorAction SilentlyContinue
125 | Remove-Item -Force package-lock.json -ErrorAction SilentlyContinue
126 | Install-Packages -folderName $folderName -packages $packages -buildVersion $buildVersion
127 | Write-Output "`nInstalling remaining packages in $folderName"
128 | npm install --save --save-exact --no-fund --loglevel=error
129 | if (-not $?) {
130 | throw "ERROR: Failed to install remaining packages in $folderName"
131 | }
132 | Build-Project -folderName $folderName
133 | } catch {
134 | Write-Error "`nAn error occurred: $_"
135 | $global:LASTEXITCODE = 1
136 | $global:ERROR_CODE = 1
137 | $global:FAILED_PROJECTS += $folderName
138 | } finally {
139 | Pop-Location
140 | }
141 | }
142 |
143 | Write-Output "`n--== JavaScript Projects Processing Completed ==--"
144 | }
145 |
146 | function Resolve-NuGetVersionWithFallback {
147 | param (
148 | [string]$PackageName,
149 | [string]$RequestedVersion
150 | )
151 |
152 | function Test-PackageAvailable {
153 | param ([string]$name, [string]$ver)
154 | dotnet add package $name --version $ver > $null 2>&1
155 | return ($LASTEXITCODE -eq 0)
156 | }
157 |
158 | if (Test-PackageAvailable -name $PackageName -ver $RequestedVersion) {
159 | Write-Host "$PackageName@$RequestedVersion is available."
160 | return $RequestedVersion
161 | }
162 |
163 | Write-Host "$PackageName@$RequestedVersion not found. Checking for -beta and -alpha versions..."
164 |
165 | $suffixes = @("beta", "alpha")
166 | foreach ($suffix in $suffixes) {
167 | $fallbackVersion = "$RequestedVersion-$suffix"
168 | if (Test-PackageAvailable -name $PackageName -ver $fallbackVersion) {
169 | Write-Host "Found $PackageName@$fallbackVersion"
170 | return $fallbackVersion
171 | }
172 | }
173 |
174 | Write-Warning "No matching versions found for $PackageName@$RequestedVersion"
175 | return $null
176 | }
177 |
178 | function Process-AspNetCoreProject {
179 | param (
180 | [Parameter(Mandatory = $true)]
181 | [string]$buildVersion
182 | )
183 |
184 | $folderPath = Get-ChildItem -Directory |
185 | Where-Object { $_.Name -match '(?i)^ASP\.NET\s*Core$' } |
186 | Select-Object -First 1 -ExpandProperty FullName
187 |
188 | if (-not $folderPath) {
189 | Write-Error "Directory matching 'ASP.NET Core' not found."
190 | return
191 | }
192 |
193 | Write-Host "Found project directory: $folderPath"
194 | Push-Location $folderPath
195 |
196 | try {
197 | $resolvedNugetVersion = Resolve-NuGetVersionWithFallback -PackageName "DevExtreme.AspNet.Core" -RequestedVersion $buildVersion
198 | if (-not $resolvedNugetVersion) {
199 | throw "No valid version found for DevExtreme.AspNet.Core"
200 | }
201 |
202 | Write-Host "Installing DevExtreme.AspNet.Core@$resolvedNugetVersion..."
203 | dotnet add package DevExtreme.AspNet.Core --version $resolvedNugetVersion
204 |
205 | $packageJsonPath = Get-ChildItem -Path $folderPath -Filter "package.json" -Recurse -File -ErrorAction SilentlyContinue |
206 | Select-Object -First 1 -ExpandProperty FullName
207 |
208 | if ($packageJsonPath) {
209 | Write-Host "Found package.json: $packageJsonPath"
210 |
211 | try {
212 | $packageJson = Get-Content -Path $packageJsonPath -Raw | ConvertFrom-Json
213 | $updated = $false
214 |
215 | if ($packageJson.dependencies.devextreme) {
216 | $validDevextremeVersion = Get-ValidNpmVersion -PackageName "devextreme" -Version $buildVersion
217 | if ($validDevextremeVersion) {
218 | $packageJson.dependencies.devextreme = $validDevextremeVersion
219 | $updated = $true
220 | }
221 | }
222 |
223 | if ($packageJson.dependencies.'devextreme-dist') {
224 | $validDevextremeDistVersion = Get-ValidNpmVersion -PackageName "devextreme-dist" -Version $buildVersion
225 | if ($validDevextremeDistVersion) {
226 | $packageJson.dependencies.'devextreme-dist' = $validDevextremeDistVersion
227 | $updated = $true
228 | }
229 | }
230 |
231 | if ($updated) {
232 | $tempJsonPath = [System.IO.Path]::GetTempFileName()
233 | $jsonContent = $packageJson | ConvertTo-Json -Depth 10
234 | [System.IO.File]::WriteAllText($tempJsonPath, $jsonContent, [System.Text.UTF8Encoding]::new($false))
235 | node -e "const fs = require('fs'); const data = fs.readFileSync('$($tempJsonPath -replace '\\', '/')', 'utf8'); fs.writeFileSync('$($packageJsonPath -replace '\\', '/')', data, 'utf8');"
236 | Remove-Item $tempJsonPath -ErrorAction SilentlyContinue
237 | Write-Host "Updated package.json with valid versions."
238 | } else {
239 | Write-Host "No matching dependencies found in package.json to update."
240 | }
241 |
242 | Write-Host "Installing NPM dependencies..."
243 | npm install --save --save-exact --no-fund --loglevel=error
244 | if (-not $?) {
245 | throw "Failed to install npm dependencies"
246 | }
247 | } catch {
248 | Write-Error "Failed to update package.json: $_"
249 | }
250 | } else {
251 | Write-Warning "No package.json file found in '$folderPath'."
252 | }
253 |
254 | Write-Host "Running dotnet build..."
255 | dotnet build
256 | if ($LASTEXITCODE -eq 0) {
257 | Write-Host "Build succeeded."
258 | } else {
259 | throw
260 | }
261 | } catch {
262 | Write-Error "An error occurred: $_"
263 | $global:LASTEXITCODE = 1
264 | $global:ERROR_CODE = 1
265 | $global:FAILED_PROJECTS += "ASP.NET Core"
266 | } finally {
267 | Pop-Location
268 | }
269 | }
270 |
271 | function Write-BuildInfo {
272 | $BUILD_VERSION = if ($global:BUILD_VERSION -ne $null -and $global:BUILD_VERSION -ne "") {
273 | $global:BUILD_VERSION
274 | } else {
275 | "(empty)"
276 | }
277 |
278 | Write-Output "Build Version: $BUILD_VERSION"
279 | }
280 |
281 | Write-BuildInfo
282 | Process-JavaScriptProjects -buildVersion $global:BUILD_VERSION
283 | Process-AspNetCoreProject -buildVersion $global:BUILD_VERSION
284 |
285 | Write-Output "`nFinished testing version: $global:BUILD_VERSION. Error code: $global:ERROR_CODE"
286 | if ($global:ERROR_CODE -ne 0 -and $global:FAILED_PROJECTS.Count -gt 0) {
287 | Write-Output "`FAILED PROJECTS: $(($global:FAILED_PROJECTS -join ", "))"
288 | }
289 |
290 | exit $global:ERROR_CODE
291 |
--------------------------------------------------------------------------------