Skip to content

Commit

Permalink
feat(common): replace jQueryUI Autocomplete with Kradeen Autocomplete (
Browse files Browse the repository at this point in the history
…#752)

* feat(common): replace jQueryUI Autocomplete with Kradeen Autocomplete
- first step in order to remove jQueryUI
  • Loading branch information
ghiscoding committed Aug 22, 2022
1 parent 9101fff commit 991d29c
Show file tree
Hide file tree
Showing 36 changed files with 1,161 additions and 1,190 deletions.
50 changes: 33 additions & 17 deletions examples/webpack-demo-vanilla-bundle/src/examples/example04.ts
@@ -1,5 +1,5 @@
import {
AutocompleteOption,
AutocompleterOption,
BindingEventService,
Column,
ColumnEditorDualInput,
Expand All @@ -14,11 +14,16 @@ import {
} from '@slickgrid-universal/common';
import { ExcelExportService } from '@slickgrid-universal/excel-export';
import { Slicker, SlickVanillaGridBundle } from '@slickgrid-universal/vanilla-bundle';
import { fetch } from 'whatwg-fetch';

import { ExampleGridOptions } from './example-grid-options';
import './example02.scss';
import './example04.scss';

const URL_COUNTRIES_COLLECTION = 'assets/data/countries.json';
const URL_COUNTRY_NAMES_COLLECTION = 'assets/data/country_names.json';

// you can create custom validator to pass to an inline editor
const myCustomTitleValidator = (value, _args) => {
const myCustomTitleValidator = (value) => {
if (value === null || value === undefined || !value.length) {
return { valid: false, msg: 'This is a required field' };
} else if (!/^Task\s\d+$/.test(value)) {
Expand Down Expand Up @@ -221,54 +226,65 @@ export class Example4 {
filterable: true,
sortable: true,
minWidth: 100,
// formatter: (_, __, val) => typeof val === 'string' ? val : val.name,
// editor: {
// model: Editors.autocompleter,
// placeholder: '🔎︎ search country',
// customStructure: { label: 'name', value: 'code' },
// // collection: require('./data/countries.json'),
// collectionAsync: fetch(URL_COUNTRIES_COLLECTION),
// // enableRenderHtml: true,
// // collection: [{ code: true, name: 'True', labelPrefix: `<i class="mdi mdi-pin-outline"></i> ` }, { code: false, name: 'False', labelSuffix: '<i class="mdi mdi-close"></i>' }],
// // editorOptions: { minLength: 1 }
// },
editor: {
model: Editors.autoComplete,
model: Editors.autocompleter,
placeholder: '🔎︎ search city',

// We can use the autocomplete through 3 ways "collection", "collectionAsync" or with your own autocomplete options
// use your own autocomplete options, instead of $.ajax, use HttpClient or FetchClient
// here we use $.ajax just because I'm not sure how to configure HttpClient with JSONP and CORS
editorOptions: {
minLength: 3,
forceUserInput: true,
source: (request, response) => {
fetch: (searchText, updateCallback) => {
$.ajax({
url: 'http://gd.geobytes.com/AutoCompleteCity',
dataType: 'jsonp',
data: {
q: request.term
q: searchText
},
success: (data) => {
response(data);
updateCallback(data);
}
});
}
} as AutocompleteOption,
},
} as Partial<AutocompleterOption>,
},
filter: {
model: Filters.autoComplete,
model: Filters.autocompleter,
// placeholder: '🔎︎ search city',
// customStructure: { label: 'name', value: 'code' },

// We can use the autocomplete through 3 ways "collection", "collectionAsync" or with your own autocomplete options
// collectionAsync: this.httpFetch.fetch(URL_COUNTRIES_COLLECTION),
// collectionAsync: fetch(URL_COUNTRIES_COLLECTION),

// OR use your own autocomplete options, instead of $.ajax, use HttpClient or FetchClient
// here we use $.ajax just because I'm not sure how to configure HttpClient with JSONP and CORS
filterOptions: {
minLength: 3,
source: (request, response) => {
fetch: (searchText, updateCallback) => {
$.ajax({
url: 'http://gd.geobytes.com/AutoCompleteCity',
dataType: 'jsonp',
data: {
q: request.term
q: searchText
},
success: (data) => {
response(data);
updateCallback(data);
}
});
}
} as AutocompleteOption,
},
} as Partial<AutocompleterOption>,
}
},
{
Expand Down
23 changes: 11 additions & 12 deletions examples/webpack-demo-vanilla-bundle/src/examples/example11.ts
@@ -1,5 +1,5 @@
import {
AutocompleteOption,
AutocompleterOption,
BindingEventService,
DOMEvent,
Column,
Expand Down Expand Up @@ -196,17 +196,16 @@ export class Example11 {
type: FieldType.object,
sortComparer: SortComparers.objectString,
editor: {
model: Editors.autoComplete,
model: Editors.autocompleter,
alwaysSaveOnEnterKey: true,
massUpdate: true,
// example with a Remote API call
editorOptions: {
openSearchListOnFocus: true,
showOnFocus: true,
minLength: 1,
source: (request, response) => {
// const items = require('c://TEMP/items.json');
fetch: (searchText, updateCallback) => {
const products = this.mockProducts();
response(products.filter(product => product.itemName.toLowerCase().includes(request.term.toLowerCase())));
updateCallback(products.filter(product => product.itemName.toLowerCase().includes(searchText.toLowerCase())));
},
renderItem: {
// layout: 'twoRows',
Expand All @@ -215,7 +214,7 @@ export class Example11 {
layout: 'fourCorners',
templateCallback: (item: any) => this.renderItemCallbackWith4Corners(item),
},
} as AutocompleteOption,
} as Partial<AutocompleterOption>,
},
filter: {
model: Filters.inputText,
Expand All @@ -236,17 +235,17 @@ export class Example11 {
sortable: true,
minWidth: 100,
editor: {
model: Editors.autoComplete,
model: Editors.autocompleter,
alwaysSaveOnEnterKey: true,
massUpdate: true,
editorOptions: {
minLength: 1,
source: (request, response) => {
fetch: (searchText, updateCallback) => {
const countries: any[] = require('./data/countries.json');
const foundCountries = countries.filter((country) => country.name.toLowerCase().includes(request.term.toLowerCase()));
response(foundCountries.map(item => ({ label: item.name, value: item.code, })));
const foundCountries = countries.filter((country) => country.name.toLowerCase().includes(searchText.toLowerCase()));
updateCallback(foundCountries.map(item => ({ label: item.name, value: item.code, })));
},
},
} as Partial<AutocompleterOption>,
},
filter: {
model: Filters.inputText,
Expand Down
69 changes: 33 additions & 36 deletions examples/webpack-demo-vanilla-bundle/src/examples/example12.ts
@@ -1,6 +1,6 @@
// import { Instance as FlatpickrInstance } from 'flatpickr/dist/types/instance';
import {
AutocompleteOption,
AutocompleterOption,
BindingEventService,
Column,
CompositeEditorModalType,
Expand Down Expand Up @@ -291,17 +291,16 @@ export class Example12 {
type: FieldType.object,
sortComparer: SortComparers.objectString,
editor: {
model: Editors.autoComplete,
model: Editors.autocompleter,
alwaysSaveOnEnterKey: true,
massUpdate: true,

// example with a Remote API call
editorOptions: {
minLength: 1,
source: (request, response) => {
// const items = require('c://TEMP/items.json');
fetch: (searchTerm, callback) => {
const products = this.mockProducts();
response(products.filter(product => product.itemName.toLowerCase().includes(request.term.toLowerCase())));
callback(products.filter(product => product.itemName.toLowerCase().includes(searchTerm.toLowerCase())));
},
renderItem: {
// layout: 'twoRows',
Expand All @@ -310,11 +309,11 @@ export class Example12 {
layout: 'fourCorners',
templateCallback: (item: any) => this.renderItemCallbackWith4Corners(item),
},
} as AutocompleteOption,
} as Partial<AutocompleterOption>,
},
filter: {
model: Filters.inputText,
// placeholder: '🔎︎ search city',
// placeholder: '🔎︎ search product',
type: FieldType.string,
queryField: 'product.itemName',
}
Expand All @@ -331,19 +330,18 @@ export class Example12 {
sortable: true,
minWidth: 100,
editor: {
model: Editors.autoComplete,
model: Editors.autocompleter,
alwaysSaveOnEnterKey: true,
massUpdate: true,
editorOptions: {
minLength: 0,
openSearchListOnFocus: false,
// onSelect: (e, ui, row, cell, column, dataContext) => console.log(ui, column, dataContext),
source: (request, response) => {
showOnFocus: false,
fetch: (searchText, updateCallback) => {
const countries: any[] = require('./data/countries.json');
const foundCountries = countries.filter((country) => country.name.toLowerCase().includes(request.term.toLowerCase()));
response(foundCountries.map(item => ({ label: item.name, value: item.code, })));
const foundCountries = countries.filter((country) => country.name.toLowerCase().includes(searchText.toLowerCase()));
updateCallback(foundCountries.map(item => ({ label: item.name, value: item.code, })));
},
},
} as Partial<AutocompleterOption>,
},
filter: {
model: Filters.inputText,
Expand Down Expand Up @@ -398,13 +396,13 @@ export class Example12 {
autoFixResizeRequiredGoodCount: 1,
datasetIdPropertyName: 'id',
eventNamingStyle: EventNamingStyle.lowerCase,
editable: true,
autoAddCustomEditorFormatter: customEditableInputFormatter,
enableAddRow: true, // <-- this flag is required to work with the (create & clone) modal types
enableCellNavigation: true,
asyncEditorLoading: false,
autoEdit: true,
autoCommitEdit: true,
editable: true,
autoResize: {
container: '.demo-container',
},
Expand Down Expand Up @@ -605,7 +603,6 @@ export class Example12 {
/*
if (columnDef.id === 'completed') {
this.compositeEditorInstance.changeFormEditorOption('percentComplete', 'filter', true); // multiple-select.js, show filter in dropdown
this.compositeEditorInstance.changeFormEditorOption('product', 'minLength', 3); // autocomplete, change minLength char to type
this.compositeEditorInstance.changeFormEditorOption('finish', 'minDate', 'today'); // flatpickr, change minDate to today
}
*/
Expand Down Expand Up @@ -889,33 +886,33 @@ export class Example12 {
<span class="mdi ${item.itemTypeName === 'I' ? 'mdi-information-outline' : 'mdi-content-copy'} mdi-14px"></span>
${item.itemName}
</span>
<div>
</div>
<div>
<div class="autocomplete-bottom-left">${item.itemNameTranslated}</div>
</div>`;
}

renderItemCallbackWith4Corners(item: any): string {
return `<div class="autocomplete-container-list">
<div class="autocomplete-left">
<!--<img src="http://i.stack.imgur.com/pC1Tv.jpg" width="50" />-->
<span class="mdi ${item.icon} mdi-26px"></span>
</div>
<div>
<span class="autocomplete-top-left">
<span class="mdi ${item.itemTypeName === 'I' ? 'mdi-information-outline' : 'mdi-content-copy'} mdi-14px"></span>
${item.itemName}
</span>
<span class="autocomplete-top-right">${formatNumber(item.listPrice, 2, 2, false, '$')}</span>
<div>
</div>
<div>
<div class="autocomplete-bottom-left">${item.itemNameTranslated}</div>
<span class="autocomplete-bottom-right">Type: <b>${item.itemTypeName === 'I' ? 'Item' : item.itemTypeName === 'C' ? 'PdCat' : 'Cat'}</b></span>
</div>`;
}

renderItemCallbackWith4Corners(item: any): string {
return `<div class="autocomplete-container-list">
<div class="autocomplete-left">
<!--<img src="http://i.stack.imgur.com/pC1Tv.jpg" width="50" />-->
<span class="mdi ${item.icon} mdi-26px"></span>
</div>
<div>
<span class="autocomplete-top-left">
<span class="mdi ${item.itemTypeName === 'I' ? 'mdi-information-outline' : 'mdi-content-copy'} mdi-14px"></span>
${item.itemName}
</span>
<span class="autocomplete-top-right">${formatNumber(item.listPrice, 2, 2, false, '$')}</span>
<div>
</div>
<div>
<div class="autocomplete-bottom-left">${item.itemNameTranslated}</div>
<span class="autocomplete-bottom-right">Type: <b>${item.itemTypeName === 'I' ? 'Item' : item.itemTypeName === 'C' ? 'PdCat' : 'Cat'}</b></span>
</div>`;
}

openCompositeModal(modalType: CompositeEditorModalType, openDelay = 0) {
// open the editor modal and we can also provide a header title with optional parsing pulled from the dataContext, via template {{ }}
// for example {{title}} => display the item title, or even complex object works {{product.itemName}} => display item product name
Expand Down
23 changes: 11 additions & 12 deletions examples/webpack-demo-vanilla-bundle/src/examples/example14.ts
@@ -1,5 +1,5 @@
import {
AutocompleteOption,
AutocompleterOption,
BindingEventService,
Column,
Editors,
Expand Down Expand Up @@ -249,16 +249,15 @@ export class Example14 {
type: FieldType.object,
sortComparer: SortComparers.objectString,
editor: {
model: Editors.autoComplete,
model: Editors.autocompleter,
alwaysSaveOnEnterKey: true,

// example with a Remote API call
editorOptions: {
minLength: 1,
source: (request, response) => {
// const items = require('c://TEMP/items.json');
fetch: (searchText, updateCallback) => {
const products = this.mockProducts();
response(products.filter(product => product.itemName.toLowerCase().includes(request.term.toLowerCase())));
updateCallback(products.filter(product => product.itemName.toLowerCase().includes(searchText.toLowerCase())));
},
renderItem: {
// layout: 'twoRows',
Expand All @@ -267,7 +266,7 @@ export class Example14 {
layout: 'fourCorners',
templateCallback: (item: any) => this.renderItemCallbackWith4Corners(item),
},
} as AutocompleteOption,
} as Partial<AutocompleterOption>,
},
filter: {
model: Filters.inputText,
Expand All @@ -288,17 +287,17 @@ export class Example14 {
sortable: true,
minWidth: 100,
editor: {
model: Editors.autoComplete,
model: Editors.autocompleter,
alwaysSaveOnEnterKey: true,
editorOptions: {
minLength: 0,
openSearchListOnFocus: false,
source: (request, response) => {
showOnFocus: false,
fetch: (searchText, updateCallback) => {
const countries: any[] = require('./data/countries.json');
const foundCountries = countries.filter((country) => country.name.toLowerCase().includes(request.term.toLowerCase()));
response(foundCountries.map(item => ({ label: item.name, value: item.code, })));
const foundCountries = countries.filter((country) => country.name.toLowerCase().includes(searchText.toLowerCase()));
updateCallback(foundCountries.map(item => ({ label: item.name, value: item.code, })));
},
},
} as Partial<AutocompleterOption>,
},
filter: {
model: Filters.inputText,
Expand Down
1 change: 1 addition & 0 deletions packages/common/package.json
Expand Up @@ -73,6 +73,7 @@
"dependencies": {
"@slickgrid-universal/event-pub-sub": "workspace:~",
"@slickgrid-universal/utils": "workspace:~",
"autocompleter": "^6.1.3",
"dequal": "^2.0.3",
"dompurify": "^2.3.10",
"flatpickr": "^4.6.13",
Expand Down

0 comments on commit 991d29c

Please sign in to comment.