Commit c9532890 authored by Iker Hurtado's avatar Iker Hurtado
Browse files

First search filter implementation completed and several more improvements

parent 716a86e2
......@@ -111,7 +111,6 @@
this.element = document.querySelector('#breadcrumb-placeholder');
this.element.innerHTML = `
<span class="goto-page Search">Search</span>
<span class="goto-page Results">&nbsp; > &nbsp; <span>Results</span></span>
<span class="goto-page Overview">&nbsp; > &nbsp; <span>Overview</span></span>
<span class="Details">
&nbsp; > &nbsp;
......@@ -124,7 +123,6 @@
</select>
</span>
`;
this.resultsSel = this.element.querySelector('.Results');
this.overviewSel = this.element.querySelector('.Overview');
this.detailsSel = this.element.querySelector('.Details');
this.detailsDropDown = this.element.querySelector('.details-dropdown');
......@@ -133,9 +131,6 @@
this.element.querySelector('.Search').addEventListener( "click", e => {
util.setBrowserHashPath('search');
});
this.resultsSel.addEventListener( "click", e => {
util.setBrowserHashPath('search/results');
});
this.overviewSel.addEventListener('click', () => {
util.setBrowserHashPath('material', util.materialId);
......@@ -162,8 +157,6 @@
setState(appModule, param){
let resultsSetLabel = this.resultsSel.querySelector('span');
resultsSetLabel.style.fontWeight = 'normal';
let overviewSelLabel = this.overviewSel.querySelector('span');
overviewSelLabel.style.fontWeight = 'normal';
......@@ -182,7 +175,6 @@
}else if (appModule === 'material'){
this.element.style.visibility = 'visible';
this.resultsSel.style.display = (util.searchResults ? 'inline' : 'none');
this.overviewSel.style.display = 'inline';
if (param === undefined){ // Overview page
......@@ -7822,10 +7814,10 @@
this.searchQuery.forEach( (item, i) => {
if (this.queryTypes[i] === 'F'){
queryObj.bool.filter.push(getESSimpleMatch('formula_reduced', item));
queryObj.bool.filter.push(this._getESSimpleMatch('formula_reduced', item));
}else if (this.queryTypes[i] === 'MN'){
queryObj.bool.filter.push(getESSimpleMatch('material_name', item));
queryObj.bool.filter.push(this._getESSimpleMatch('material_name', item));
}
else if (this.queryTypes[i] === 'E') elements.push(item);
//else if (this.queryTypes[i] !== 'S'){ // property }
......@@ -7887,17 +7879,9 @@
this.element.querySelector('.add-box').style.display = 'none';
}
*/
function getESSimpleMatch(field, value){
return {
"match": { [field] : value }
};
}
});
this.cleanButton.addEventListener( "click", (e) => {
this.searchQuery = [];
this.queryTypes = [];
......@@ -7968,8 +7952,6 @@
}
});
}
......@@ -7977,27 +7959,36 @@
//let filters = [];
filterMap.forEach((values/*Array*/, filterName) => {
if ('mass-density'){
let massDensity = values.split(':');
let massDensityObj = {
"range": {
"mass_density": { "gte" : massDensity[0], "lte" : massDensity[1] }
}
};
queryFilterArray.push( massDensityObj );
}else{ // normal case
let filterNameDef = replaceDashes(filterName);
queryFilterArray.push( this._getFieldESMatch(filterNameDef, values, false) );
}
let filterNameDef = replaceDashes(filterName);
if (filterName === 'mass-density' || filterName === 'band-gap'){
//***** util.eV2J() apply?
queryFilterArray.push( this._getFieldESRange(filterNameDef, values) );
}else if (filterName === 'band-gap-type'){ // special case
if ( values !== 'both')
queryFilterArray.push( this._getESSimpleMatch('band_gap_direct',
( values === 'direct' ? true : false ) ) );
}else if (filterName.startsWith('has')){ // has- filters
queryFilterArray.push( this._getESSimpleMatch(filterNameDef, values, false) );
}else{ // normal case
queryFilterArray.push( this._getFieldESMatch(filterNameDef, values, false) );
}
});
//return filters;
}
_getESSimpleMatch(field, value){
return {
"match": { [field] : value }
};
}
_getFieldESMatch(field, elements, and = true){
let elementsString = '';
if (elements.length > 0) elementsString = elements.join(' ');
......@@ -8013,6 +8004,18 @@
}
_getFieldESRange(field, valuesString){
let data = valuesString.split(':');
console.log('_getFieldESRange data', data);
return {
"range": {
[field]: { "gte" : parseInt(data[0]), "lte" : parseInt(data[1]) }
}
};
}
_setTabSelectedStyles(element, value){
/*
element.style.fontWeight = (value ? 'bold' : 'normal');
......@@ -9276,9 +9279,9 @@
<div class="field" style="padding-top: 28px;">
<input type="radio" name="band-gap-type" value="d"> Direct<br>
<input type="radio" name="band-gap-type" value="i"> Indirect<br>
<input type="radio" name="band-gap-type" value="d/i" checked> Both<br>
<input type="radio" name="band-gap-type" value="direct"> Direct<br>
<input type="radio" name="band-gap-type" value="indirect"> Indirect<br>
<input type="radio" name="band-gap-type" value="both" checked> Both<br>
</div>
......@@ -9315,18 +9318,6 @@
this.slider.setRange(0,10000);
this.testSlider.appendChild(this.slider.element);
*/
// this.checkbox.checked
this._events();
}
_events() {
/*
let panel = this.element.querySelector('.properties-box-panel');
panel.addEventListener( 'input', e => { this.checkPropsValues(); });
panel.addEventListener( 'change', e => { this.checkPropsValues(); });
*/
}
......@@ -9336,35 +9327,17 @@
let filterMap = new Map();
this.addFilterFromTextField(filterMap, 'space-group-number');
this.addFilterFromCheckboxes(filterMap,'system-type');
this.addMassDensityFilter(filterMap);
this.addRangeFilter(filterMap, 'mass-density');
this.addFilterFromDropdownList(filterMap, 'structure-type');
this.addFilterFromCheckboxes(filterMap, 'crystal-system');
this.addRangeFilter(filterMap, 'band-gap');
this.addBandgapTypeFilter(filterMap);
this.addFiltersFromBoolCheckboxes(filterMap,
['has-band-structure', 'has-dos', 'has-fermi-surface', 'has-thermal-properties']);
console.log('FilterPanel selected:', filterMap);
return filterMap;
}
/*
getPropsWithValueFromCurrentTab(reset){
//console.log('andButton: ',tabString);
let propsMap = new Map();
if (tabString === 'structure'){
this.addPropsFromTextFields(propsMap,['space-group-number'], reset);
this.addPropsFromDropdownList(propsMap,['structure-type'], reset);
this.addPropsFromCheckboxes(propsMap,['system-type','crystal-system'], reset);
this.addMassDensityProps(propsMap, reset);
}else if (tabString === 'results'){
this.addBandgapProps(propsMap, reset);
this.addPropsFromCheckboxes(propsMap,['has-band-structure', 'has-dos',
'has-fermi-surface', 'has-thermal-properties'], reset);
}else if (tabString === 'method'){
this.addPropsFromCheckboxes(propsMap,['functional-type','basis-set-type'], reset);
this.addPropsFromDropdownList(propsMap,['code-name'], reset);
}//else if (this.tabSelected.className === 'contributors-tab'){
//this.addPropsFromTextFields(propsMap,['contributors']);}
return propsMap;
}
*/
addFilterFromTextField(filterMap, filterName){
......@@ -9389,10 +9362,9 @@
//if (reset) field.selectedIndex = 0;
}
addMassDensityFilter(filterMap){
let minField = document.querySelector('.mass-density-min-field');
let maxField = document.querySelector('.mass-density-max-field');
let fieldName = 'mass-density';
addRangeFilter(filterMap, filterName){
let minField = document.querySelector('.'+filterName+'-min-field');
let maxField = document.querySelector('.'+filterName+'-max-field');
let value = ':';
//let label = 'Mass Density';
if (minField.value !== ''){
......@@ -9405,72 +9377,29 @@
value = value+maxField.value;
//if (reset) maxField.value = '';
}
if (value !== ':') filterMap.set(fieldName, value);
if (value !== ':') filterMap.set(filterName, value);
}
addPropsFromTextFields(propsMap,propsArray, reset = false){
propsArray.forEach(propName => {
let field = this.element.querySelector('.'+propName+'-field');
if (field.value !== ''){
propsMap.set(propName, [field.value]);
if (reset) field.value = '';
}
});
addBandgapTypeFilter(filterMap){
let val = document.querySelector('input[name="band-gap-type"]:checked').value;
filterMap.set("band-gap-type", val);
}
addPropsFromCheckboxes(propsMap,propsArray, reset){
propsArray.forEach(propName => {
let checkboxes = this.element.querySelectorAll('.'+propName+'-field');
let value = [];
addFiltersFromBoolCheckboxes(filterMap, boolFilters){
boolFilters.forEach( filterName => {
let checkboxes = this.element.querySelectorAll('.'+filterName+'-field');
//let value = [];
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked){
value.push(checkboxes[i].value);
if (reset) checkboxes[i].checked = false;
//value.push(checkboxes[i].value);
filterMap.set(filterName, true);
}
}
if (value.length > 0) propsMap.set(propName, value);
//if (value.length > 0) propsMap.set(propName, value);
});
}
addPropsFromDropdownList(propsMap,propsArray, reset){
propsArray.forEach(propName => {
let field = this.element.querySelector('.'+propName+'-field');
let value = field.options[field.selectedIndex].value;
if (value.length > 2) propsMap.set(propName, [value]);
if (reset) field.selectedIndex = 0;
});
}
addBandgapProps(propsMap, reset){
let minField = document.querySelector('.band-gap-min-field');
let maxField = document.querySelector('.band-gap-max-field');
let fieldName = 'band-gap';
let label = 'Band Gap';
if (minField.value !== ''){
label = minField.value+' < '+label;
fieldName += ':'+minField.value;
if (reset) minField.value = '';
}
if (maxField.value !== ''){
label += ' < '+maxField.value;
fieldName += ':'+maxField.value;
if (reset) maxField.value = '';
}
if (label !== 'Band Gap'){
let val = document.querySelector('input[name="band-gap-type"]:checked').value;
if (val === 'd') fieldName += ':True';
else if (val === 'i') fieldName += ':False';
propsMap.set(fieldName, [label+' '+val]);
}
}
setAddPropertiesListener(listener) {
this.addPropertiesListener= listener;
......
......@@ -427,50 +427,6 @@ div.title span.unfolded::before{
}
#search-properties-box{
background-color: #DDD;
padding: 4px;
height: 370px;
}
.props-box-tabs-wrapper{
background-color: #EEE;
height: 100%;
}
.properties-box-tabs div{
padding: 20px;
font-size: 0.9em;
border-bottom: 1px solid #DDD;
background-color: #EEE;
cursor: pointer;
text-align: center;
}
.properties-box-tabs div.props-tab-selected{
font-weight: bold;
color: #E56400;
background-color: #DDD;
}
.props-tab-panel{
padding: 10px 60px;
font-size: 0.8em;
display: none;
}
.properties-box-enter-button{
text-align: right;
}
.properties-box-enter-button button{
margin: 8px 20px;
padding: 9px;
}
.field{
margin-bottom: 16px;
}
......
......@@ -65,7 +65,6 @@ class Breadcrumb {
this.element = document.querySelector('#breadcrumb-placeholder');
this.element.innerHTML = `
<span class="goto-page Search">Search</span>
<span class="goto-page Results">&nbsp; > &nbsp; <span>Results</span></span>
<span class="goto-page Overview">&nbsp; > &nbsp; <span>Overview</span></span>
<span class="Details">
&nbsp; > &nbsp;
......@@ -78,7 +77,6 @@ class Breadcrumb {
</select>
</span>
`;
this.resultsSel = this.element.querySelector('.Results');
this.overviewSel = this.element.querySelector('.Overview');
this.detailsSel = this.element.querySelector('.Details');
this.detailsDropDown = this.element.querySelector('.details-dropdown');
......@@ -87,9 +85,6 @@ class Breadcrumb {
this.element.querySelector('.Search').addEventListener( "click", e => {
util.setBrowserHashPath('search');
});
this.resultsSel.addEventListener( "click", e => {
util.setBrowserHashPath('search/results');
});
this.overviewSel.addEventListener('click', () => {
util.setBrowserHashPath('material', util.materialId);
......@@ -116,8 +111,6 @@ class Breadcrumb {
setState(appModule, param){
let resultsSetLabel = this.resultsSel.querySelector('span');
resultsSetLabel.style.fontWeight = 'normal';
let overviewSelLabel = this.overviewSel.querySelector('span');
overviewSelLabel.style.fontWeight = 'normal';
......@@ -136,7 +129,6 @@ class Breadcrumb {
}else if (appModule === 'material'){
this.element.style.visibility = 'visible';
this.resultsSel.style.display = (util.searchResults ? 'inline' : 'none');
this.overviewSel.style.display = 'inline';
if (param === undefined){ // Overview page
......
......@@ -98,9 +98,9 @@ class FilterPanel {
<div class="field" style="padding-top: 28px;">
<input type="radio" name="band-gap-type" value="d"> Direct<br>
<input type="radio" name="band-gap-type" value="i"> Indirect<br>
<input type="radio" name="band-gap-type" value="d/i" checked> Both<br>
<input type="radio" name="band-gap-type" value="direct"> Direct<br>
<input type="radio" name="band-gap-type" value="indirect"> Indirect<br>
<input type="radio" name="band-gap-type" value="both" checked> Both<br>
</div>
......@@ -137,18 +137,6 @@ class FilterPanel {
this.slider.setRange(0,10000);
this.testSlider.appendChild(this.slider.element);
*/
// this.checkbox.checked
this._events();
}
_events() {
/*
let panel = this.element.querySelector('.properties-box-panel');
panel.addEventListener( 'input', e => { this.checkPropsValues(); });
panel.addEventListener( 'change', e => { this.checkPropsValues(); });
*/
}
......@@ -158,35 +146,17 @@ class FilterPanel {
let filterMap = new Map();
this.addFilterFromTextField(filterMap, 'space-group-number');
this.addFilterFromCheckboxes(filterMap,'system-type');
this.addMassDensityFilter(filterMap);
this.addRangeFilter(filterMap, 'mass-density');
this.addFilterFromDropdownList(filterMap, 'structure-type');
this.addFilterFromCheckboxes(filterMap, 'crystal-system');
this.addRangeFilter(filterMap, 'band-gap');
this.addBandgapTypeFilter(filterMap);
this.addFiltersFromBoolCheckboxes(filterMap,
['has-band-structure', 'has-dos', 'has-fermi-surface', 'has-thermal-properties']);
console.log('FilterPanel selected:', filterMap);
return filterMap;
}
/*
getPropsWithValueFromCurrentTab(reset){
//console.log('andButton: ',tabString);
let propsMap = new Map();
if (tabString === 'structure'){
this.addPropsFromTextFields(propsMap,['space-group-number'], reset);
this.addPropsFromDropdownList(propsMap,['structure-type'], reset);
this.addPropsFromCheckboxes(propsMap,['system-type','crystal-system'], reset);
this.addMassDensityProps(propsMap, reset);
}else if (tabString === 'results'){
this.addBandgapProps(propsMap, reset);
this.addPropsFromCheckboxes(propsMap,['has-band-structure', 'has-dos',
'has-fermi-surface', 'has-thermal-properties'], reset);
}else if (tabString === 'method'){
this.addPropsFromCheckboxes(propsMap,['functional-type','basis-set-type'], reset);
this.addPropsFromDropdownList(propsMap,['code-name'], reset);
}//else if (this.tabSelected.className === 'contributors-tab'){
//this.addPropsFromTextFields(propsMap,['contributors']);}
return propsMap;
}
*/
addFilterFromTextField(filterMap, filterName){
......@@ -211,10 +181,9 @@ class FilterPanel {
//if (reset) field.selectedIndex = 0;
}
addMassDensityFilter(filterMap){
let minField = document.querySelector('.mass-density-min-field');
let maxField = document.querySelector('.mass-density-max-field');
let fieldName = 'mass-density';
addRangeFilter(filterMap, filterName){
let minField = document.querySelector('.'+filterName+'-min-field');
let maxField = document.querySelector('.'+filterName+'-max-field');
let value = ':';
//let label = 'Mass Density';
if (minField.value !== ''){
......@@ -227,72 +196,29 @@ class FilterPanel {
value = value+maxField.value;
//if (reset) maxField.value = '';
}
if (value !== ':') filterMap.set(fieldName, value);
if (value !== ':') filterMap.set(filterName, value);
}
addPropsFromTextFields(propsMap,propsArray, reset = false){
propsArray.forEach(propName => {
let field = this.element.querySelector('.'+propName+'-field');
if (field.value !== ''){
propsMap.set(propName, [field.value]);
if (reset) field.value = '';
}
});
addBandgapTypeFilter(filterMap){
let val = document.querySelector('input[name="band-gap-type"]:checked').value;
filterMap.set("band-gap-type", val);
}
addPropsFromCheckboxes(propsMap,propsArray, reset){
propsArray.forEach(propName => {
let checkboxes = this.element.querySelectorAll('.'+propName+'-field');
let value = [];
addFiltersFromBoolCheckboxes(filterMap, boolFilters){
boolFilters.forEach( filterName => {
let checkboxes = this.element.querySelectorAll('.'+filterName+'-field');
//let value = [];
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked){
value.push(checkboxes[i].value);
if (reset) checkboxes[i].checked = false;
//value.push(checkboxes[i].value);
filterMap.set(filterName, true);
}
}
if (value.length > 0) propsMap.set(propName, value);
//if (value.length > 0) propsMap.set(propName, value);
});
}
addPropsFromDropdownList(propsMap,propsArray, reset){
propsArray.forEach(propName => {
let field = this.element.querySelector('.'+propName+'-field');
let value = field.options[field.selectedIndex].value;
if (value.length > 2) propsMap.set(propName, [value]);
if (reset) field.selectedIndex = 0;
});
}
addBandgapProps(propsMap, reset){
let minField = document.querySelector('.band-gap-min-field');
let maxField = document.querySelector('.band-gap-max-field');
let fieldName = 'band-gap';
let label = 'Band Gap';
if (minField.value !== ''){
label = minField.value+' < '+label;
fieldName += ':'+minField.value;
if (reset) minField.value = '';
}
if (maxField.value !== ''){
label += ' < '+maxField.value;
fieldName += ':'+maxField.value;
if (reset) maxField.value = '';
}
if (label !== 'Band Gap'){
let val = document.querySelector('input[name="band-gap-type"]:checked').value;
if (val === 'd') fieldName += ':True';
else if (val === 'i') fieldName += ':False';
propsMap.set(fieldName, [label+' '+val]);
}
}
setAddPropertiesListener(listener) {
this.addPropertiesListener= listener;
......
......@@ -207,10 +207,10 @@ class NewSearchMod {
this.searchQuery.forEach( (item, i) => {
if (this.queryTypes[i] === 'F'){
queryObj.bool.filter.push(getESSimpleMatch('formula_reduced', item));
queryObj.bool.filter.push(this._getESSimpleMatch('formula_reduced', item));
}else if (this.queryTypes[i] === 'MN'){
queryObj.bool.filter.push(getESSimpleMatch('material_name', item));
queryObj.bool.filter.push(this._getESSimpleMatch('material_name', item));
}
else if (this.queryTypes[i] === 'E') elements.push(item);
//else if (this.queryTypes[i] !== 'S'){ // property }
......@@ -272,17 +272,9 @@ class NewSearchMod {
this.element.querySelector('.add-box').style.display = 'none';
}
*/
function getESSimpleMatch(field, value){
return {
"match": { [field] : value }
};
}
});
this.cleanButton.addEventListener( "click", (e) => {
this.searchQuery = [];