added search type dropdown with vue-select

This commit is contained in:
2020-07-16 15:59:05 +02:00
parent 9a4f839fc1
commit 0f48e600b9
5 changed files with 223 additions and 62 deletions
+96 -28
View File
@@ -552,35 +552,90 @@ footer[role="tools"]{
background-color: $bleuroi; background-color: $bleuroi;
form{ form{
padding: 0.7em; padding: 0.7em;
label[for="keys"]{ fieldset{
display: none; padding:1em;
border: none;
&:not(:first-of-type){
border-left: 1px solid $grisclair;
}
} }
input[type="text"]{ fieldset.search{
padding:0.3em; >div{
font-size: 0.756em; display: inline-block;
line-height: 1; width:80%;
height:1em; vertical-align: middle;
border:none; }
border-radius: 2px; label[for="keys"]{
} display: none;
// input[type="submit"]{ }
// #submit-search{ input[type="text"]{
// border:none; padding:0.3em;
// box-sizing: border-box;
// } font-size: 0.756em;
// } line-height: 1;
span.mdi{ width:100%;
display: inline-block; height:1.2em;
font-size: 1.2em; border:none;
line-height:1.1; border-radius: 2px;
vertical-align:middle; }
width:1.2em; height:1.2em; #search-type{
border-radius: 0.6em; padding:0.2em 0 0 0;
background-color: #fff; div[role="combobox"]{
color: $bleuroi; background-color: #fff;
text-align: center; padding:0;
font-weight: 700; border-radius: 2px;
cursor: pointer; border: none;
}
input[type="search"]{
margin:0;
padding:0;
}
.vs__search{
&, &:focus{
font-size: 0.756em;
line-height: 1;
height:1.2em;
border:none;
box-sizing: border-box;
}
}
.vs__actions{
padding:1px 3px;
svg[role="presentation"]{
transform: scale(0.8);
path{
fill: $bleuroi;
}
}
}
.vs__selected{
margin:0;
padding:0;
line-height:1;
font-size: 0.756em;
}
// border-radius: 2px;
// border: none;
}
// input[type="submit"]{
// #submit-search{
// border:none;
//
// }
// }
span.mdi{
display: inline-block;
font-size: 1.2em;
line-height:1.1;
vertical-align:middle;
width:1.2em; height:1.2em;
border-radius: 0.6em;
background-color: #fff;
color: $bleuroi;
text-align: center;
font-weight: 700;
cursor: pointer;
}
} }
} }
} }
@@ -594,6 +649,19 @@ footer[role="tools"]{
} }
} }
// vue-select
ul[role="listbox"]{
@include fontsans;
padding:0;
margin:0;
border:none;
li{
padding:0.3em;
margin:0;
font-size: 0.756em;
line-height: 1;
}
}
// ___ // ___
// |_ _|__ ___ _ _ ___ // |_ _|__ ___ _ _ ___
+10
View File
@@ -1063,6 +1063,11 @@
"@types/yargs": "^13.0.0" "@types/yargs": "^13.0.0"
} }
}, },
"@popperjs/core": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.4.4.tgz",
"integrity": "sha512-1oO6+dN5kdIA3sKPZhRGJTfGVP4SWV6KqlMOwry4J3HfyD68sl/3KmG7DeYUzvN+RbhXDnv/D8vNNB8168tAMg=="
},
"@types/babel__core": { "@types/babel__core": {
"version": "7.1.3", "version": "7.1.3",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz",
@@ -12066,6 +12071,11 @@
"bezier-easing": "2.1.0" "bezier-easing": "2.1.0"
} }
}, },
"vue-select": {
"version": "3.10.7",
"resolved": "https://registry.npmjs.org/vue-select/-/vue-select-3.10.7.tgz",
"integrity": "sha512-6rvIYBNEp9y0xK/sq2ZzDCxKA2BoVNliyctOeMtzarQzvpLlab7l8zvqr2jhGZOxozp7jd2AvZxpF3Ivems2wQ=="
},
"vue-server-renderer": { "vue-server-renderer": {
"version": "2.6.10", "version": "2.6.10",
"resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.6.10.tgz", "resolved": "https://registry.npmjs.org/vue-server-renderer/-/vue-server-renderer-2.6.10.tgz",
+2
View File
@@ -18,12 +18,14 @@
"author": "Daniel Cook", "author": "Daniel Cook",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@popperjs/core": "^2.4.4",
"axios": "^0.18.1", "axios": "^0.18.1",
"vue": "^2.6.10", "vue": "^2.6.10",
"vue-infinite-loading": "^2.4.5", "vue-infinite-loading": "^2.4.5",
"vue-meta": "^1.6.0", "vue-meta": "^1.6.0",
"vue-router": "^3.1.3", "vue-router": "^3.1.3",
"vue-scrollto": "^2.18.1", "vue-scrollto": "^2.18.1",
"vue-select": "^3.10.7",
"vuex": "^3.1.1", "vuex": "^3.1.1",
"vuex-router-sync": "^5.0.0" "vuex-router-sync": "^5.0.0"
}, },
+112 -33
View File
@@ -1,48 +1,81 @@
<template> <template>
<div id="search" class="col-11"> <div id="search" class="col-11">
<form class="search-form"> <form class="search-form row">
<label for="keys">Search</label> <fieldset class="search col-3">
<input <div>
id="keys" <label for="keys">Search</label>
v-model="keys" <input
type="text" id="keys"
placeholder="search" v-model="keys"
@keydown.enter.prevent="submit" type="text"
> placeholder="search"
<span @keydown.enter.prevent="submit"
v-if="!isloading" >
class="mdi mdi-magnify" <v-select
title="rechercher" id="search-type"
@click.prevent="submit" type="select"
@keydown.enter.prevent="submit" placeholder="dans ..."
/> append-to-body
<span :calculate-position="withPopper"
v-else :options="searchTypeOptions"
class="mdi mdi-loading" :clearable="false"
title="chargement" :value="searchTypeValue"
/> @input="onSearchTypeSelected"
<!-- <input />
id="submit-search" </div>
type="submit"
name="search" <span
value="Search" v-if="!isloading"
class="mdi mdi-magnify" class="mdi mdi-magnify"
@click.prevent="submit" title="rechercher"
@keyup.enter="submit" @click.prevent="submit"
> --> @keydown.enter.prevent="submit"
/>
<span
v-else
class="mdi mdi-loading"
title="chargement"
/>
<!-- <input
id="submit-search"
type="submit"
name="search"
value="Search"
class="mdi mdi-magnify"
@click.prevent="submit"
@keyup.enter="submit"
> -->
</fieldset>
<fieldset class="filters-nominum col-3">
<span>Filters Nominum</span>
</fieldset>
<fieldset class="filters-locorum col-3">
<span>Filters Nominum</span>
</fieldset>
<fieldset class="filters-operum col-3">
<span>Filters Nominum</span>
</fieldset>
</form> </form>
</div> </div>
</template> </template>
<script> <script>
import { createPopper } from '@popperjs/core'
import { mapActions, mapState } from 'vuex' import { mapActions, mapState } from 'vuex'
export default { export default {
name: 'Search', name: 'Search',
// data: () => ({ data: () => ({
// typed: '' searchTypeOptions: [
// }), { 'code': 'text', 'label': 'Dans les textes' },
{ 'code': 'nominum', 'label': 'Dans les personnes' },
{ 'code': 'locorum', 'label': 'Dans les lieux' },
{ 'code': 'operum', 'label': 'Dans les objets' }
],
searchTypeValue: { 'code': 'text', 'label': 'Dans les textes' }
}),
computed: { computed: {
keys: { keys: {
get () { return this.$store.state.Search.keys }, get () { return this.$store.state.Search.keys },
@@ -59,6 +92,52 @@ export default {
submit () { submit () {
console.log('submited', this.keys) console.log('submited', this.keys)
this.getResults() this.getResults()
},
withPopper (dropdownList, component, { width }) {
/**
* We need to explicitly define the dropdown width since
* it is usually inherited from the parent with CSS.
*/
dropdownList.style.width = width
/**
* Here we position the dropdownList relative to the $refs.toggle Element.
*
* The 'offset' modifier aligns the dropdown so that the $refs.toggle and
* the dropdownList overlap by 1 pixel.
*
* The 'toggleClass' modifier adds a 'drop-up' class to the Vue Select
* wrapper so that we can set some styles for when the dropdown is placed
* above.
*/
const popper = createPopper(component.$refs.toggle, dropdownList, {
placement: 'top',
modifiers: [
{
name: 'offset',
options: {
offset: [0, -1]
}
},
{
name: 'toggleClass',
enabled: true,
phase: 'write',
fn ({ state }) {
component.$el.classList.toggle('drop-up', state.placement === 'top')
}
}]
})
/**
* To prevent memory leaks Popper needs to be destroyed.
* If you return function, it will be called just before dropdown is removed from DOM.
*/
return () => popper.destroy()
},
onSearchTypeSelected (e) {
console.log('onSearchTypeSelected', e)
this.searchTypeValue = e
} }
} }
} }
+3 -1
View File
@@ -5,11 +5,13 @@ import store from './store'
import Meta from 'vue-meta' import Meta from 'vue-meta'
import InfiniteLoading from 'vue-infinite-loading' import InfiniteLoading from 'vue-infinite-loading'
import VueScrollTo from 'vue-scrollto' import VueScrollTo from 'vue-scrollto'
import VueSelect from 'vue-select'
import App from './App' import App from './App'
import 'assets/css/mdi/css/materialdesignicons.css' import 'assets/css/mdi/css/materialdesignicons.css'
// import 'mdi/font' // import 'mdi/font'
import 'vue-select/src/scss/vue-select.scss'
import 'assets/css/app.scss' import 'assets/css/app.scss'
Vue.use(Meta) Vue.use(Meta)
@@ -30,7 +32,7 @@ Vue.use(InfiniteLoading, {
Vue.use(VueScrollTo) Vue.use(VueScrollTo)
// window.env = process.env Vue.component('v-select', VueSelect)
window.apipath = process.env === 'prod' ? `http://${window.location.hostname}/api` : 'http://localhost:8984' window.apipath = process.env === 'prod' ? `http://${window.location.hostname}/api` : 'http://localhost:8984'