feat(requests): don't spam requests, fixed results dropdown, don't request if there is no url

This commit is contained in:
Benjamin Wegener
2021-10-23 12:43:53 +02:00
parent b34642cd5e
commit 27e267f4ee
2 changed files with 102 additions and 47 deletions

View File

@@ -66,7 +66,6 @@
flex: 1;
background: white;
padding: $padding;
overflow-x: auto;
white-space: nowrap;
border: $border-default-transparent;
border-radius: $border-radius * .8;
@@ -116,7 +115,16 @@
}
&__value {
@extend .simplecomplete__input-field;
border: $border-default-transparent;
border-radius: $border-radius * .8;
background: white;
flex: 1;
flex-flow: row wrap;
white-space: normal;
margin: .125em;
padding: 0;
padding-bottom: $spacer * .25;
outline: none;
&:not(.hide) {
& ~ .simplecomplete__input {
display: none;
@@ -136,13 +144,7 @@
background: $gray;
color: $black;
&:first-child {
margin-left: -.25em;
}
&:last-child {
margin-right: -.25em;
}
margin: $spacer * .25 $spacer * .25 0;
}
> .empty-item {
@@ -154,10 +156,22 @@
&.is-empty {
color: $text-secondary;
}
@media screen and (max-width: 992px) {
border-radius: 0;
}
}
&:not(.is-select) {
.simplecomplete__value.is-empty {
padding: $spacer * .75 $spacer * .5;
}
}
&.is-multiple, &.is-blankable {
.simplecomplete__value > .selected-option {
.simplecomplete__value {
position: relative;
> .selected-option {
&:after {
content: "\00D7";
display: inline;
@@ -165,6 +179,7 @@
color: darken($text-secondary, 20);
}
}
}
.simplecomplete__input-cancel {
display: block;
@@ -172,6 +187,7 @@
}
&__results {
display: none;
position: absolute;
top: 100%;
left: 0;
@@ -286,6 +302,24 @@
display: none;
}
&.is-select:not(.active) {
display: flex;
flex-flow: row nowrap;
align-items: center;
&:after {
content: "";
display: inline-block;
border: solid .25em $black;
border-top-color: transparent;
border-right-color: transparent;
transform: translateY(-40%) rotate(-45deg);
width: 0;
height: 0;
margin: 0 1em;
}
}
&.is-blankable:not(.active) {
.simplecomplete__value > .selected-option {
&:after {
@@ -302,7 +336,7 @@
&.active.is-select, &:not(.is-select) {
.simplecomplete__input-field {
padding: $spacer * 1.05;
padding: $spacer * .85;
}
}
@@ -379,9 +413,9 @@
}
}
&:not(.has-results) {
&.active {
.simplecomplete__results {
display: none;
display: block;
}
}
}

View File

@@ -148,8 +148,9 @@ export default class SimpleComplete {
}
onInput (e) {
if (this.launchedRequest) {
if (this.launchedRequest !== null) {
window.clearTimeout(this.launchedRequest)
this.launchedRequest = null
}
switch (e.keyCode) {
@@ -161,18 +162,21 @@ export default class SimpleComplete {
}
this.query = e.target.textContent.trim()
if (this.options.url) {
this.launchedRequest = window.setTimeout(this.onSend.bind(this), this.options.delay || 300)
console.log(this.options.url)
}
this.onResults()
}
finishRequest (xhr) {
this.wrapper.classList.remove('is-busy')
this.queued = false
}
sendRequest (_cb = null) {
sendRequest () {
let headers = {
Accept: 'application/json',
'Cache-Control': 'no-cache',
'X-Requested-With': 'XMLHttpRequest',
...(this.options.headers || {})
}
@@ -252,14 +256,17 @@ export default class SimpleComplete {
if (!(200 <= xhr.status && xhr.status < 300)) {
this.onError('simplecomplete.errors.xhr_wrong_status')
} else {
let data =
this.options.onResponse (response, xhr)
this.onResults(response.data || response)
}
}
onSend (e = null) {
if(this.launchedRequest !== null) {
window.clearTimeout(this.launchedRequest)
this.launchedRequest = null
}
if (!this.query || (this.options.minLength > 0 && this.query.length < this.options.minLength)) {
this.onError('simplecomplete.errors.min-length')
} else {
@@ -267,18 +274,7 @@ export default class SimpleComplete {
this.queued = true
} else if (this.options.url) {
this.wrapper.classList.add('is-busy')
this.sendRequest((xhr) => {
console.log('DONE', xhr)
})
/*window.setTimeout(() => {
this.wrapper.classList.remove('is-busy')
if(this.queued) {
this.queued = false
this.onSend ()
}
}, 3000)*/
this.sendRequest()
}
}
}
@@ -335,7 +331,7 @@ export default class SimpleComplete {
updateLabel () {
this.currentValue.classList.remove('is-empty')
this.currentValue.innerHTML = ''
if (this.isMultiple() || this.isSelectElement()) {
if (this.isMultiple() && this.isSelectElement()) {
let _opts = Array.from(this.element.selectedOptions)
for (let _key in _opts) {
let o = _opts[_key]
@@ -360,7 +356,17 @@ export default class SimpleComplete {
}
if(!this.currentValue.childNodes.length) {
let placeholder = this.element.value || this.element.getAttribute('placeholder') || this.element.dataset.placeholder || this.options.placeholder || 'Search'
if (this.element.value) {
let badge = SimpleComplete.createElement('SPAN', {
classes: 'selected-option'
})
let label = this.results.filter(item => item.value == this.element.value).map(item => item.label || item.value).shift()
badge.textContent = label || this.element.value
this.currentValue.appendChild(badge)
} else {
let placeholder = this.element.getAttribute('placeholder') || this.element.dataset.placeholder || this.options.placeholder || 'Search'
if (this.isSelectElement()) {
let badge = SimpleComplete.createElement('SPAN', {
classes: 'empty-item'
@@ -378,6 +384,7 @@ export default class SimpleComplete {
}
}
}
}
onError (key) {
console.log(key)
@@ -484,14 +491,14 @@ export default class SimpleComplete {
if(this.results && this.resultsList) {
this.resultsList.innerHTML = ''
if (this.isSelectElement ()) {
[...this.element.options].forEach(option => {
[...this.element.options].filter(this.filterResults.bind(this)).forEach(option => {
this.resultsList.appendChild(this.renderOption({
value: option.value,
label: option.textContent
}))
})
} else {
this.results.forEach( res => this.resultsList.appendChild(this.renderOption(res)) )
this.results.filter(this.filterResults.bind(this)).forEach( res => this.resultsList.appendChild(this.renderOption(res)) )
}
if (!this.resultsList.childNodes.length) {
@@ -502,6 +509,9 @@ export default class SimpleComplete {
emptyNode.textContent = this.options.emptyText || 'No results'
this.resultsList.appendChild(emptyNode)
this.wrapper.classList.add('has-results')
} else {
this.wrapper.classList.remove('has-results')
}
}
} catch(err) {
@@ -509,6 +519,17 @@ export default class SimpleComplete {
}
}
filterResults (option) {
if(!this.query) {
return true
}
let regexp = new RegExp(this.query,'gi')
let label = option.label || option.textContent
let check = label.matchAll(regexp)
return [...check].length > 0
}
isSelected (_val) {
let opts = Array.from(this.element.selectedOptions || [])
for (let _index = 0; _index < opts.length; _index++) {