269 lines
8.4 KiB
JavaScript
269 lines
8.4 KiB
JavaScript
/* Copyright (c) 2017 Jean-Marc VIGLINO,
|
|
released under the CeCILL-B license (French BSD license)
|
|
(http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt).
|
|
*/
|
|
import ol_control_SelectBase from './SelectBase.js'
|
|
import ol_ext_element from '../util/element.js'
|
|
|
|
/**
|
|
* Select Control.
|
|
* A control to select features by attributes
|
|
*
|
|
* @constructor
|
|
* @extends {ol_control_SelectBase}
|
|
* @fires select
|
|
* @param {Object=} options
|
|
* @param {string} options.className control class name
|
|
* @param {Element | undefined} options.target Specify a target if you want the control to be rendered outside of the map's viewport.
|
|
* @param {ol.source.Vector | Array<ol.source.Vector>} options.source the source to search in
|
|
* @param {string} [options.selectLabel=select] select button label
|
|
* @param {string} [options.addLabel=add] add button label
|
|
* @param {string} [options.caseLabel=case sensitive] case checkbox label
|
|
* @param {string} [options.allLabel=match all] match all checkbox label
|
|
* @param {string} [options.attrPlaceHolder=attribute]
|
|
* @param {string} [options.valuePlaceHolder=value]
|
|
*/
|
|
var ol_control_Select = class olcontrolSelect extends ol_control_SelectBase {
|
|
constructor(options) {
|
|
options = options || {};
|
|
|
|
// Container
|
|
var div = options.content = document.createElement('div');
|
|
super(options);
|
|
var bt = div.querySelector('button');
|
|
|
|
// Autocompletion list
|
|
this._ul = ol_ext_element.create('UL', {
|
|
parent: div
|
|
});
|
|
|
|
// All conditions
|
|
this._all = ol_ext_element.create('INPUT', {
|
|
type: 'checkbox',
|
|
checked: true
|
|
});
|
|
var label_match_all = ol_ext_element.create('LABEL', {
|
|
html: this._all,
|
|
parent: div
|
|
});
|
|
ol_ext_element.appendText(label_match_all, options.allLabel || 'match all');
|
|
|
|
// Use case
|
|
this._useCase = ol_ext_element.create('INPUT', {
|
|
type: 'checkbox'
|
|
});
|
|
var label_case_sensitive = ol_ext_element.create('LABEL', {
|
|
html: this._useCase,
|
|
parent: div
|
|
});
|
|
ol_ext_element.appendText(label_case_sensitive, options.caseLabel || 'case sensitive');
|
|
|
|
// Add ok button at the end
|
|
div.appendChild(bt);
|
|
|
|
// Add button
|
|
ol_ext_element.create('BUTTON', {
|
|
className: 'ol-append',
|
|
html: options.addLabel || 'add rule',
|
|
click: function () {
|
|
this.addCondition();
|
|
}.bind(this),
|
|
parent: div
|
|
});
|
|
|
|
this._conditions = [];
|
|
this.set('attrPlaceHolder', options.attrPlaceHolder || 'attribute');
|
|
this.set('valuePlaceHolder', options.valuePlaceHolder || 'value');
|
|
this.addCondition();
|
|
}
|
|
/** Add a new condition
|
|
* @param {*} options
|
|
* @param {string} options.attr attribute name
|
|
* @param {string} options.op operator
|
|
* @param {string} options.val attribute value
|
|
*/
|
|
addCondition(options) {
|
|
options = options || {};
|
|
this._conditions.push({
|
|
attr: options.attr || '',
|
|
op: options.op || '=',
|
|
val: options.val || ''
|
|
});
|
|
this._drawlist();
|
|
}
|
|
/** Get the condition list
|
|
*/
|
|
getConditions() {
|
|
return {
|
|
usecase: this._useCase.checked,
|
|
all: this._all.checked,
|
|
conditions: this._conditions
|
|
};
|
|
}
|
|
/** Set the condition list
|
|
*/
|
|
setConditions(cond) {
|
|
this._useCase.checked = cond.usecase;
|
|
this._all.checked = cond.all;
|
|
this._conditions = cond.conditions;
|
|
this._drawlist();
|
|
}
|
|
/** Get the conditions as string
|
|
*/
|
|
getConditionsString(cond) {
|
|
var st = '';
|
|
for (var i = 0, c; c = cond.conditions[i]; i++) {
|
|
if (c.attr) {
|
|
st += (st ? (cond.all ? ' AND ' : ' OR ') : '')
|
|
+ c.attr
|
|
+ this.operationsList[c.op]
|
|
+ c.val;
|
|
}
|
|
}
|
|
return st;
|
|
}
|
|
/** Draw the liste
|
|
* @private
|
|
*/
|
|
_drawlist() {
|
|
this._ul.innerHTML = '';
|
|
for (var i = 0; i < this._conditions.length; i++) {
|
|
this._ul.appendChild(this._getLiCondition(i));
|
|
}
|
|
}
|
|
/** Get a line
|
|
* @return {*}
|
|
* @private
|
|
*/
|
|
_autocomplete(val, ul) {
|
|
ul.classList.remove('ol-hidden');
|
|
ul.innerHTML = '';
|
|
var attributes = {};
|
|
var sources = this.get('source');
|
|
for (var i = 0, s; s = sources[i]; i++) {
|
|
var features = s.getFeatures();
|
|
for (var j = 0, f; f = features[j]; j++) {
|
|
Object.assign(attributes, f.getProperties());
|
|
if (j > 100)
|
|
break;
|
|
}
|
|
}
|
|
var rex = new RegExp(val, 'i');
|
|
for (var a in attributes) {
|
|
if (a === 'geometry')
|
|
continue;
|
|
if (rex.test(a)) {
|
|
var li = document.createElement('li');
|
|
li.textContent = a;
|
|
li.addEventListener("click", function () {
|
|
ul.previousElementSibling.value = this.textContent;
|
|
var event = document.createEvent('HTMLEvents');
|
|
event.initEvent('change', true, false);
|
|
ul.previousElementSibling.dispatchEvent(event);
|
|
ul.classList.add('ol-hidden');
|
|
});
|
|
ul.appendChild(li);
|
|
}
|
|
}
|
|
}
|
|
/** Get a line
|
|
* @return {*}
|
|
* @private
|
|
*/
|
|
_getLiCondition(i) {
|
|
var self = this;
|
|
var li = document.createElement('li');
|
|
// Attribut
|
|
var autocomplete = document.createElement('div');
|
|
autocomplete.classList.add('ol-autocomplete');
|
|
autocomplete.addEventListener("mouseleave", function () {
|
|
this.querySelector('ul').classList.add('ol-hidden');
|
|
});
|
|
li.appendChild(autocomplete);
|
|
var input_attr = document.createElement('input');
|
|
input_attr.classList.add('ol-attr');
|
|
input_attr.setAttribute('type', 'search');
|
|
input_attr.setAttribute('placeholder', this.get('attrPlaceHolder'));
|
|
input_attr.addEventListener('keyup', function () {
|
|
self._autocomplete(this.value, this.nextElementSibling);
|
|
});
|
|
input_attr.addEventListener('focusout', function () {
|
|
setTimeout(function () {
|
|
autocomplete.querySelector('ul').classList.add('ol-hidden');
|
|
}, 300);
|
|
});
|
|
input_attr.addEventListener('click', function () {
|
|
setTimeout(function () {
|
|
self._autocomplete(this.value, this.nextElementSibling);
|
|
this.nextElementSibling.classList.remove('ol-hidden');
|
|
}.bind(this));
|
|
});
|
|
input_attr.addEventListener('change', function () {
|
|
self._conditions[i].attr = this.value;
|
|
});
|
|
input_attr.value = self._conditions[i].attr;
|
|
autocomplete.appendChild(input_attr);
|
|
// Autocomplete list
|
|
var ul_autocomplete = document.createElement('ul');
|
|
ul_autocomplete.classList.add('ol-hidden');
|
|
autocomplete.appendChild(ul_autocomplete);
|
|
|
|
// Operation
|
|
var select = document.createElement('select');
|
|
li.appendChild(select);
|
|
for (var k in this.operationsList) {
|
|
var option = document.createElement('option');
|
|
option.value = k;
|
|
option.textContent = this.operationsList[k];
|
|
select.appendChild(option);
|
|
}
|
|
select.value = self._conditions[i].op;
|
|
select.addEventListener('change', function () {
|
|
self._conditions[i].op = this.value;
|
|
});
|
|
|
|
// Value
|
|
var input_value = document.createElement('input');
|
|
input_value.setAttribute('type', 'text');
|
|
input_value.setAttribute('placeholder', this.get('valuePlaceHolder'));
|
|
input_value.addEventListener('change', function () {
|
|
self._conditions[i].val = this.value;
|
|
});
|
|
input_value.value = self._conditions[i].val;
|
|
li.appendChild(input_value);
|
|
if (this._conditions.length > 1) {
|
|
var div_delete = document.createElement('div');
|
|
div_delete.classList.add('ol-delete');
|
|
div_delete.addEventListener("click", function () { self.removeCondition(i); });
|
|
li.appendChild(div_delete);
|
|
}
|
|
|
|
//
|
|
return li;
|
|
}
|
|
/** Remove the ith condition
|
|
* @param {int} i condition index
|
|
*/
|
|
removeCondition(i) {
|
|
this._conditions.splice(i, 1);
|
|
this._drawlist();
|
|
}
|
|
/** Select features by attributes
|
|
* @param {*} options
|
|
* @param {Array<ol.source.Vector>|undefined} options.sources source to apply rules, default the select sources
|
|
* @param {bool} options.useCase case sensitive, default checkbox state
|
|
* @param {bool} options.matchAll match all conditions, , default checkbox state
|
|
* @param {Array<conditions>} options.conditions array of conditions
|
|
* @fires select
|
|
*/
|
|
doSelect(options) {
|
|
options = options || {};
|
|
options.useCase = options.useCase || this._useCase.checked;
|
|
options.matchAll = options.matchAll || this._all.checked;
|
|
options.conditions = options.conditions || this._conditions;
|
|
return super.doSelect(options);
|
|
}
|
|
}
|
|
|
|
export default ol_control_Select
|