|
|
|
const options = { |
|
}; |
|
|
|
(function(parentNode, options) { |
|
|
|
function Model(options, value) { |
|
this.options = options; |
|
this.value = value; |
|
} |
|
|
|
Model.prototype.setOptions = function setOptions(options) { |
|
this.options = options; |
|
} |
|
|
|
Model.prototype.setValue = function setValue(value) { |
|
this.value = value; |
|
} |
|
|
|
Model.prototype.getValue = function getValue(value) { |
|
return this.value; |
|
} |
|
|
|
function View() { |
|
this.createNode(); |
|
} |
|
|
|
View.prototype.createNode = function createNode() { |
|
const baseNode = document.createElement('div'); |
|
baseNode.className = 'autocomplite'; |
|
|
|
const label = document.createElement('label'); |
|
label.textContent = 'Autocomplite: '; |
|
|
|
this.input = document.createElement('input'); |
|
|
|
const loader = document.createElement('div'); |
|
loader.className = 'loader hide'; |
|
|
|
baseNode.appendChild(label); |
|
baseNode.appendChild(this.input); |
|
baseNode.appendChild(loader); |
|
|
|
this.node = baseNode; |
|
}; |
|
|
|
View.prototype.bindEventListenersForInput = function bindEventListenersForInput(eventMap) { |
|
eventMap.forEach((event) => { |
|
this.input.addEventListener(event.type, event.handler); |
|
}); |
|
}; |
|
|
|
View.prototype.unbindEventListenersForInput = function unbindEventListenersForInput(eventMap) { |
|
eventMap.forEach((event) => { |
|
this.input.removeEventListener(event.type, event.handler); |
|
}); |
|
}; |
|
|
|
View.prototype.getNode = function getNode() { |
|
return this.node; |
|
}; |
|
|
|
View.prototype.showAutocomplite = function showAutocomplite(options) { |
|
// create ul and append to div element |
|
}; |
|
|
|
View.prototype.hideAutocomplite = function hideAutocomplite(options) { |
|
// remove ui element |
|
}; |
|
|
|
function AutocompliteController(parentNode, options) { |
|
this.parentNode = parentNode; |
|
this.options = options; |
|
this.initModel(); |
|
this.initView(); |
|
}; |
|
|
|
AutocompliteController.prototype.destroy = function destroy() { |
|
delete this.parentNode; |
|
delete this.options; |
|
this.destroyView(); |
|
this.destroyModel(); |
|
}; |
|
|
|
AutocompliteController.prototype.destroyView = function destroyView(options) { |
|
this.parentNode.removeChild(this.view.getNode()); |
|
this.view.unbindEventListenersForInput(this.getInputEventsMap()); |
|
delete this.view; |
|
}; |
|
|
|
AutocompliteController.prototype.destroyModel = function destroyModel(options) { |
|
delete this.model; |
|
}; |
|
|
|
AutocompliteController.prototype.initModel = function initModel(options) { |
|
this.model = new Model(this.options.options, this.options.value); |
|
}; |
|
|
|
AutocompliteController.prototype.initView = function initView(options) { |
|
this.view = new View(); |
|
this.view.bindEventListenersForInput(this.getInputEventsMap()); |
|
this.parentNode.appendChild(this.view.getNode()); |
|
}; |
|
|
|
AutocompliteController.prototype.showAutocomplite = function showAutocomplite(matches) { |
|
this.view.showAutocomplite(matches); |
|
this.view.bindAutocompliteEvent(this.getAutocompliteEvent()); |
|
}; |
|
|
|
AutocompliteController.prototype.hideAutocomplite = function showAutocomplite() { |
|
this.view.unbindAutocompliteEvent(this.getAutocompliteEvent()); |
|
this.view.hideAutocomplite(); |
|
}; |
|
|
|
AutocompliteController.prototype.getAutocompliteEvent = function getAutocompliteEvent() { |
|
return [ |
|
{type: 'click', (event) => { |
|
this.model.setValue(event.currentTarget.value); |
|
this.hideAutocomplite(); |
|
}} |
|
]; |
|
}; |
|
|
|
AutocompliteController.prototype.onInputChange = function onInputChange(event) { |
|
const matches = this.findMatches(event); |
|
this.showAutocomplite(matches); |
|
}; |
|
|
|
AutocompliteController.prototype.onAutocompliteChange = (function (onAutocompliteChange) { |
|
if (onAutocompliteChange) { |
|
return (event) => { |
|
this.showSpinner(); |
|
onAutocompliteChange(event).then((options) => { |
|
this.model.setOptions(options); |
|
this.showAutocomplite(options); |
|
this.hideSpinner(); |
|
}).catch((error) => { |
|
this.hideSpinner(); |
|
if (typeof error === 'object') { |
|
error = JSON.stringify(error); |
|
} |
|
throw new Error(`onAutocompliteChange end work with error: ${error}`); |
|
}); |
|
} |
|
} else { |
|
return (event) => this.onInputChange(event); |
|
} |
|
})(options.onAutocompliteChange); |
|
|
|
AutocompliteController.prototype.getInputEventsMap = function getInputEventsMap() { |
|
return [ |
|
{type: 'input', handler: (...args) => this.onAutocompliteChange(...args)}, |
|
{type: 'blur', handler: () => { |
|
this.autocompliteDestroy(); |
|
this.options.onChange(); |
|
}} |
|
]; |
|
}; |
|
|
|
const autocomplite = new AutocompliteController(parentNode, options); |
|
|
|
return { |
|
setOptions: (options) autocomolite.model.setOptions(options), |
|
getValue : () => autocomolite.model.getValue() |
|
}; |
|
})(document.body, options); |
|
|
|
(function(cssLink){ |
|
var cssElement = document.createElement("link"); |
|
cssElement.rel = "stylesheet"; |
|
cssElement.href = cssLink; |
|
document.getElementsByTagName("head")[0].appendChild(cssElement); |
|
})('./styles.css'); |