75 lines
2.4 KiB
Vue
75 lines
2.4 KiB
Vue
|
<template>
|
||
|
<div class="tt-menu-search-container">
|
||
|
<AutoComplete class="tt-menu-search" placeholder="Search Menu" v-model="terms" :suggestions="searchSuggestions"
|
||
|
optionGroupLabel="label" optionGroupChildren="items"
|
||
|
@complete="searchMenu($event)" @item-select="selectItem($event)" field="label" :minLength="minLength"/>
|
||
|
</div>
|
||
|
<div class="search-separator"></div>
|
||
|
</template>
|
||
|
<script>
|
||
|
import AutoComplete from 'primevue/autocomplete';
|
||
|
|
||
|
export default {
|
||
|
name: 'TTMenuSearch',
|
||
|
props: {
|
||
|
model: Array,
|
||
|
search: String,
|
||
|
},
|
||
|
data() {
|
||
|
return {
|
||
|
terms: null,
|
||
|
searchSuggestions: null,
|
||
|
minLength: 2
|
||
|
};
|
||
|
},
|
||
|
methods: {
|
||
|
searchMenu( event ) {
|
||
|
let findItems = ( items, suggestions, group_header ) => {
|
||
|
let filtered_items = [];
|
||
|
for ( let i = 0; i < items.length; i++ ) {
|
||
|
//If item is a valid menu link compare the label to the search term and add to filtered items if matches.
|
||
|
if ( items[i].parent_id && items[i].command && items[i].label && items[i].label.toLowerCase().includes( event.query.toLowerCase() ) ) {
|
||
|
filtered_items.push( items[i] );
|
||
|
}
|
||
|
//If item is a header and has child items, recursively search child items.
|
||
|
if ( items[i].items && items[i].items.length > 0 ) {
|
||
|
suggestions = findItems( items[i].items, suggestions, items[i].label );
|
||
|
}
|
||
|
//Finally add all items from that group to the suggestions by the group header.
|
||
|
if ( i === items.length - 1 && filtered_items.length > 0 && group_header ) {
|
||
|
suggestions.push( { label: group_header, items: filtered_items } );
|
||
|
}
|
||
|
}
|
||
|
return suggestions;
|
||
|
};
|
||
|
|
||
|
this.searchSuggestions = findItems( this.model, [] );
|
||
|
},
|
||
|
selectItem( event ) {
|
||
|
event.value.command();
|
||
|
},
|
||
|
},
|
||
|
components: {
|
||
|
AutoComplete
|
||
|
}
|
||
|
};
|
||
|
</script>
|
||
|
<style scoped>
|
||
|
.tt-menu-search-container {
|
||
|
margin: 5px;
|
||
|
width: 100%;
|
||
|
}
|
||
|
|
||
|
.search-separator {
|
||
|
border-top: 1px solid #dee2e6;
|
||
|
}
|
||
|
|
||
|
::v-deep(.tt-menu-search) {
|
||
|
width: calc(100% - 10px);
|
||
|
}
|
||
|
|
||
|
::v-deep(.p-inputtext) {
|
||
|
width: 100%;
|
||
|
}
|
||
|
</style>
|