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 {
this.element = document.createElement('div');
this.element.setAttribute("id",'filter-panel-placeholder');
this.fieldsMap = new Map(); // Map keeping the properties Map<Map<>>
this.fields = [];
let structureGroupBox = this.createPropsGroupBox('Structure')
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: '2D', text: '2D'},
{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: 'hexagonal', text: 'Hexagonal'},
{value: 'trigonal', text: 'Trigonal'},
......@@ -55,28 +57,35 @@ class FilterPanel {
{value: 'orthorhombic', text: 'Orthorhombic'},
{value: 'monoclinic', text: 'Monoclinic'},
{value: 'triclinic', text: 'Triclinic'},
]))
]);
this.fields.push(crystalSystemField)
structureGroupBox.append(crystalSystemField.element);
structureGroupBox.append(this.createSpaceGroupField());
structureGroupBox.append(
this.createAutocompleteField('Structure type', "structure-type", 'structure_type'));
const spaceGroupField = new SpaceGroupField();
this.fields.push(spaceGroupField)
structureGroupBox.append(spaceGroupField.element);
//structureGroupBox.append(this.createAutocompleteField('Strukturbericht designation',
// "strukturbericht", 'strukturbericht_designation'));
const structureTypeField = new AutocompleteField('Structure type', "structure-type", 'structure_type');
this.fields.push(structureTypeField)
structureGroupBox.append(structureTypeField.element);
// const structureTypeField = new AutocompleteField('Strukturbericht designation', "strukturbericht", 'strukturbericht_designation'));
let propertiesGroupBox = this.createPropsGroupBox('Properties')
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: 'DOS', text: 'DOS', id: 'has-dos'},
{value: 'Thermal properties', text: 'Thermal properties', id: 'has-thermal-properties'},
]));
console.log('this.fieldsMap: ',this.fieldsMap)
]);
this.fields.push(boolValueFields)
propertiesGroupBox.append(boolValueFields.element);
InfoSys.addToInfoSystem(this.element);
......@@ -99,38 +108,119 @@ class FilterPanel {
}
createCheckboxesField(name, id, valuesDesc){
getValues(){
let fieldElement = document.createElement('div');
fieldElement.className = 'filter-quantity-box';
fieldElement.innerHTML = `<div class="field-title">
<span info-sys-data="${id}">${name}</span>
let filterMap = new Map();
this.fields.forEach( field => {
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>`;
valuesDesc.forEach( valueDesc => {
let fieldId = id ? id : valueDesc.id; // id -> checkboxes related: only one field / no id -> every checkbox is and independent field
let infoSysValue = id ? (fieldId+'.value:'+valueDesc.value) : fieldId;
let fieldId = commonId ? commonId : valueDesc.id; // commonId -> checkboxes related: only one field / no commonId -> every checkbox is and independent field
let infoSysValue = commonId ? (fieldId+'.value:'+valueDesc.value) : fieldId;
let valueElement = document.createElement('div');
valueElement.innerHTML = `
<input type="checkbox" class="${fieldId}-field" value="${valueDesc.value}">
<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');
}
getValues(){
if (id) this.fieldsMap.set(id, 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){
return fieldElement;
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');
fieldElement.className = 'filter-quantity-box';
fieldElement.innerHTML = `
constructor(){
this.element = document.createElement('div');
this.element.className = 'filter-quantity-box';
this.element.innerHTML = `
<div class="field-title"> <span info-sys-data="space-group">Space group</span></div>
<select id="space-group-dropdown-list">
<option value="by-number">by number</option>
......@@ -138,144 +228,98 @@ class FilterPanel {
</select>
<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){
class AutocompleteField{
let fieldElement = document.createElement('div');
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>
</div>`;
let autocomplete = new AutocompleteMultiselectList(id);
autocomplete.element.placeholder = "Search and select options";
autocomplete.element.classList.add('textfield-filter');
fieldElement.append(autocomplete.element)
this.autocomplete = new AutocompleteMultiselectList(id);
this.autocomplete.element.placeholder = "Search and select options";
this.autocomplete.element.classList.add('textfield-filter');
this.element.append(this.autocomplete.element)
let r1 = util.serverReq(util.getSuggestionURL(apiId), (e) => {
let names = JSON.parse(r1.response)[apiId];
autocomplete.autocomplete(names);
this.autocomplete.autocomplete(names);
});
}
this.fieldsMap.set(id, autocomplete);
getValues(){
const values = this.autocomplete.getSelected();
return ( values.length === 0 ? null : { fieldId: this.fieldId, value: values } );
}
return fieldElement;
highlightSelected(bool){
if (this.getValues() === null)
this.autocomplete.element.style.opacity = (bool ? 0.1 : '')
}
}
createMassDensityField(){
class MassDensityField{
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>
constructor(){
this.element = document.createElement('div');
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.fieldsMap.set('mass-density', fieldElement)
return fieldElement;
this.inputs = this.element.querySelectorAll('input');
}
getValues(){
let filterMap = new Map();
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;
}
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){
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){
let values = this.fieldsMap.get(fieldId).getSelected();
if (values.length > 0) filterMap.set(fieldId, values);
}
addRangeValue(filterMap, fieldId){
const inputs = this.fieldsMap.get(fieldId).querySelectorAll('input');
let value = ':';
if (inputs[0].value !== ''){ // Min value
value = inputs[0].value+value;
if (this.inputs[0].value.trim() !== ''){ // Min value
value = this.inputs[0].value+value;
}
if (inputs[1].value !== ''){ // Max value
value = value+inputs[1].value;
if (this.inputs[1].value.trim() !== ''){ // Max value
value = value+this.inputs[1].value;
}
if (value !== ':') filterMap.set(fieldId, value);
}
addValuesFromBoolCheckboxes(filterMap, fieldIds){
fieldIds.forEach( fieldId => {
let checkbox = this.fieldsMap.get(fieldId).querySelector('input');
if (checkbox.checked) filterMap.set(fieldId, true);
});
return ( value === ':' ? null : { fieldId: 'mass-density', value: value } );
}
setAddPropertiesListener(listener) {
this.addPropertiesListener= listener;
highlightSelected(bool){
if (this.getValues() === null)
this.inputs[0].parentElement.style.opacity = (bool ? 0.1 : '')
}
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
......
......@@ -358,10 +358,10 @@ class NewSearchMod {
mainSideElem.addEventListener( "mouseenter", event => {
// console.log('filters:', this.filterPanel.getValues())
//this.filterPanel.showSelectedProps(true)
this.filterPanel.showSelectedProps(true)
});
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