- vuejs solr faceted search

- with extra display for active filter items
This commit is contained in:
Arno Kaimbacher 2019-10-10 12:58:13 +02:00
parent c596a620cc
commit a95282e49e
15 changed files with 261 additions and 120 deletions

View file

@ -2,17 +2,31 @@ import axios from "axios";
export default {
async search(term) {
async search(term, filterItems) {
// solr endpoint
// const host = 'http://voyagerdemo.com/';
const host = 'https://repository.geologie.ac.at/';
const path = 'solr/rdr_data/select';
const fields = 'id,server_date_published,abstract_output,title_output,title_additional,author,subject'; // fields we want returned
const dismaxFields = "title^3 abstract^2 subject^1";
const facetFields = "facet.field=language&facet.field={!key=datatype}doctype";//&fq=year:(2019)";//&facet.query=year:2018";
const facetFields = "facet.field=language&facet.field={!key=datatype}doctype&facet.field=subject";//&fq=year:(2019)";//&facet.query=year:2018";
var filterFields = "";
// filterItems.forEach(function (item) {
// console.log(item.value + " " + item.category);
// filterFields += "&fq=" + item.category +":("+ item.value + ")";
// });
Object.entries(filterItems).forEach(([key, valueArray]) => {
// console.log(`${key} ${valueArray}`);
valueArray.forEach(function (value) {
filterFields += "&fq=" + key +":("+ value + ")";
});
});
// $dismax->setQueryFields('title^3 abstract^2 subject^1');
const api = `${host}${path}?defType=dismax&q=${term}&fl=${fields}&qf=${dismaxFields}&facet=on&${facetFields}&wt=json&rows=20&indent=on`;
const api = `${host}${path}?defType=dismax&q=${term}&fl=${fields}&qf=${dismaxFields}&facet=on&${facetFields}&${filterFields}&wt=json&rows=20&indent=on`;
const res = await axios.get(api);
return res.data;//.response;//.docs;

View file

@ -1,67 +1,79 @@
import { Component, Vue, Prop, Provide } from 'vue-property-decorator';
@Component
export default class FacetList extends Vue {
ITEMS_PER_FILTER = 5;
bar = 'bar';
// filterItems = [];
ITEMS_PER_FILTER = 2;
bar = '';
collapsed = true;
// filterItems = [];
@Prop()
data;
@Prop()
@Prop([String])
filterName;
get myLanguageFilters() {
// console.log(this.filterName);
// console.log(this.data);
var facetValues = this.data.map((facet, i) => {
if (i % 2 === 0) {
// var rObj = {};
// rObj['value'] = facet;
// rObj['count'] = solrArray[i +1];
var rObj = { value: facet, count: this.data[i + 1] };
return rObj;
}
}).filter(function (el) {
return el != null && el.count > 0;
});
// var facetValues = this.data.language.filter(function(facet, i) {
// return i % 2 === 0;
// }).map(function (facet, i) {
// var rObj = { value: facet, count: this.data.language[i + 1] };
// return rObj;
// }, this);
return facetValues;
};
get facets() {
return this.data;
};
@Prop([String])
// alias;
get alias() {
return this.filterName == 'datatype' ? 'doctype' : this.filterName
}
// get filterItems() {
// var facetValues = this.data.map((facet, i) => {
// if (i % 2 === 0) {
// // var rObj = {};
// // rObj['value'] = facet;
// // rObj['count'] = solrArray[i +1];
// var rObj = { value: facet, count: this.data[i + 1], category: this.alias };
// return rObj;
// }
// }).filter(function (el) {
// return el != null && el.count > 0;
// });
// // var facetValues = this.data.language.filter(function(facet, i) {
// // return i % 2 === 0;
// // }).map(function (facet, i) {
// // var rObj = { value: facet, count: this.data.language[i + 1] };
// // return rObj;
// // }, this);
// return facetValues;
// }
get filterItems() {
var facetValues = this.data.map((facet, i) => {
if (i % 2 === 0) {
// var rObj = {};
// rObj['value'] = facet;
// rObj['count'] = solrArray[i +1];
var rObj = { value: facet, count: this.data[i + 1] };
return rObj;
}
}).filter(function (el) {
return el != null && el.count > 0;
});
// var facetValues = this.data.language.filter(function(facet, i) {
// return i % 2 === 0;
// }).map(function (facet, i) {
// var rObj = { value: facet, count: this.data.language[i + 1] };
// return rObj;
// }, this);
return facetValues;
};
return this.data;
}
mounted() {
};
get overflowing() {
//ko.observable(self.filterItems().length - self.activeFilterItems().length > ITEMS_PER_FILTER);
return (this.filterItems.length) > this.ITEMS_PER_FILTER;
}
get uncollapseLabelText() {
if (this.collapsed == true) {
// return myLabels.viewer.sidePanel.more; //"More results";
return "More results";
}
else {
// return myLabels.viewer.sidePanel.collapse; //"Collapse";
return "Collapse";
}
}
toggle = function () {
if (this.collapsed == true) {
this.collapsed = false;
}
else if (this.collapsed == false) {
this.collapsed = true;
//list.children("li:gt(4)").hide();
}
}
activateItem = function (filterItem) {
filterItem.Category = this.alias;
filterItem.Active = true;
this.$emit("filter", filterItem);
}
mounted() {
}
}

View file

@ -5,28 +5,24 @@
<div class="panel panel-primary">
<h3 class="panel-title filterViewModelName">{{ filterName }}</h3>
<!-- e.g.language -->
<ul
class="filter-items"
v-for="(value, index) in myLanguageFilters"
:key="index"
v-bind:class="{'limited':filterItems.length > 1}"
>
<li class="active" role="radio">
<input
<ul class="filter-items" v-bind:class="{'limited':filterItems.length > 1 && collapsed }">
<li v-for="(item, index) in filterItems" :key="index" class="list-group-item">
<!-- <input
class="css-w1gpbi"
name="language"
v-bind:id="value.value"
v-bind:id="item.value"
type="radio"
v-bind:value="value.value"
v-bind:value="item.value"
/>
<label :for="value.value">
<span>{{ value.value }} ({{ value.count }})</span>
</label>
<label :for="item.value">
<span click: @click="activateItem(item)">{{ item.value }} ({{ item.count }})</span>
</label>-->
<a :class="Active ? 'disabled' : ''" @click.prevent="activateItem(item)">{{ item.value }} ({{ item.count }})</a>
</li>
</ul>
<ul class="overflowing">
<ul class="overflowing" v-if="overflowing == true">
<li>
<span @click="toggle()"></span>
<span @click="toggle()">{{ uncollapseLabelText }}</span>
</li>
</ul>
</div>
@ -35,4 +31,12 @@
<script lang="ts">
import FacetList from "./facet-list-class";
export default FacetList;
</script>
</script>
<style scoped>
/* local styles */
.disabled {
color: lightgrey;
pointer-events: none;
}
</style>