Commit 35959d2b authored by Iker Hurtado's avatar Iker Hurtado
Browse files

Manual merge/integration of "new-search" branch into master + Several new search improvements (2)

FilterPanel.view.js deep refactoring
parent 5e855ad0
Pipeline #89806 skipped with stage
...@@ -36,18 +36,20 @@ class FilterPanel { ...@@ -36,18 +36,20 @@ class FilterPanel {
this.element = document.createElement('div'); this.element = document.createElement('div');
this.element.setAttribute("id",'filter-panel-placeholder'); this.element.setAttribute("id",'filter-panel-placeholder');
this.fieldsMap = new Map(); // Map keeping the properties Map<Map<>> this.fields = [];
let structureGroupBox = this.createPropsGroupBox('Structure') let structureGroupBox = this.createPropsGroupBox('Structure')
this.element.append(structureGroupBox); this.element.append(structureGroupBox);
structureGroupBox.append(this.createCheckboxesField('System type', 'system-type', [ const systemTypeField = new CheckboxesField('System type', 'system-type', [
{value: 'bulk', text: 'Bulk'}, {value: 'bulk', text: 'Bulk'},
{value: '2D', text: '2D'}, {value: '2D', text: '2D'},
{value: '1D', text: '1D'} {value: '1D', text: '1D'}
])); ]);
this.fields.push(systemTypeField)
structureGroupBox.append(systemTypeField.element); /// By looping*****
structureGroupBox.append(this.createCheckboxesField('Crystal system', 'crystal-system', [ const crystalSystemField = new CheckboxesField('Crystal system', 'crystal-system', [
{value: 'cubic', text: 'Cubic'}, {value: 'cubic', text: 'Cubic'},
{value: 'hexagonal', text: 'Hexagonal'}, {value: 'hexagonal', text: 'Hexagonal'},
{value: 'trigonal', text: 'Trigonal'}, {value: 'trigonal', text: 'Trigonal'},
...@@ -55,28 +57,35 @@ class FilterPanel { ...@@ -55,28 +57,35 @@ class FilterPanel {
{value: 'orthorhombic', text: 'Orthorhombic'}, {value: 'orthorhombic', text: 'Orthorhombic'},
{value: 'monoclinic', text: 'Monoclinic'}, {value: 'monoclinic', text: 'Monoclinic'},
{value: 'triclinic', text: 'Triclinic'}, {value: 'triclinic', text: 'Triclinic'},
])) ]);
this.fields.push(crystalSystemField)
structureGroupBox.append(crystalSystemField.element);
structureGroupBox.append(this.createSpaceGroupField());
structureGroupBox.append( const spaceGroupField = new SpaceGroupField();
this.createAutocompleteField('Structure type', "structure-type", 'structure_type')); this.fields.push(spaceGroupField)
structureGroupBox.append(spaceGroupField.element);
//structureGroupBox.append(this.createAutocompleteField('Strukturbericht designation', const structureTypeField = new AutocompleteField('Structure type', "structure-type", 'structure_type');
// "strukturbericht", 'strukturbericht_designation')); this.fields.push(structureTypeField)
structureGroupBox.append(structureTypeField.element);
// const structureTypeField = new AutocompleteField('Strukturbericht designation', "strukturbericht", 'strukturbericht_designation'));
let propertiesGroupBox = this.createPropsGroupBox('Properties') let propertiesGroupBox = this.createPropsGroupBox('Properties')
this.element.append(propertiesGroupBox); this.element.append(propertiesGroupBox);
propertiesGroupBox.append(this.createMassDensityField()); const massDensityField = new MassDensityField();
this.fields.push(massDensityField)
propertiesGroupBox.append(massDensityField.element);
propertiesGroupBox.append(this.createCheckboxesField('Results containing...', undefined, [ const boolValueFields = new CheckboxesField('Results containing...', undefined, [
{value: 'Band structure', text: 'Band structure', id: 'has-band-structure'}, {value: 'Band structure', text: 'Band structure', id: 'has-band-structure'},
{value: 'DOS', text: 'DOS', id: 'has-dos'}, {value: 'DOS', text: 'DOS', id: 'has-dos'},
{value: 'Thermal properties', text: 'Thermal properties', id: 'has-thermal-properties'}, {value: 'Thermal properties', text: 'Thermal properties', id: 'has-thermal-properties'},
])); ]);
this.fields.push(boolValueFields)
console.log('this.fieldsMap: ',this.fieldsMap) propertiesGroupBox.append(boolValueFields.element);
InfoSys.addToInfoSystem(this.element); InfoSys.addToInfoSystem(this.element);
...@@ -99,38 +108,119 @@ class FilterPanel { ...@@ -99,38 +108,119 @@ class FilterPanel {
} }
createCheckboxesField(name, id, valuesDesc){ getValues(){
let fieldElement = document.createElement('div'); let filterMap = new Map();
fieldElement.className = 'filter-quantity-box';
fieldElement.innerHTML = `<div class="field-title"> this.fields.forEach( field => {
<span info-sys-data="${id}">${name}</span> const values = field.getValues();
if (Array.isArray(values)){
values.forEach( value => filterMap.set(value.fieldId, value.value))
}else{
if (values && values.value.length > 0)
filterMap.set(values.fieldId, values.value)
}
});
console.log('FilterPanel getValues:', filterMap);
return filterMap;
}
setAddPropertiesListener(listener) {
this.addPropertiesListener= listener;
}
showSelectedProps(show){
this.fields.forEach( field => {
field.highlightSelected(show)
})
/*
let selectedPropBox = this.element.querySelector('.selected-props-view')
let values = this.getValues()
let html = ''
values.forEach( (value, key) => {
html += ` <h3>${key}</h3> <p>${value}</p>
`
} )
selectedPropBox.innerHTML = html
selectedPropBox.style.display = (show ? '' : 'none')
this.element.querySelector('.regular-view').style.display = (show ? 'none' : '')
*/
}
}
class CheckboxesField{
constructor(name, commonId, valuesDesc ){
this.commonId = commonId;
this.element = document.createElement('div');
this.element.className = 'filter-quantity-box';
this.element.innerHTML = `<div class="field-title">
<span info-sys-data="${commonId}">${name}</span>
</div>`; </div>`;
valuesDesc.forEach( valueDesc => { valuesDesc.forEach( valueDesc => {
let fieldId = id ? id : valueDesc.id; // id -> checkboxes related: only one field / no id -> every checkbox is and independent field let fieldId = commonId ? commonId : valueDesc.id; // commonId -> checkboxes related: only one field / no commonId -> every checkbox is and independent field
let infoSysValue = id ? (fieldId+'.value:'+valueDesc.value) : fieldId; let infoSysValue = commonId ? (fieldId+'.value:'+valueDesc.value) : fieldId;
let valueElement = document.createElement('div'); let valueElement = document.createElement('div');
valueElement.innerHTML = ` valueElement.innerHTML = `
<input type="checkbox" class="${fieldId}-field" value="${valueDesc.value}"> <input type="checkbox" class="${fieldId}-field" value="${valueDesc.value}">
<span info-sys-data="${infoSysValue}">${valueDesc.text}</span> <span info-sys-data="${infoSysValue}">${valueDesc.text}</span>
`; `;
fieldElement.append(valueElement); this.element.append(valueElement);
});
if (!id) this.fieldsMap.set(fieldId, valueElement); this.checkboxes = this.element.querySelectorAll('input');
}) }
if (id) this.fieldsMap.set(id, fieldElement); getValues(){
return fieldElement; if (this.commonId){
let values = [];
this.checkboxes.forEach( checkbox => {
if (checkbox.checked) values.push(checkbox.value);
});
return {fieldId: this.commonId, value: values};
}else{
let values = [];
this.checkboxes.forEach( checkbox => {
if (checkbox.checked) {
let s = checkbox.className;
values.push({fieldId: s.substring(0, s.indexOf('-field')), value: true});
}
});
return values;
}
}
highlightSelected(bool){
this.checkboxes.forEach( checkbox => {
if (checkbox.checked){
//checkbox.parentElement.style.backgroundColor = 'red'
checkbox.parentElement.style.opacity = ''//(bool ? '' : '')
}else{
checkbox.parentElement.style.opacity = (bool ? 0.1 : '')
}
});
} }
}
createSpaceGroupField(){ class SpaceGroupField{
let fieldElement = document.createElement('div'); constructor(){
fieldElement.className = 'filter-quantity-box'; this.element = document.createElement('div');
fieldElement.innerHTML = ` this.element.className = 'filter-quantity-box';
this.element.innerHTML = `
<div class="field-title"> <span info-sys-data="space-group">Space group</span></div> <div class="field-title"> <span info-sys-data="space-group">Space group</span></div>
<select id="space-group-dropdown-list"> <select id="space-group-dropdown-list">
<option value="by-number">by number</option> <option value="by-number">by number</option>
...@@ -138,144 +228,98 @@ class FilterPanel { ...@@ -138,144 +228,98 @@ class FilterPanel {
</select> </select>
<input type="text" class="space-group-textfield" style="width: 60px"> <input type="text" class="space-group-textfield" style="width: 60px">
`; `;
this.select = this.element.querySelector('select');
this.input = this.element.querySelector('input')
}
this.fieldsMap.set('space-group', fieldElement)
return fieldElement; getValues(){
let type = this.select.options[this.select.selectedIndex].value;
let propName = (type === 'by-number' ? 'space-group-number'
: 'space-group-international-short-symbol');
let value = this.input.value;
return ( value.trim() === '' ? null : { fieldId: propName, value: [value] } );
} }
highlightSelected(bool){
if (this.getValues() === null){
this.select.style.opacity = (bool ? 0.1 : '')
this.input.style.opacity = (bool ? 0.1 : '')
}
}
}
createAutocompleteField(name, id, apiId){
let fieldElement = document.createElement('div'); class AutocompleteField{
fieldElement.className = 'filter-quantity-box';
fieldElement.innerHTML = `<div class="field-title"> constructor(name, id, apiId){
this.fieldId = id
this.element = document.createElement('div');
this.element.className = 'filter-quantity-box';
this.element.innerHTML = `<div class="field-title">
<span info-sys-data="${id}">${name}</span> <span info-sys-data="${id}">${name}</span>
</div>`; </div>`;
let autocomplete = new AutocompleteMultiselectList(id); this.autocomplete = new AutocompleteMultiselectList(id);
autocomplete.element.placeholder = "Search and select options"; this.autocomplete.element.placeholder = "Search and select options";
autocomplete.element.classList.add('textfield-filter'); this.autocomplete.element.classList.add('textfield-filter');
fieldElement.append(autocomplete.element) this.element.append(this.autocomplete.element)
let r1 = util.serverReq(util.getSuggestionURL(apiId), (e) => { let r1 = util.serverReq(util.getSuggestionURL(apiId), (e) => {
let names = JSON.parse(r1.response)[apiId]; let names = JSON.parse(r1.response)[apiId];
autocomplete.autocomplete(names); this.autocomplete.autocomplete(names);
}); });
this.fieldsMap.set(id, autocomplete);
return fieldElement;
} }
createMassDensityField(){
let fieldElement = document.createElement('div');
fieldElement.className = 'filter-quantity-box';
fieldElement.innerHTML = `
<div class="field-title"><span info-sys-data="mass-density">Mass density</span> <span style="font-weight: normal;">(kg/m<sup>3</sup>)</span></div>
Min: <input type="text" class="mass-density-min-field">&nbsp;&nbsp;
Max: <input type="text" class="mass-density-max-field">
`;
this.fieldsMap.set('mass-density', fieldElement)
return fieldElement;
}
getValues(){ getValues(){
const values = this.autocomplete.getSelected();
let filterMap = new Map(); return ( values.length === 0 ? null : { fieldId: this.fieldId, value: values } );
this.addValuesFromCheckboxes(filterMap,'system-type');
this.addValuesFromCheckboxes(filterMap, 'crystal-system');
this.addSpaceGroupValue(filterMap)
this.addValuesFromAutocompleteField(filterMap, 'structure-type')
//this.addValuesFromAutocompleteField(filterMap, 'strukturbericht')
this.addRangeValue(filterMap, 'mass-density');
this.addValuesFromBoolCheckboxes(filterMap,
['has-band-structure', 'has-dos', 'has-thermal-properties']);
console.log('FilterPanel getValues:', filterMap);
return filterMap;
} }
highlightSelected(bool){
if (this.getValues() === null)
this.autocomplete.element.style.opacity = (bool ? 0.1 : '')
addValuesFromCheckboxes(filterMap, fieldId){
let checkboxes = this.fieldsMap.get(fieldId).querySelectorAll('input');
let value = [];
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked) value.push(checkboxes[i].value);
}
if (value.length > 0) filterMap.set(fieldId, value);
} }
}
addSpaceGroupValue(filterMap){ class MassDensityField{
let propName;
let select = this.fieldsMap.get('space-group').querySelector('select');
let type = select.options[select.selectedIndex].value;
if (type === 'by-number') propName = 'space-group-number';
else propName = 'space-group-international-short-symbol';
let value = this.fieldsMap.get('space-group').querySelector('input').value;
if (value.trim() !== '') filterMap.set(propName, [value]);
//if (reset) field.selectedIndex = 0;
}
addValuesFromAutocompleteField(filterMap, fieldId){ constructor(){
let values = this.fieldsMap.get(fieldId).getSelected(); this.element = document.createElement('div');
if (values.length > 0) filterMap.set(fieldId, values); this.element.className = 'filter-quantity-box';
this.element.innerHTML = `
<div class="field-title">
<span info-sys-data="mass-density">Mass density</span>
<span style="font-weight: normal;">(kg/m<sup>3</sup>)</span>
</div>
<div>
Min: <input type="text" class="mass-density-min-field">&nbsp;&nbsp;
Max: <input type="text" class="mass-density-max-field">
</div>
`;
this.inputs = this.element.querySelectorAll('input');
} }
addRangeValue(filterMap, fieldId){ getValues(){
const inputs = this.fieldsMap.get(fieldId).querySelectorAll('input');
let value = ':'; let value = ':';
if (inputs[0].value !== ''){ // Min value if (this.inputs[0].value.trim() !== ''){ // Min value
value = inputs[0].value+value; value = this.inputs[0].value+value;
} }
if (inputs[1].value !== ''){ // Max value if (this.inputs[1].value.trim() !== ''){ // Max value
value = value+inputs[1].value; value = value+this.inputs[1].value;
} }
if (value !== ':') filterMap.set(fieldId, value); return ( value === ':' ? null : { fieldId: 'mass-density', value: value } );
} }
highlightSelected(bool){
addValuesFromBoolCheckboxes(filterMap, fieldIds){ if (this.getValues() === null)
fieldIds.forEach( fieldId => { this.inputs[0].parentElement.style.opacity = (bool ? 0.1 : '')
let checkbox = this.fieldsMap.get(fieldId).querySelector('input');
if (checkbox.checked) filterMap.set(fieldId, true);
});
}
setAddPropertiesListener(listener) {
this.addPropertiesListener= listener;
}
showSelectedProps(show){
/*
let selectedPropBox = this.element.querySelector('.selected-props-view')
let values = this.getValues()
let html = ''
values.forEach( (value, key) => {
html += ` <h3>${key}</h3> <p>${value}</p>
`
} )
selectedPropBox.innerHTML = html
selectedPropBox.style.display = (show ? '' : 'none')
this.element.querySelector('.regular-view').style.display = (show ? 'none' : '')
*/
} }
} }
// EXPORTS // EXPORTS
......
...@@ -358,10 +358,10 @@ class NewSearchMod { ...@@ -358,10 +358,10 @@ class NewSearchMod {
mainSideElem.addEventListener( "mouseenter", event => { mainSideElem.addEventListener( "mouseenter", event => {
// console.log('filters:', this.filterPanel.getValues()) // console.log('filters:', this.filterPanel.getValues())
//this.filterPanel.showSelectedProps(true) this.filterPanel.showSelectedProps(true)
}); });
mainSideElem.addEventListener( "mouseleave", event => { mainSideElem.addEventListener( "mouseleave", event => {
//this.filterPanel.showSelectedProps(false) this.filterPanel.showSelectedProps(false)
}); });
/* /*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment