Skip to content

Commit

Permalink
Merge branch '1.next-cake4' into 2.next-cake5
Browse files Browse the repository at this point in the history
  • Loading branch information
skie committed Sep 17, 2024
2 parents 1ad8b1d + d66104e commit e71d327
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 45 deletions.
2 changes: 1 addition & 1 deletion src/Filter/LookupFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public function setLookupFields(array $lookupFields): self
public function toArray(): array
{
if (empty($this->properties['autocompleteUrl'])) {
$this->properties['autocompleteUrl'] = Router::url($this->getAutocompleteRoute(), true);
$this->properties['autocompleteUrl'] = Router::url($this->getAutocompleteRoute());
}
$props = parent::toArray();

Expand Down
2 changes: 2 additions & 0 deletions templates/element/Search/v_search.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
var values = null;
<?php if (!empty($values)): ?>
window._search.values = <?= json_encode($values) ?>;
<?php else: ?>
window._search.values = {};
<?php endif; ?>
</script>

Expand Down
35 changes: 23 additions & 12 deletions templates/element/Search/v_templates.php
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@
display: block;
padding: 0.3125rem 0;
margin: 0.125rem 0 0;
font-size: 1rem;
font-size: 14px;
text-align: left;
list-style: none;
background-color: var(--search-color-white);
Expand All @@ -349,7 +349,7 @@
}

.suggestions-list li {
padding: 0.1875rem 1.25rem;
padding: 0.2rem 1.25rem;
clear: both;
font-weight: 400;
line-height: 1.5;
Expand All @@ -363,6 +363,10 @@
text-decoration: none;
background-color: var(--search-color-gray-100);
}

.suggestions-list .is-active {
background-color: var(--search-color-gray-200);
}
</style>

<script type="text/x-template" id="search-list">
Expand Down Expand Up @@ -711,29 +715,36 @@ class="btn-remove-item"
</script>

<script type="text/x-template" id="search-input-lookup-template">
<span class="lookup-wrapper">
<input
type="hidden"
:name="'v[' + index + '][id][]'"
v-model="selectedId"
/>
<div class="lookup-wrapper">
<input
type="text"
class="form-control value typeahead"
:name="'v[' + index + '][value][]'"
v-model="inputValue"
autocomplete="off"
@input="onInput"
@keydown.down="onArrowDown"
@keydown.up="onArrowUp"
@keydown.enter="onEnter"
@keydown.esc="onEscape"
@blur="onBlur"
/>
<ul v-if="showSuggestions" class="suggestions-list">
<ul v-if="showSuggestions" class="suggestions-list" role="listbox">
<li
v-for="suggestion in suggestions"
:key="suggestion.id"
v-for="(suggestion, index) in suggestions"
:key="suggestion[idName]"
@click="selectSuggestion(suggestion)"
@mouseenter="arrowCounter = index"
:class="{ 'is-active': index === arrowCounter }"
role="option"
>
{{ suggestion[valueName] }}
</li>
</ul>
</span>
<input
type="hidden"
:name="'v[' + index + '][id][]'"
v-model="selectedId"
/>
</div>
</script>
111 changes: 79 additions & 32 deletions webroot/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,14 @@ const SearchApp = {
},
mounted() {
console.info("Search mounted!");
const keys = Object.keys(this.values);
for (let filter of keys) {
this.add({filter: filter, ...this.values[filter]});
}
if (keys.length == 0) {
this.add();
if (this.values != null && this.values != undefined) {
const keys = Object.keys(this.values);
for (let filter of keys) {
this.add({filter: filter, ...this.values[filter]});
}
if (keys.length == 0) {
this.add();
}
}
const appRoot = document.getElementById(window._search.rootElemId);
appRoot.addEventListener(
Expand Down Expand Up @@ -708,6 +710,7 @@ const SearchLookupInput = {
suggestions: [],
showSuggestions: false,
debounceTimeout: null,
arrowCounter: -1
};
},
computed: {
Expand All @@ -732,52 +735,96 @@ const SearchLookupInput = {
clearTimeout(this.debounceTimeout);
this.debounceTimeout = setTimeout(() => {
this.fetchSuggestions();
}, 300);
}, 200);
},
async fetchSuggestions() {
if (this.inputValue.length < 2) {
if (this.inputValue.length >= 2) {
try {
let query = this.query.replace(this.wildcard, this.inputValue)
let autocompleteUrl = this.autocompleteUrl + '?' + query;
if (!/^https?:\/\//i.test(autocompleteUrl)) {
autocompleteUrl = `${window.location.origin}${autocompleteUrl}`;
}
const url = new URL(autocompleteUrl);
const response = await fetch(url);
this.suggestions = await response.json();
this.showSuggestions = true;
this.arrowCounter = -1;
} catch (error) {
console.error('Error fetching suggestions:', error);
}
} else {
this.suggestions = [];
this.showSuggestions = false;
return;
}

let query = this.query.replace(this.wildcard, this.inputValue)
let autocompleteUrl = this.autocompleteUrl + '?' + query;
const url = new URL(autocompleteUrl);

try {
const response = await fetch(url);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data = await response.json();
this.suggestions = data;
this.showSuggestions = true;
} catch (error) {
console.error('Error fetching suggestions:', error);
}
},
selectSuggestion(suggestion) {
this.inputValue = suggestion[this.valueName];
this.selectedId = suggestion[this.idName];
this.showSuggestions = false;
this.$emit('change-value', {
index: this.index,
value: { id: this.selectedId, value: this.inputValue }
});
this.$emit('change-value', { index: this.index, value: { id: this.selectedId, value: this.inputValue } });
},
onArrowDown(evt) {
if (this.showSuggestions) {
if (this.arrowCounter < this.suggestions.length - 1) {
this.arrowCounter++;
}
this.scrollToActive();
evt.preventDefault();
}
},
onArrowUp(evt) {
if (this.showSuggestions) {
if (this.arrowCounter > 0) {
this.arrowCounter--;
}
this.scrollToActive();
evt.preventDefault();
}
},
onEnter(event) {
if (this.showSuggestions && this.arrowCounter > -1 && this.arrowCounter < this.suggestions.length) {
event.preventDefault();
this.selectSuggestion(this.suggestions[this.arrowCounter]);
}
},
onEscape() {
if (this.showSuggestions) {
this.showSuggestions = false;
this.arrowCounter = -1;
this.$el.querySelector('input[type="text"]').focus();
}
},
scrollToActive() {
const activeItem = this.$el.querySelector('.is-active');
if (activeItem) {
activeItem.scrollIntoView({ block: 'nearest' });
}
},
onBlur() {
setTimeout(() => {
this.showSuggestions = false;
this.arrowCounter = -1;
}, 200);
},
}
},
mounted() {
if (this.value) {
this.inputValue = this.value.value;
this.selectedId = this.value.id;
this.inputValue = this.value.value || '';
this.selectedId = this.value.id || '';
}
},
watch: {
value(newValue) {
if (newValue) {
this.inputValue = newValue.value || '';
this.selectedId = newValue.id || '';
} else {
this.inputValue = '';
this.selectedId = '';
}
}
}
};

const createMyApp = (root, callback) => {
Expand Down

0 comments on commit e71d327

Please sign in to comment.