Skip to content

Commit cfba2bc

Browse files
andrewkfiedlerrzwiefel
authored andcommitted
DDF-2644 Add boolean / number support to query / filter
- Adds boolean support to cql writer / reader. - Adds boolean input to specifically handle boolean fields. - Adds number input to specifically handle number fields. - Adds support for boolean and number searching to both query and local filtering.
1 parent 858cbbb commit cfba2bc

File tree

14 files changed

+288
-18
lines changed

14 files changed

+288
-18
lines changed

catalog/ui/catalog-ui-search/src/main/webapp/component/component.less

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
@import 'ingest-menu/ingest-menu';
2424
@import 'ingest-details/ingest-details';
2525
@import 'input/input';
26+
@import 'input/boolean/input-boolean';
2627
@import 'input/date/input-date';
2728
@import 'input/bulk/input-bulk';
2829
@import 'input/enum/input-enum';

catalog/ui/catalog-ui-search/src/main/webapp/component/filter-comparator/filter-comparator.view.js

+16-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ define([
2525
var geometryComparators = ['INTERSECTS'];
2626
var dateComparators = ['BEFORE', 'AFTER'];
2727
var stringComparators = ['CONTAINS', 'MATCHCASE', 'EQUALS'];
28+
var numberComparators = ['>','<','=','>=','<='];
29+
var booleanComparators = ['='];
2830

2931
return Marionette.ItemView.extend({
3032
template: template,
@@ -59,19 +61,30 @@ define([
5961
this.model.set('comparator', geometryComparators[0]);
6062
}
6163
return geometryComparators;
62-
break;
6364
case 'DATE':
6465
if (dateComparators.indexOf(this.model.get('comparator')) === -1){
6566
this.model.set('comparator', dateComparators[0]);
6667
}
6768
return dateComparators;
68-
break;
69+
case 'BOOLEAN':
70+
if (booleanComparators.indexOf(this.model.get('comparator')) === -1){
71+
this.model.set('comparator', booleanComparators[0]);
72+
}
73+
return booleanComparators;
74+
case 'LONG':
75+
case 'DOUBLE':
76+
case 'FLOAT':
77+
case 'INTEGER':
78+
case 'SHORT':
79+
if (numberComparators.indexOf(this.model.get('comparator')) === -1){
80+
this.model.set('comparator', numberComparators[0]);
81+
}
82+
return numberComparators;
6983
default:
7084
if (stringComparators.indexOf(this.model.get('comparator')) === -1){
7185
this.model.set('comparator', stringComparators[0]);
7286
}
7387
return stringComparators;
74-
break;
7588
}
7689
}
7790
});

catalog/ui/catalog-ui-search/src/main/webapp/component/filter/filter.view.js

+20-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,12 @@ define([
3737
INTERSECTS: 'INTERSECTS',
3838
CONTAINS: 'ILIKE',
3939
MATCHCASE: 'LIKE',
40-
EQUALS: '='
40+
EQUALS: '=',
41+
'>': '>',
42+
'<': '<',
43+
'=': '=',
44+
'<=': '<=',
45+
'>=': '>='
4146
};
4247

4348
var CQLtoComparator = {};
@@ -108,6 +113,20 @@ define([
108113
this.model.set('comparator', 'BEFORE');
109114
}
110115
break;
116+
case 'BOOLEAN':
117+
if (['='].indexOf(currentComparator) === -1){
118+
this.model.set('comparator', '=');
119+
}
120+
break;
121+
case 'LONG':
122+
case 'DOUBLE':
123+
case 'FLOAT':
124+
case 'INTEGER':
125+
case 'SHORT':
126+
if (['>', '<', '=', '>=', '<='].indexOf(currentComparator) === -1 ){
127+
this.model.set('comparator', '>');
128+
}
129+
break;
111130
default:
112131
if (['CONTAINS', 'MATCHCASE', 'EQUALS'].indexOf(currentComparator) === -1) {
113132
this.model.set('comparator', 'CONTAINS');
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{{!--
2+
/**
3+
* Copyright (c) Codice Foundation
4+
*
5+
* This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either
6+
* version 3 of the License, or any later version.
7+
*
8+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9+
* See the GNU Lesser General Public License for more details. A copy of the GNU Lesser General Public License is distributed along with this program and can be found at
10+
* <http://www.gnu.org/licenses/lgpl.html>.
11+
*
12+
**/
13+
--}}
14+
<div class="if-editing">
15+
<label>
16+
<input id="{{cid}}" value="{{value}}" placeholder="{{property.placeholder}}" name="{{property.id}}" type="checkbox" {{#if value}}checked{{/if}}>
17+
<button class="checkbox-placeholder is-button is-neutral">
18+
<span class="is-not-checked">false</span>
19+
<span class="is-checked">true</span>
20+
</button>
21+
</label>
22+
</div>
23+
<div class="if-viewing">
24+
<label>
25+
{{value}}
26+
</label>
27+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
@{customElementNamespace}input.is-boolean {
2+
input {
3+
display: none;
4+
}
5+
6+
.if-editing label {
7+
width: 100%;
8+
cursor: pointer;
9+
height: @minimumButtonSize;
10+
}
11+
12+
.checkbox-placeholder {
13+
width: 100%;
14+
padding-left: 10px;
15+
border: 1px solid @lighten-inherited-background-color;
16+
background: @lighten-inherited-background-color;
17+
height: 100%;
18+
text-align: left;
19+
20+
span {
21+
font-size: @minimumFontSize;
22+
}
23+
}
24+
25+
.is-not-checked {
26+
display: block;
27+
}
28+
29+
.is-checked {
30+
display: none;
31+
}
32+
33+
input:checked + button {
34+
.is-checked {
35+
display: block;
36+
}
37+
.is-not-checked {
38+
display: none;
39+
}
40+
}
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* Copyright (c) Codice Foundation
3+
*
4+
* This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser
5+
* General Public License as published by the Free Software Foundation, either version 3 of the
6+
* License, or any later version.
7+
*
8+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9+
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10+
* Lesser General Public License for more details. A copy of the GNU Lesser General Public License
11+
* is distributed along with this program and can be found at
12+
* <http://www.gnu.org/licenses/lgpl.html>.
13+
*
14+
**/
15+
/*global require*/
16+
var Marionette = require('marionette');
17+
var template = require('./input-boolean.hbs');
18+
var InputView = require('../input.view');
19+
20+
module.exports = InputView.extend({
21+
template: template,
22+
getCurrentValue: function(){
23+
return this.$el.find('input').is(':checked');
24+
},
25+
handleValue: function(){
26+
this.$el.find('input').attr('checked', Boolean(this.model.getValue()));
27+
},
28+
events: {
29+
'click label': 'triggerCheckboxClick'
30+
},
31+
triggerCheckboxClick: function(){
32+
this.$el.find('input').click();
33+
}
34+
});

catalog/ui/catalog-ui-search/src/main/webapp/component/input/input.less

+4-2
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@
2727
}
2828
}
2929

30-
@{customElementNamespace}input.is-text {
30+
@{customElementNamespace}input.is-text,
31+
@{customElementNamespace}input.is-number,
32+
@{customElementNamespace}input.is-boolean {
3133
input {
3234
height: @minimumButtonSize;
3335
width: 100%;
3436
}
35-
label {
37+
.if-viewing label {
3638
padding-left: 10px;
3739
line-height: @minimumButtonSize;
3840
margin: 0px;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{{!--
2+
/**
3+
* Copyright (c) Codice Foundation
4+
*
5+
* This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either
6+
* version 3 of the License, or any later version.
7+
*
8+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9+
* See the GNU Lesser General Public License for more details. A copy of the GNU Lesser General Public License is distributed along with this program and can be found at
10+
* <http://www.gnu.org/licenses/lgpl.html>.
11+
*
12+
**/
13+
--}}
14+
<div class="if-editing">
15+
<input id="{{cid}}" value="{{value}}" placeholder="{{property.placeholder}}" name="{{property.id}}" type="number">
16+
</div>
17+
<div class="if-viewing">
18+
<label>
19+
{{value}}
20+
</label>
21+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Copyright (c) Codice Foundation
3+
*
4+
* This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser
5+
* General Public License as published by the Free Software Foundation, either version 3 of the
6+
* License, or any later version.
7+
*
8+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
9+
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10+
* Lesser General Public License for more details. A copy of the GNU Lesser General Public License
11+
* is distributed along with this program and can be found at
12+
* <http://www.gnu.org/licenses/lgpl.html>.
13+
*
14+
**/
15+
/*global require*/
16+
var Marionette = require('marionette');
17+
var template = require('./input-number.hbs');
18+
var InputView = require('../input.view');
19+
20+
module.exports = InputView.extend({
21+
template: template,
22+
getCurrentValue: function(){
23+
return Number(this.$el.find('input').val());
24+
}
25+
});

catalog/ui/catalog-ui-search/src/main/webapp/component/property/property.js

+10
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,16 @@ define([
9191
case 'LOCATION':
9292
this.set('calculatedType', 'location');
9393
break;
94+
case 'BOOLEAN':
95+
this.set('calculatedType', 'boolean');
96+
break;
97+
case 'LONG':
98+
case 'DOUBLE':
99+
case 'FLOAT':
100+
case 'INTEGER':
101+
case 'SHORT':
102+
this.set('calculatedType', 'number');
103+
break;
94104
case 'STRING':
95105
case 'GEOMETRY':
96106
case 'XML':

catalog/ui/catalog-ui-search/src/main/webapp/component/value/value.collection.view.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ define([
3232
case 'thumbnail':
3333
case 'location':
3434
return this.children.first().hasChanged();
35-
break;
3635
case 'date':
3736
var currentValue = this.children.map(function(childView){
3837
return childView.getCurrentValue();
@@ -45,14 +44,20 @@ define([
4544
return dateValue;
4645
}
4746
}).toString();
48-
break;
47+
case 'number': //needed until cql result correctly returns numbers as numbers
48+
var currentValue = this.children.map(function(childView){
49+
return childView.getCurrentValue().toString();
50+
});
51+
currentValue.sort();
52+
return JSON.stringify(currentValue) !== JSON.stringify(this.model.getInitialValue().map(function(value){
53+
return Number(value).toString(); //handle cases of unnecessary number padding -> 22.0000
54+
}));
4955
default:
5056
var currentValue = this.children.map(function(childView){
5157
return childView.getCurrentValue();
5258
});
5359
currentValue.sort();
5460
return JSON.stringify(currentValue) !== JSON.stringify(this.model.getInitialValue());
55-
break;
5661
}
5762
},
5863
addNewValue: function (propertyModel){

catalog/ui/catalog-ui-search/src/main/webapp/component/value/value.view.js

+11-4
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ define([
2424
'component/input/date/input-date.view',
2525
'component/input/location/input-location.view',
2626
'component/input/enum/input-enum.view',
27-
'component/input/radio/input-radio.view'
27+
'component/input/radio/input-radio.view',
28+
'component/input/number/input-number.view',
29+
'component/input/boolean/input-boolean.view'
2830
], function (Marionette, _, $, template, CustomElements, InputView, InputThumbnailView, InputDateView,
29-
InputLocationView, InputEnumView, InputRadioView) {
31+
InputLocationView, InputEnumView, InputRadioView, InputNumberView, InputBooleanView) {
3032

3133
return Marionette.LayoutView.extend({
3234
template: template,
@@ -70,8 +72,13 @@ define([
7072
model: this.model
7173
}));
7274
break;
73-
case 'text':
74-
this.input.show(new InputView({
75+
case 'boolean':
76+
this.input.show(new InputBooleanView({
77+
model: this.model
78+
}));
79+
break;
80+
case 'number':
81+
this.input.show(new InputNumberView({
7582
model: this.model
7683
}));
7784
break;

catalog/ui/catalog-ui-search/src/main/webapp/js/cql.js

+15-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ define(function () {
2929
COMMA: /^,/,
3030
LOGICAL: /^(AND|OR)/i,
3131
VALUE: /^('([^']|'')*'|-?\d+(\.\d*)?|\.\d+)/,
32+
BOOLEAN: /^(false|true)/i,
3233
LPAREN: /^\(/,
3334
RPAREN: /^\)/,
3435
SPATIAL: /^(BBOX|INTERSECTS|DWITHIN|WITHIN|CONTAINS)/i,
@@ -73,9 +74,10 @@ define(function () {
7374
PROPERTY: ['COMPARISON', 'BETWEEN', 'COMMA', 'IS_NULL', 'BEFORE', 'AFTER', 'DURING'],
7475
BETWEEN: ['VALUE'],
7576
IS_NULL: ['END'],
76-
COMPARISON: ['VALUE'],
77+
COMPARISON: ['VALUE', 'BOOLEAN'],
7778
COMMA: ['GEOMETRY', 'VALUE', 'UNITS', 'PROPERTY'],
7879
VALUE: ['LOGICAL', 'COMMA', 'RPAREN', 'END'],
80+
BOOLEAN: ['RPAREN'],
7981
SPATIAL: ['LPAREN'],
8082
UNITS: ['RPAREN'],
8183
LOGICAL: ['NOT', 'VALUE', 'SPATIAL', 'PROPERTY', 'LPAREN'],
@@ -183,6 +185,7 @@ define(function () {
183185
case "VALUE":
184186
case "TIME":
185187
case "TIME_PERIOD":
188+
case "BOOLEAN":
186189
postfix.push(tok);
187190
break;
188191
case "COMPARISON":
@@ -302,7 +305,15 @@ define(function () {
302305
} else {
303306
return Number(tok.text);
304307
}
305-
break;
308+
case "BOOLEAN":
309+
switch(tok.text){
310+
case 'false':
311+
return false;
312+
case 'true':
313+
return true;
314+
default:
315+
return false;
316+
}
306317
case "SPATIAL":
307318
switch (tok.text.toUpperCase()) {
308319
case "BBOX":
@@ -458,6 +469,8 @@ define(function () {
458469
return "'" + filter.replace(/'/g, "''") + "'";
459470
} else if (typeof filter === "number") {
460471
return String(filter);
472+
} else if (typeof filter === "boolean") {
473+
return Boolean(filter);
461474
}
462475
break;
463476
default:

0 commit comments

Comments
 (0)