Skip to content

Commit

Permalink
[MAJOR] Remove jQuery dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
core23 committed Nov 16, 2019
1 parent a07b255 commit 72a5410
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 89 deletions.
119 changes: 119 additions & 0 deletions assets/js/Autocomplete.js
@@ -0,0 +1,119 @@
import 'awesomplete';
import 'awesomplete/awesomplete.css'

export default class Autocomplete {
/**
* @param {Element|string} element
* @param {Object=} options
*
* @constructor
*/
constructor(element, options) {
if (typeof element === 'string') {
this.element = document.querySelector(element);
} else {
this.element = element;
}

if (!this.element) {
return;
}

const defaults = {
ajaxRoute: '',
minChars: 3,
};

this.settings = {...defaults, ...options};

const self = this;

this.shadowElement = this.createShadowElement(element);

const autocomplete = new Awesomplete(element, {
minChars: self.settings.minChars,
list: [],

replace: function (suggestion) {
self.element.value = suggestion.label;
self.shadowElement.value = suggestion.value;
},
});

element.addEventListener('input', async function () {
autocomplete.list = await self.fetchResult(element.value);

if (autocomplete.list.length === 0) {
self.shadowElement.value = '0';
}

autocomplete.evaluate();
autocomplete.open();
});
}

createShadowElement(element) {
const shadowInput = document.createElement('input');
shadowInput.setAttribute("type", "hidden");
shadowInput.setAttribute("name", element.name);

element.parentNode.insertBefore(shadowInput, element.nextSibling);
element.setAttribute("name", element.name + '_autocomplete');

return shadowInput;
}

async fetchResult(query) {
if (!query || query.length < this.settings.minChars) {
return [];
}

return await this.sendRequest(query)
.then(function (result) {
return JSON.parse(result).map(function (item) {
return {
value: item.id,
label: item.value
}
});
}).catch(function (err) {
console.error(err)
});
}

async sendRequest(query) {
const self = this;

const xhr = new XMLHttpRequest();
return new Promise(function (resolve, reject) {
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 300) {
reject("Error, status code = " + xhr.status)
} else {
resolve(xhr.responseText);
}
}
};
xhr.open('get', self.settings.ajaxRoute + '?q=' + query, true);
xhr.send();
});
}
}

// Bind
const weakMap = new WeakMap();

document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('[data-autocomplete]').forEach((element) => {
if (weakMap.has(element) && weakMap.get(element).autocomplete) {
return;
}

const options = JSON.parse(element.getAttribute('data-autocomplete') || {});

weakMap.set(element, {
autocomplete: new Autocomplete(element, options)
});
});
});
84 changes: 0 additions & 84 deletions assets/js/Select2Autocomplete.js

This file was deleted.

4 changes: 3 additions & 1 deletion assets/npm.js
@@ -1 +1,3 @@
import './js/Select2Autocomplete';
import Autocomplete from './js/Autocomplete';

export default Autocomplete
3 changes: 1 addition & 2 deletions package.json
Expand Up @@ -4,8 +4,7 @@
"homepage": "https://core23.de",
"author": "Christian Gripp <mail@core23.de>",
"dependencies": {
"select2": "^3.5.1",
"select2-bootstrap-css": "^1.4"
"awesomplete": "^1.1"
},
"main": "assets/npm.js",
"files": [
Expand Down
4 changes: 2 additions & 2 deletions src/Bridge/Symfony/Resources/views/Form/widgets.html.twig
Expand Up @@ -113,10 +113,10 @@

{% block core23_autocomplete_widget %}
{% set attr = attr|merge({
'data-select2-autocomplete': {
'data-autocomplete': {
'ajaxRoute': path(route_name),
'text': text|default(empty_value|trans({}, translation_domain))
}|json_encode,
'placeholder': text|default(empty_value|trans({}, translation_domain))
}) %}
{{ block('form_widget') }}
{% endblock %}

0 comments on commit 72a5410

Please sign in to comment.