mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-01 20:29:29 +00:00
improve responsive layout of search results
This commit is contained in:
@@ -473,4 +473,45 @@ html {
|
||||
transition-property: background,color;
|
||||
transition-duration: 0.3s,0.2s;
|
||||
transition-timing-function: ease-out,ease-out;
|
||||
}
|
||||
@media screen and ( max-width: 767px ) {
|
||||
#nav-search {
|
||||
position: static;
|
||||
}
|
||||
|
||||
#nav-search .searchbar_results {
|
||||
top: 100%;
|
||||
width: 98vw !important;
|
||||
left: 1vw !important;
|
||||
right: 1vw !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and ( max-width: 576px ) {
|
||||
.searchbar_icon img {
|
||||
max-width: 65px !important;
|
||||
}
|
||||
|
||||
.searchbar_icon i {
|
||||
font-size: 3em !important;
|
||||
}
|
||||
|
||||
.searchbar_grid {
|
||||
grid-template-columns: [icon] 75px [data] auto;
|
||||
}
|
||||
|
||||
.searchbar_table,
|
||||
.searchbar_tablerow,
|
||||
.searchbar_tablecell {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.searchbar_tablecell.searchbar_label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.searchbar_tablecell.searchbar_value {
|
||||
padding-left: 2.5rem;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
}
|
||||
@@ -21,14 +21,17 @@
|
||||
z-index: 9998;
|
||||
background-color: #fff;
|
||||
border: 1px solid lightgrey;
|
||||
padding: 1rem;
|
||||
overflow-y: auto;
|
||||
padding: .5rem;
|
||||
top: 100%;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.searchbar_results_scroller {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.searchbar_result {
|
||||
border-bottom: 1px solid lightgrey;
|
||||
margin-bottom: 1rem;
|
||||
@@ -104,4 +107,4 @@
|
||||
-webkit-user-select: none; /* Safari */
|
||||
-moz-user-select: none; /* Firefox */
|
||||
-ms-user-select: none; /* IE/Edge */
|
||||
}
|
||||
}
|
||||
|
||||
+10
-2
@@ -15,6 +15,7 @@ const app = Vue.createApp({
|
||||
return {
|
||||
searchbaroptions: {
|
||||
cssclass: "",
|
||||
calcheightonly: true,
|
||||
types: [
|
||||
"mitarbeiter",
|
||||
"raum",
|
||||
@@ -75,9 +76,16 @@ const app = Vue.createApp({
|
||||
},
|
||||
organisationunit: {
|
||||
defaultaction: {
|
||||
type: "function",
|
||||
type: "link",
|
||||
renderif: function(data) {
|
||||
if(data.mailgroup) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
action: function(data) {
|
||||
alert('organisationunit defaultaction ' + JSON.stringify(data));
|
||||
const link = 'mailto:' + data.mailgroup;
|
||||
return link;
|
||||
}
|
||||
},
|
||||
childactions: []
|
||||
|
||||
@@ -30,8 +30,8 @@ export default {
|
||||
<div class="searchbar_table">
|
||||
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">Standard-Kostenstelle</div>
|
||||
<div class="searchbar_tablecell">
|
||||
<div class="searchbar_tablecell searchbar_label">Standard-Kostenstelle</div>
|
||||
<div class="searchbar_tablecell searchbar_value">
|
||||
<ul class="searchbar_inline_ul" v-if="res.standardkostenstelle.length > 0">
|
||||
<li v-for="(stdkst, idx) in res.standardkostenstelle" :key="idx">{{ stdkst }}</li>
|
||||
</ul>
|
||||
@@ -40,8 +40,8 @@ export default {
|
||||
</div>
|
||||
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">Organisations-Einheit</div>
|
||||
<div class="searchbar_tablecell">
|
||||
<div class="searchbar_tablecell searchbar_label">Organisations-Einheit</div>
|
||||
<div class="searchbar_tablecell searchbar_value">
|
||||
<ul class="searchbar_inline_ul" v-if="res.organisationunit_name.length > 0">
|
||||
<li v-for="(oe, idx) in res.organisationunit_name" :key="idx">{{ oe }}</li>
|
||||
</ul>
|
||||
@@ -50,8 +50,8 @@ export default {
|
||||
</div>
|
||||
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">EMail</div>
|
||||
<div class="searchbar_tablecell">
|
||||
<div class="searchbar_tablecell searchbar_label">EMail</div>
|
||||
<div class="searchbar_tablecell searchbar_value">
|
||||
<a :href="this.mailtourl">
|
||||
{{ res.email }}
|
||||
</a>
|
||||
@@ -59,8 +59,8 @@ export default {
|
||||
</div>
|
||||
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">Telefon</div>
|
||||
<div class="searchbar_tablecell">
|
||||
<div class="searchbar_tablecell searchbar_label">Telefon</div>
|
||||
<div class="searchbar_tablecell searchbar_value">
|
||||
<a :href="this.telurl">
|
||||
{{ res.phone }}
|
||||
</a>
|
||||
|
||||
@@ -28,24 +28,25 @@ export default {
|
||||
<div class="searchbar_table">
|
||||
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">übergeordnete OrgEinheit</div>
|
||||
<div class="searchbar_tablecell">
|
||||
<div class="searchbar_tablecell searchbar_label">übergeordnete OrgEinheit</div>
|
||||
<div class="searchbar_tablecell searchbar_value">
|
||||
{{ res.parentoe_name }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">Gruppen-EMail</div>
|
||||
<div class="searchbar_tablecell">
|
||||
<a :href="this.mailtourl">
|
||||
<div class="searchbar_tablecell searchbar_label">Gruppen-EMail</div>
|
||||
<div class="searchbar_tablecell searchbar_value">
|
||||
<a :href="this.mailtourl" v-if="res.mailgroup">
|
||||
{{ res.mailgroup }}
|
||||
</a>
|
||||
<span v-else>-</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">Leiter</div>
|
||||
<div class="searchbar_tablecell">
|
||||
<div class="searchbar_tablecell searchbar_label">Leiter</div>
|
||||
<div class="searchbar_tablecell searchbar_value">
|
||||
<ul class="searchbar_inline_ul" v-if="res.leaders.length > 0">
|
||||
<li v-for="(leader, idx) in res.leaders" :key="idx">{{ leader.name }}</li>
|
||||
</ul>
|
||||
@@ -54,8 +55,8 @@ export default {
|
||||
</div>
|
||||
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">Mitarbeiter-Anzahl</div>
|
||||
<div class="searchbar_tablecell">
|
||||
<div class="searchbar_tablecell searchbar_label">Mitarbeiter-Anzahl</div>
|
||||
<div class="searchbar_tablecell searchbar_value">
|
||||
{{ res.number_of_people }}
|
||||
</div>
|
||||
</div>
|
||||
@@ -64,7 +65,7 @@ export default {
|
||||
|
||||
<actions :res="this.res" :actions="this.actions.childactions" @actionexecuted="$emit('actionexecuted')"></actions>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -29,8 +29,8 @@ export default {
|
||||
|
||||
<div class="searchbar_table">
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">EMail</div>
|
||||
<div class="searchbar_tablecell">
|
||||
<div class="searchbar_tablecell searchbar_label">EMail</div>
|
||||
<div class="searchbar_tablecell searchbar_value">
|
||||
<a :href="this.mailtourl">
|
||||
{{ res.mail }}
|
||||
</a>
|
||||
|
||||
@@ -31,36 +31,36 @@ export default {
|
||||
<div class="searchbar_table">
|
||||
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">Prestudent_id</div>
|
||||
<div class="searchbar_tablecell">
|
||||
<div class="searchbar_tablecell searchbar_label">Prestudent_id</div>
|
||||
<div class="searchbar_tablecell searchbar_value">
|
||||
{{ res.prestudent_id }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">Student_uid</div>
|
||||
<div class="searchbar_tablecell">
|
||||
<div class="searchbar_tablecell searchbar_label">Student_uid</div>
|
||||
<div class="searchbar_tablecell searchbar_value">
|
||||
{{ res.uid }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">Person_id</div>
|
||||
<div class="searchbar_tablecell">
|
||||
<div class="searchbar_tablecell searchbar_label">Person_id</div>
|
||||
<div class="searchbar_tablecell searchbar_value">
|
||||
{{ res.person_id }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">Studiengang</div>
|
||||
<div class="searchbar_tablecell">
|
||||
<div class="searchbar_tablecell searchbar_label">Studiengang</div>
|
||||
<div class="searchbar_tablecell searchbar_value">
|
||||
{{ res.bezeichnung }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">EMail</div>
|
||||
<div class="searchbar_tablecell">
|
||||
<div class="searchbar_tablecell searchbar_label">EMail</div>
|
||||
<div class="searchbar_tablecell searchbar_value">
|
||||
<a :href="this.mailtourl">
|
||||
{{ res.email }}
|
||||
</a>
|
||||
|
||||
@@ -25,20 +25,20 @@ export default {
|
||||
|
||||
<div class="searchbar_table">
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">Standort</div>
|
||||
<div class="searchbar_tablecell">{{ res.standort }}</div>
|
||||
<div class="searchbar_tablecell searchbar_label">Standort</div>
|
||||
<div class="searchbar_tablecell searchbar_value">{{ res.standort }}</div>
|
||||
</div>
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">Sitzplätze</div>
|
||||
<div class="searchbar_tablecell">{{ res.sitzplaetze }}</div>
|
||||
<div class="searchbar_tablecell searchbar_label">Sitzplätze</div>
|
||||
<div class="searchbar_tablecell searchbar_value">{{ res.sitzplaetze }}</div>
|
||||
</div>
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">Gebäude</div>
|
||||
<div class="searchbar_tablecell">{{ res.building }}</div>
|
||||
<div class="searchbar_tablecell searchbar_label">Gebäude</div>
|
||||
<div class="searchbar_tablecell searchbar_value">{{ res.building }}</div>
|
||||
</div>
|
||||
<div class="searchbar_tablerow">
|
||||
<div class="searchbar_tablecell">Zusatz Informationen</div>
|
||||
<div class="searchbar_tablecell"><div v-html="res.austattung.replace('<br />','')"></div></div>
|
||||
<div class="searchbar_tablecell searchbar_label">Zusatz Informationen</div>
|
||||
<div class="searchbar_tablecell searchbar_value"><div v-html="res.austattung.replace('<br />','')"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -36,30 +36,33 @@ export default {
|
||||
<form ref="searchform" class="d-flex me-3" :class="searchoptions.cssclass" action="javascript:void(0);"
|
||||
@focusin="this.searchfocusin" @focusout="this.searchfocusout">
|
||||
|
||||
<div class="h-100 input-group me-2 bg-white">
|
||||
|
||||
<input ref="searchbox" @keyup="this.search" @focus="this.showsearchresult"
|
||||
<div ref="searchbox" class="h-100 input-group me-2 bg-white">
|
||||
<input @keyup="this.search" @focus="this.showsearchresult"
|
||||
v-model="this.searchsettings.searchstr" class="form-control"
|
||||
type="search" :placeholder="'Search: '+ searchsettings.types.join(' / ')" aria-label="Search">
|
||||
<button data-bs-toggle="collapse" data-bs-target="#searchSettings" aria-expanded="false" aria-controls="searchSettings" ref="settingsbutton" class="btn btn-outline-secondary" type="button" id="search-filter"><i class="fas fa-cog"></i></button>
|
||||
</div>
|
||||
|
||||
<div v-show="this.showresult" ref="result"
|
||||
<div v-show="this.showresult"
|
||||
class="searchbar_results" tabindex="-1">
|
||||
<div v-if="this.searching">
|
||||
<i class="fas fa-spinner fa-spin fa-2x"></i>
|
||||
</div>
|
||||
<div v-else-if="this.error !== null">{{ this.error }}</div>
|
||||
<div v-else-if="searchresult.length < 1">Es wurden keine Ergebnisse gefunden.</div>
|
||||
<template v-else="" v-for="res in searchresult">
|
||||
<person v-if="res.type === 'person'" :res="res" :actions="this.searchoptions.actions.person" @actionexecuted="this.hideresult"></person>
|
||||
<student v-else-if="res.type === 'student'" :res="res" :actions="this.searchoptions.actions.student" @actionexecuted="this.hideresult"></student>
|
||||
<prestudent v-else-if="res.type === 'prestudent'" :res="res" :actions="this.searchoptions.actions.prestudent" @actionexecuted="this.hideresult"></prestudent>
|
||||
<employee v-else-if="res.type === 'mitarbeiter' || res.type === 'mitarbeiter_ohne_zuordnung'" :res="res" :actions="this.searchoptions.actions.employee" @actionexecuted="this.hideresult"></employee>
|
||||
<organisationunit v-else-if="res.type === 'organisationunit'" :res="res" :actions="this.searchoptions.actions.organisationunit" @actionexecuted="this.hideresult"></organisationunit>
|
||||
<raum v-else-if="res.type === 'raum'" :res="res" :actions="this.searchoptions.actions.raum" @actionexecuted="this.hideresult"></raum>
|
||||
<div v-else="">Unbekannter Ergebnistyp: '{{ res.type }}'.</div>
|
||||
</template>
|
||||
<div class="searchbar_results_scroller" ref="result">
|
||||
<div class="searchbar_results_wrapper" ref="results">
|
||||
<div v-if="this.searching">
|
||||
<i class="fas fa-spinner fa-spin fa-2x"></i>
|
||||
</div>
|
||||
<div v-else-if="this.error !== null">{{ this.error }}</div>
|
||||
<div v-else-if="searchresult.length < 1">Es wurden keine Ergebnisse gefunden.</div>
|
||||
<template v-else="" v-for="res in searchresult">
|
||||
<person v-if="res.type === 'person'" :res="res" :actions="this.searchoptions.actions.person" @actionexecuted="this.hideresult"></person>
|
||||
<student v-else-if="res.type === 'student'" :res="res" :actions="this.searchoptions.actions.student" @actionexecuted="this.hideresult"></student>
|
||||
<prestudent v-else-if="res.type === 'prestudent'" :res="res" :actions="this.searchoptions.actions.prestudent" @actionexecuted="this.hideresult"></prestudent>
|
||||
<employee v-else-if="res.type === 'mitarbeiter' || res.type === 'mitarbeiter_ohne_zuordnung'" :res="res" :actions="this.searchoptions.actions.employee" @actionexecuted="this.hideresult"></employee>
|
||||
<organisationunit v-else-if="res.type === 'organisationunit'" :res="res" :actions="this.searchoptions.actions.organisationunit" @actionexecuted="this.hideresult"></organisationunit>
|
||||
<raum v-else-if="res.type === 'raum'" :res="res" :actions="this.searchoptions.actions.raum" @actionexecuted="this.hideresult"></raum>
|
||||
<div v-else="">Unbekannter Ergebnistyp: '{{ res.type }}'.</div>
|
||||
</template>
|
||||
</div>
|
||||
</duv>
|
||||
</div>
|
||||
|
||||
<div id="searchSettings" ref="settings" @[\`show.bs.collapse\`]="$emit('showSettings','settings')"
|
||||
@@ -91,6 +94,13 @@ export default {
|
||||
toggle: false
|
||||
});
|
||||
},
|
||||
updated() {
|
||||
if(this.showresult) {
|
||||
Vue.nextTick(() => {
|
||||
this.calcSearchResultHeight();
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateSearchOptions: function() {
|
||||
this.searchsettings.types = [];
|
||||
@@ -98,12 +108,26 @@ export default {
|
||||
this.searchsettings.types.push(this.searchoptions.types[idx]);
|
||||
}
|
||||
},
|
||||
calcSearchResultHeight: function() {
|
||||
const rect = this.$refs.results.getBoundingClientRect();
|
||||
if( rect.height > 0 && rect.height < (window.innerHeight * 0.8) ) {
|
||||
this.$refs.result.style.height = Math.ceil(rect.height) + 'px';
|
||||
} else {
|
||||
this.$refs.result.style.height = Math.floor(window.innerHeight * 0.8) + 'px';
|
||||
}
|
||||
},
|
||||
calcSearchResultExtent: function() {
|
||||
var rect = this.$refs.searchbox.getBoundingClientRect();
|
||||
this.$refs.result.style.top = Math.floor(rect.bottom + 3) + 'px';
|
||||
this.$refs.result.style.right = Math.floor(window.innerWidth - rect.right) + 'px';
|
||||
this.$refs.result.style.width = Math.floor(window.innerWidth * 0.75) + 'px';
|
||||
this.$refs.result.style.height = Math.floor(window.innerHeight * 0.75) + 'px';
|
||||
if(!this.showresult) {
|
||||
return;
|
||||
}
|
||||
if(this.searchoptions?.calcheightonly === undefined
|
||||
|| this.searchoptions.calcheightonly === false) {
|
||||
var rect = this.$refs.searchbox.getBoundingClientRect();
|
||||
this.$refs.result.style.top = Math.floor(rect.bottom + 3) + 'px';
|
||||
this.$refs.result.style.right = Math.floor(rect.right) + 'px';
|
||||
this.$refs.result.style.width = Math.floor(rect.width) + 'px';
|
||||
}
|
||||
this.calcSearchResultHeight();
|
||||
},
|
||||
search: function() {
|
||||
if( this.searchtimer !== null ) {
|
||||
@@ -159,6 +183,7 @@ export default {
|
||||
if( this.searchsettings.searchstr.length >= 2 ) {
|
||||
this.showresult = true;
|
||||
window.addEventListener('resize', this.calcSearchResultExtent);
|
||||
this.calcSearchResultExtent();
|
||||
}
|
||||
},
|
||||
searchfocusin: function(e) {
|
||||
|
||||
Reference in New Issue
Block a user