-
Notifications
You must be signed in to change notification settings - Fork 672
✨AI Column: Write jQuery Demo #31582
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f17819c
29a615d
3919def
7d1fd98
0b3066a
ded0d2e
31af444
04fbc0b
b983caa
c2eb9b5
46ae17b
0c278ee
bce1369
f50958f
fdd489b
f5a8440
5f7d139
ddc0217
7bb7dc7
b6cf6bc
88f6d21
5a1dc0b
97e3d5f
0bfb51d
30b0c64
e78e975
f9f8ad9
f392200
aad4f02
05eaca7
621e22d
1593bcc
1a9c8aa
6a043b2
dfd87b4
c4ff9ef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| <!DOCTYPE html> | ||
| <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> | ||
| <head> | ||
| <title>DevExtreme Demo</title> | ||
| <meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" /> | ||
| <link rel="stylesheet" type="text/css" href="../../../../node_modules/devextreme/dist/css/dx.light.css" /> | ||
| <script src="../../../../node_modules/jquery/dist/jquery.min.js"></script> | ||
| <script src="../../../../node_modules/devextreme-dist/js/dx.all.js"></script> | ||
| <script type="module"> | ||
| import { AzureOpenAI } from "https://esm.sh/openai@4.73.1"; | ||
|
|
||
| window.AzureOpenAI = AzureOpenAI; | ||
| </script> | ||
| <script src="data.js"></script> | ||
| <script src="../../../../node_modules/devextreme-dist/js/dx.ai-integration.js"></script> | ||
| <script src="index.js"></script> | ||
| <link rel="stylesheet" type="text/css" href="styles.css" /> | ||
| </head> | ||
| <body class="dx-viewport"> | ||
| <div class="demo-container"> | ||
| <div id="data-grid-demo"> | ||
| <div id="gridContainer"></div> | ||
| <div id="popup"></div> | ||
| </div> | ||
| </div> | ||
| </body> | ||
| </html> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,202 @@ | ||
| $(() => { | ||
| const aiService = new AzureOpenAI({ | ||
| dangerouslyAllowBrowser: true, | ||
| deployment, | ||
| endpoint, | ||
| apiVersion, | ||
| apiKey, | ||
| }); | ||
|
Raushen marked this conversation as resolved.
|
||
|
|
||
| async function getAIResponse(messages, signal) { | ||
| const params = { | ||
| messages, | ||
| model: deployment, | ||
| max_tokens: 1000, | ||
| temperature: 0.7, | ||
| }; | ||
| const response = await aiService.chat.completions.create(params, { signal }); | ||
| const result = response.choices[0].message?.content; | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| const aiIntegration = new DevExpress.aiIntegration({ | ||
| sendRequest({ prompt }) { | ||
| const controller = new AbortController(); | ||
| const signal = controller.signal; | ||
|
|
||
| const aiPrompt = [ | ||
| { role: 'system', content: prompt.system }, | ||
| { role: 'user', content: prompt.user }, | ||
| ]; | ||
|
|
||
| const promise = getAIResponse(aiPrompt, signal); | ||
|
|
||
| const result = { | ||
| promise, | ||
| abort: () => { | ||
| controller.abort(); | ||
| }, | ||
| }; | ||
|
|
||
| return result; | ||
| }, | ||
| }); | ||
|
|
||
| const popupContentTemplate = function (vehicle) { | ||
| const { | ||
| Source, | ||
| LicenseName, | ||
| Author, | ||
| Edits, | ||
| } = vehicle; | ||
| const sourceLink = `https://${Source}`; | ||
| return $('<div>').append( | ||
| $('<p>') | ||
| .append($('<b>').text('Image licensed under: ')) | ||
| .append($('<span>').text(LicenseName)), | ||
| $('<p>') | ||
| .append($('<b>').text('Author: ')) | ||
| .append($('<span>').text(Author)), | ||
| $('<p>') | ||
| .append($('<b>').text('Source link: ')) | ||
| .append( | ||
| $('<a>', { | ||
| href: sourceLink, | ||
| target: '_blank', | ||
| }) | ||
| .text(sourceLink), | ||
| ), | ||
| $('<p>') | ||
| .append($('<b>').text('Edits: ')) | ||
| .append($('<span>').text(Edits)), | ||
| ); | ||
| }; | ||
|
|
||
| const popup = $('#popup').dxPopup({ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we explicitly set the showCloseButton option? By default, it has different values in different themes. |
||
| width: 360, | ||
| height: 260, | ||
| visible: false, | ||
| dragEnabled: false, | ||
| hideOnOutsideClick: true, | ||
| showCloseButton: true, | ||
| title: 'Image Info', | ||
| position: { | ||
| at: 'center', | ||
| my: 'center', | ||
| collision: 'fit', | ||
| }, | ||
| }).dxPopup('instance'); | ||
|
|
||
| const createTrademarkTemplate = (vehicle) => { | ||
| const { | ||
| ID, | ||
| Name, | ||
| TrademarkName, | ||
| } = vehicle; | ||
|
Raushen marked this conversation as resolved.
|
||
| const trademarkWrapper = $('<div>').addClass('trademark__wrapper'); | ||
| const imgWrapper = $('<div>').addClass('trademark__img-wrapper'); | ||
| const img = $('<img>').addClass('trademark__img'); | ||
| img.attr({ | ||
| src: `../../../../images/vehicles/image_${ID}.png`, | ||
| alt: `${TrademarkName} ${Name}`, | ||
| tabindex: 0, | ||
| role: 'button', | ||
| 'aria-haspopup': 'dialog', | ||
| 'aria-label': `${TrademarkName} ${Name} - press Enter for image info`, | ||
| }); | ||
|
|
||
| const showPopup = () => { | ||
| popup.option('contentTemplate', () => popupContentTemplate(vehicle)); | ||
| popup.show(); | ||
| }; | ||
|
|
||
| img.on('click', showPopup); | ||
|
|
||
| img.on('keydown', (e) => { | ||
| if (e.key === 'Enter') { | ||
| showPopup(); | ||
| } | ||
| }); | ||
|
|
||
| imgWrapper.append(img); | ||
| trademarkWrapper.append(imgWrapper); | ||
|
|
||
| const textWrapper = $('<div>').addClass('trademark__text-wrapper'); | ||
| const trademarkText = $('<div>').addClass('trademark__text trademark__text--title').text(TrademarkName); | ||
| const nameText = $('<div>').addClass('trademark__text trademark__text--subtitle').text(Name); | ||
|
dmlvr marked this conversation as resolved.
|
||
|
|
||
| textWrapper.append(trademarkText, nameText); | ||
| trademarkWrapper.append(textWrapper); | ||
|
|
||
| return trademarkWrapper; | ||
| }; | ||
|
|
||
| const createCategoryTemplate = ({ CategoryName }) => $('<div>').addClass('category__wrapper').text(CategoryName); | ||
|
dmlvr marked this conversation as resolved.
Raushen marked this conversation as resolved.
|
||
|
|
||
| $('#gridContainer').dxDataGrid({ | ||
| dataSource: vehicles, | ||
|
dmlvr marked this conversation as resolved.
dmlvr marked this conversation as resolved.
Raushen marked this conversation as resolved.
|
||
| keyExpr: 'ID', | ||
| paging: { | ||
| pageSize: 10, | ||
| }, | ||
| aiIntegration, | ||
| grouping: { | ||
| contextMenuEnabled: false, | ||
| }, | ||
| groupPanel: { | ||
| visible: false, | ||
| }, | ||
| columns: [ | ||
| { | ||
| caption: 'Trademark', | ||
| width: 220, | ||
| cellTemplate: (container, options) => { | ||
| const vehicle = options.data; | ||
| const imageWrapper = createTrademarkTemplate(vehicle); | ||
| container.append(imageWrapper); | ||
| }, | ||
| }, | ||
| { | ||
| dataField: 'Price', | ||
| format: 'currency', | ||
| width: 100, | ||
| }, | ||
| { | ||
| caption: 'Category', | ||
|
dmlvr marked this conversation as resolved.
|
||
| cellTemplate: (container, options) => { | ||
| const category = options.data; | ||
| const categoryWrapper = createCategoryTemplate(category); | ||
| container.append(categoryWrapper); | ||
| }, | ||
| minWidth: 180, | ||
| }, | ||
| { | ||
| dataField: 'Modification', | ||
| width: 180, | ||
| }, | ||
| { | ||
| dataField: 'Horsepower', | ||
| width: 140, | ||
| }, | ||
| { | ||
| dataField: 'BodyStyleName', | ||
| caption: 'Body Style', | ||
| width: 180, | ||
| }, | ||
| { | ||
| name: 'AI column', | ||
|
dmlvr marked this conversation as resolved.
|
||
| caption: 'AI Column', | ||
| type: 'ai', | ||
| ai: { | ||
| prompt: 'Identify the country where this vehicle model is originally manufactured or developed, based on its brand, model, and specifications.', | ||
| mode: 'auto', | ||
| }, | ||
| width: 200, | ||
| fixed: true, | ||
| fixedPosition: 'right', | ||
| cssClass: 'ai__cell', | ||
| }, | ||
| ], | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,52 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #gridContainer .ai__cell { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| background-color: var(--dx-datagrid-row-alternation-bg); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .trademark__wrapper { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| display: flex; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| align-items: center; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gap: 8px; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .trademark__img-wrapper { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| width: 40px; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| height: 40px; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| border: var(--dx-border-width) solid var(--dx-color-border); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| border-radius: var(--dx-border-radius); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| cursor: pointer; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .trademark__img-wrapper img { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| width: 100%; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| height: 100%; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| object-fit: cover; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| object-position: center; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| border-radius: var(--dx-border-radius); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .trademark__text-wrapper { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| width: calc(100% - 48px); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .trademark__text { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| margin: 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| padding: 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| white-space: nowrap; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| overflow: hidden; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| text-overflow: ellipsis; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .trademark__text--title { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| font-weight: 600; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .trademark__text--subtitle { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| font-weight: 400; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .category__wrapper { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| display: inline-block; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| padding: 2px 8px; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| border-radius: 24px; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| background-color: var(--dx-color-separator); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1
to
+52
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #gridContainer .ai__cell { | |
| background-color: var(--dx-color-main-bg); | |
| } | |
| .trademark__wrapper { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .trademark__img-wrapper { | |
| width: 40px; | |
| height: 40px; | |
| border: var(--dx-border-width) solid var(--dx-color-border); | |
| border-radius: var(--dx-border-radius); | |
| cursor: pointer; | |
| } | |
| .trademark__img-wrapper img { | |
| width: 100%; | |
| height: 100%; | |
| object-fit: cover; | |
| object-position: center; | |
| border-radius: var(--dx-border-radius); | |
| } | |
| .trademark__text-wrapper { | |
| width: calc(100% - 48px); | |
| } | |
| .trademark__text { | |
| margin: 0; | |
| padding: 0; | |
| white-space: nowrap; | |
| overflow: hidden; | |
| text-overflow: ellipsis; | |
| } | |
| .trademark__text--title { | |
| font-weight: 600; | |
| } | |
| .trademark__text--subtitle { | |
| font-weight: 400; | |
| } | |
| .category__wrapper { | |
| display: inline-block; | |
| padding: 2px 8px; | |
| border-radius: 24px; | |
| background-color: var(--dx-color-separator); | |
| } | |
| @import "../../common/ai-column-shared.css"; |
Uh oh!
There was an error while loading. Please reload this page.