feat(requests): don't spam requests, fixed results dropdown, don't request if there is no url
This commit is contained in:
@@ -66,7 +66,6 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
background: white;
|
background: white;
|
||||||
padding: $padding;
|
padding: $padding;
|
||||||
overflow-x: auto;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
border: $border-default-transparent;
|
border: $border-default-transparent;
|
||||||
border-radius: $border-radius * .8;
|
border-radius: $border-radius * .8;
|
||||||
@@ -116,7 +115,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&__value {
|
&__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) {
|
&:not(.hide) {
|
||||||
& ~ .simplecomplete__input {
|
& ~ .simplecomplete__input {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -136,13 +144,7 @@
|
|||||||
background: $gray;
|
background: $gray;
|
||||||
color: $black;
|
color: $black;
|
||||||
|
|
||||||
&:first-child {
|
margin: $spacer * .25 $spacer * .25 0;
|
||||||
margin-left: -.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-right: -.25em;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
> .empty-item {
|
> .empty-item {
|
||||||
@@ -154,10 +156,22 @@
|
|||||||
&.is-empty {
|
&.is-empty {
|
||||||
color: $text-secondary;
|
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 {
|
&.is-multiple, &.is-blankable {
|
||||||
.simplecomplete__value > .selected-option {
|
.simplecomplete__value {
|
||||||
|
position: relative;
|
||||||
|
> .selected-option {
|
||||||
&:after {
|
&:after {
|
||||||
content: "\00D7";
|
content: "\00D7";
|
||||||
display: inline;
|
display: inline;
|
||||||
@@ -165,6 +179,7 @@
|
|||||||
color: darken($text-secondary, 20);
|
color: darken($text-secondary, 20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.simplecomplete__input-cancel {
|
.simplecomplete__input-cancel {
|
||||||
display: block;
|
display: block;
|
||||||
@@ -172,6 +187,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&__results {
|
&__results {
|
||||||
|
display: none;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 100%;
|
top: 100%;
|
||||||
left: 0;
|
left: 0;
|
||||||
@@ -286,6 +302,24 @@
|
|||||||
display: none;
|
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) {
|
&.is-blankable:not(.active) {
|
||||||
.simplecomplete__value > .selected-option {
|
.simplecomplete__value > .selected-option {
|
||||||
&:after {
|
&:after {
|
||||||
@@ -302,7 +336,7 @@
|
|||||||
|
|
||||||
&.active.is-select, &:not(.is-select) {
|
&.active.is-select, &:not(.is-select) {
|
||||||
.simplecomplete__input-field {
|
.simplecomplete__input-field {
|
||||||
padding: $spacer * 1.05;
|
padding: $spacer * .85;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,9 +413,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.has-results) {
|
&.active {
|
||||||
.simplecomplete__results {
|
.simplecomplete__results {
|
||||||
display: none;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,8 +148,9 @@ export default class SimpleComplete {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onInput (e) {
|
onInput (e) {
|
||||||
if (this.launchedRequest) {
|
if (this.launchedRequest !== null) {
|
||||||
window.clearTimeout(this.launchedRequest)
|
window.clearTimeout(this.launchedRequest)
|
||||||
|
this.launchedRequest = null
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (e.keyCode) {
|
switch (e.keyCode) {
|
||||||
@@ -161,18 +162,21 @@ export default class SimpleComplete {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.query = e.target.textContent.trim()
|
this.query = e.target.textContent.trim()
|
||||||
|
if (this.options.url) {
|
||||||
this.launchedRequest = window.setTimeout(this.onSend.bind(this), this.options.delay || 300)
|
this.launchedRequest = window.setTimeout(this.onSend.bind(this), this.options.delay || 300)
|
||||||
|
console.log(this.options.url)
|
||||||
|
}
|
||||||
this.onResults()
|
this.onResults()
|
||||||
}
|
}
|
||||||
|
|
||||||
finishRequest (xhr) {
|
finishRequest (xhr) {
|
||||||
this.wrapper.classList.remove('is-busy')
|
this.wrapper.classList.remove('is-busy')
|
||||||
|
this.queued = false
|
||||||
}
|
}
|
||||||
|
|
||||||
sendRequest (_cb = null) {
|
sendRequest () {
|
||||||
let headers = {
|
let headers = {
|
||||||
Accept: 'application/json',
|
Accept: 'application/json',
|
||||||
'Cache-Control': 'no-cache',
|
|
||||||
'X-Requested-With': 'XMLHttpRequest',
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
...(this.options.headers || {})
|
...(this.options.headers || {})
|
||||||
}
|
}
|
||||||
@@ -252,14 +256,17 @@ export default class SimpleComplete {
|
|||||||
if (!(200 <= xhr.status && xhr.status < 300)) {
|
if (!(200 <= xhr.status && xhr.status < 300)) {
|
||||||
this.onError('simplecomplete.errors.xhr_wrong_status')
|
this.onError('simplecomplete.errors.xhr_wrong_status')
|
||||||
} else {
|
} else {
|
||||||
let data =
|
|
||||||
|
|
||||||
this.options.onResponse (response, xhr)
|
this.options.onResponse (response, xhr)
|
||||||
this.onResults(response.data || response)
|
this.onResults(response.data || response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onSend (e = null) {
|
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)) {
|
if (!this.query || (this.options.minLength > 0 && this.query.length < this.options.minLength)) {
|
||||||
this.onError('simplecomplete.errors.min-length')
|
this.onError('simplecomplete.errors.min-length')
|
||||||
} else {
|
} else {
|
||||||
@@ -267,18 +274,7 @@ export default class SimpleComplete {
|
|||||||
this.queued = true
|
this.queued = true
|
||||||
} else if (this.options.url) {
|
} else if (this.options.url) {
|
||||||
this.wrapper.classList.add('is-busy')
|
this.wrapper.classList.add('is-busy')
|
||||||
|
this.sendRequest()
|
||||||
this.sendRequest((xhr) => {
|
|
||||||
console.log('DONE', xhr)
|
|
||||||
})
|
|
||||||
|
|
||||||
/*window.setTimeout(() => {
|
|
||||||
this.wrapper.classList.remove('is-busy')
|
|
||||||
if(this.queued) {
|
|
||||||
this.queued = false
|
|
||||||
this.onSend ()
|
|
||||||
}
|
|
||||||
}, 3000)*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -335,7 +331,7 @@ export default class SimpleComplete {
|
|||||||
updateLabel () {
|
updateLabel () {
|
||||||
this.currentValue.classList.remove('is-empty')
|
this.currentValue.classList.remove('is-empty')
|
||||||
this.currentValue.innerHTML = ''
|
this.currentValue.innerHTML = ''
|
||||||
if (this.isMultiple() || this.isSelectElement()) {
|
if (this.isMultiple() && this.isSelectElement()) {
|
||||||
let _opts = Array.from(this.element.selectedOptions)
|
let _opts = Array.from(this.element.selectedOptions)
|
||||||
for (let _key in _opts) {
|
for (let _key in _opts) {
|
||||||
let o = _opts[_key]
|
let o = _opts[_key]
|
||||||
@@ -360,7 +356,17 @@ export default class SimpleComplete {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!this.currentValue.childNodes.length) {
|
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()) {
|
if (this.isSelectElement()) {
|
||||||
let badge = SimpleComplete.createElement('SPAN', {
|
let badge = SimpleComplete.createElement('SPAN', {
|
||||||
classes: 'empty-item'
|
classes: 'empty-item'
|
||||||
@@ -378,6 +384,7 @@ export default class SimpleComplete {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onError (key) {
|
onError (key) {
|
||||||
console.log(key)
|
console.log(key)
|
||||||
@@ -484,14 +491,14 @@ export default class SimpleComplete {
|
|||||||
if(this.results && this.resultsList) {
|
if(this.results && this.resultsList) {
|
||||||
this.resultsList.innerHTML = ''
|
this.resultsList.innerHTML = ''
|
||||||
if (this.isSelectElement ()) {
|
if (this.isSelectElement ()) {
|
||||||
[...this.element.options].forEach(option => {
|
[...this.element.options].filter(this.filterResults.bind(this)).forEach(option => {
|
||||||
this.resultsList.appendChild(this.renderOption({
|
this.resultsList.appendChild(this.renderOption({
|
||||||
value: option.value,
|
value: option.value,
|
||||||
label: option.textContent
|
label: option.textContent
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
} else {
|
} 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) {
|
if (!this.resultsList.childNodes.length) {
|
||||||
@@ -502,6 +509,9 @@ export default class SimpleComplete {
|
|||||||
emptyNode.textContent = this.options.emptyText || 'No results'
|
emptyNode.textContent = this.options.emptyText || 'No results'
|
||||||
|
|
||||||
this.resultsList.appendChild(emptyNode)
|
this.resultsList.appendChild(emptyNode)
|
||||||
|
this.wrapper.classList.add('has-results')
|
||||||
|
} else {
|
||||||
|
this.wrapper.classList.remove('has-results')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(err) {
|
} 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) {
|
isSelected (_val) {
|
||||||
let opts = Array.from(this.element.selectedOptions || [])
|
let opts = Array.from(this.element.selectedOptions || [])
|
||||||
for (let _index = 0; _index < opts.length; _index++) {
|
for (let _index = 0; _index < opts.length; _index++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user