Added text search facet.
git-svn-id: http://google-refine.googlecode.com/svn/trunk@23 7d457c2a-affb-35e4-300a-418c747d4874
This commit is contained in:
parent
f3d9a7804e
commit
ac46653aa3
@ -13,6 +13,7 @@ import com.metaweb.gridlock.Jsonizable;
|
|||||||
import com.metaweb.gridlock.browsing.facets.Facet;
|
import com.metaweb.gridlock.browsing.facets.Facet;
|
||||||
import com.metaweb.gridlock.browsing.facets.ListFacet;
|
import com.metaweb.gridlock.browsing.facets.ListFacet;
|
||||||
import com.metaweb.gridlock.browsing.facets.RangeFacet;
|
import com.metaweb.gridlock.browsing.facets.RangeFacet;
|
||||||
|
import com.metaweb.gridlock.browsing.facets.TextSearchFacet;
|
||||||
import com.metaweb.gridlock.browsing.filters.RowFilter;
|
import com.metaweb.gridlock.browsing.filters.RowFilter;
|
||||||
import com.metaweb.gridlock.model.Project;
|
import com.metaweb.gridlock.model.Project;
|
||||||
|
|
||||||
@ -54,6 +55,8 @@ public class Engine implements Jsonizable {
|
|||||||
facet = new ListFacet();
|
facet = new ListFacet();
|
||||||
} else if ("range".equals(type)) {
|
} else if ("range".equals(type)) {
|
||||||
facet = new RangeFacet();
|
facet = new RangeFacet();
|
||||||
|
} else if ("text".equals(type)) {
|
||||||
|
facet = new TextSearchFacet();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (facet != null) {
|
if (facet != null) {
|
||||||
|
@ -7,7 +7,7 @@ import org.json.JSONObject;
|
|||||||
import org.json.JSONWriter;
|
import org.json.JSONWriter;
|
||||||
|
|
||||||
import com.metaweb.gridlock.browsing.FilteredRows;
|
import com.metaweb.gridlock.browsing.FilteredRows;
|
||||||
import com.metaweb.gridlock.browsing.filters.ExpressionComparisonRowFilter;
|
import com.metaweb.gridlock.browsing.filters.ExpressionNumberComparisonRowFilter;
|
||||||
import com.metaweb.gridlock.browsing.filters.RowFilter;
|
import com.metaweb.gridlock.browsing.filters.RowFilter;
|
||||||
import com.metaweb.gridlock.expr.Evaluable;
|
import com.metaweb.gridlock.expr.Evaluable;
|
||||||
import com.metaweb.gridlock.expr.Parser;
|
import com.metaweb.gridlock.expr.Parser;
|
||||||
@ -69,19 +69,19 @@ public class RangeFacet implements Facet {
|
|||||||
@Override
|
@Override
|
||||||
public RowFilter getRowFilter() {
|
public RowFilter getRowFilter() {
|
||||||
if ("min".equals(_mode)) {
|
if ("min".equals(_mode)) {
|
||||||
return new ExpressionComparisonRowFilter(_eval, _cellIndex) {
|
return new ExpressionNumberComparisonRowFilter(_eval, _cellIndex) {
|
||||||
protected boolean checkValue(double d) {
|
protected boolean checkValue(double d) {
|
||||||
return d >= _min;
|
return d >= _min;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} else if ("max".equals(_mode)) {
|
} else if ("max".equals(_mode)) {
|
||||||
return new ExpressionComparisonRowFilter(_eval, _cellIndex) {
|
return new ExpressionNumberComparisonRowFilter(_eval, _cellIndex) {
|
||||||
protected boolean checkValue(double d) {
|
protected boolean checkValue(double d) {
|
||||||
return d <= _max;
|
return d <= _max;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return new ExpressionComparisonRowFilter(_eval, _cellIndex) {
|
return new ExpressionNumberComparisonRowFilter(_eval, _cellIndex) {
|
||||||
protected boolean checkValue(double d) {
|
protected boolean checkValue(double d) {
|
||||||
return d >= _min && d <= _max;
|
return d >= _min && d <= _max;
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
package com.metaweb.gridlock.browsing.facets;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.json.JSONWriter;
|
||||||
|
|
||||||
|
import com.metaweb.gridlock.browsing.FilteredRows;
|
||||||
|
import com.metaweb.gridlock.browsing.filters.ExpressionNumberComparisonRowFilter;
|
||||||
|
import com.metaweb.gridlock.browsing.filters.ExpressionStringComparisonRowFilter;
|
||||||
|
import com.metaweb.gridlock.browsing.filters.RowFilter;
|
||||||
|
import com.metaweb.gridlock.expr.Evaluable;
|
||||||
|
import com.metaweb.gridlock.expr.Parser;
|
||||||
|
import com.metaweb.gridlock.expr.VariableExpr;
|
||||||
|
import com.metaweb.gridlock.model.Project;
|
||||||
|
|
||||||
|
public class TextSearchFacet implements Facet {
|
||||||
|
protected String _name;
|
||||||
|
protected int _cellIndex;
|
||||||
|
protected String _query;
|
||||||
|
|
||||||
|
protected String _mode;
|
||||||
|
protected boolean _caseSensitive;
|
||||||
|
|
||||||
|
public TextSearchFacet() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(JSONWriter writer, Properties options)
|
||||||
|
throws JSONException {
|
||||||
|
|
||||||
|
writer.object();
|
||||||
|
writer.key("name"); writer.value(_name);
|
||||||
|
writer.key("cellIndex"); writer.value(_cellIndex);
|
||||||
|
writer.key("query"); writer.value(_query);
|
||||||
|
writer.key("mode"); writer.value(_mode);
|
||||||
|
writer.key("caseSensitive"); writer.value(_caseSensitive);
|
||||||
|
writer.endObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initializeFromJSON(JSONObject o) throws Exception {
|
||||||
|
_name = o.getString("name");
|
||||||
|
_cellIndex = o.getInt("cellIndex");
|
||||||
|
_query = o.getString("query");
|
||||||
|
_mode = o.getString("mode");
|
||||||
|
_caseSensitive = o.getBoolean("caseSensitive");
|
||||||
|
if (!_caseSensitive) {
|
||||||
|
_query = _query.toLowerCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RowFilter getRowFilter() {
|
||||||
|
Evaluable eval = new VariableExpr("value");
|
||||||
|
|
||||||
|
if ("regex".equals(_mode)) {
|
||||||
|
return new ExpressionStringComparisonRowFilter(eval, _cellIndex) {
|
||||||
|
protected boolean checkValue(String s) {
|
||||||
|
return s.matches(_query);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return new ExpressionStringComparisonRowFilter(eval, _cellIndex) {
|
||||||
|
protected boolean checkValue(String s) {
|
||||||
|
return s.toLowerCase().contains(_query);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void computeChoices(Project project, FilteredRows filteredRows) {
|
||||||
|
// nothing to do
|
||||||
|
}
|
||||||
|
}
|
@ -7,11 +7,11 @@ import com.metaweb.gridlock.model.Cell;
|
|||||||
import com.metaweb.gridlock.model.Project;
|
import com.metaweb.gridlock.model.Project;
|
||||||
import com.metaweb.gridlock.model.Row;
|
import com.metaweb.gridlock.model.Row;
|
||||||
|
|
||||||
abstract public class ExpressionComparisonRowFilter implements RowFilter {
|
abstract public class ExpressionNumberComparisonRowFilter implements RowFilter {
|
||||||
final protected Evaluable _evaluable;
|
final protected Evaluable _evaluable;
|
||||||
final protected int _cellIndex;
|
final protected int _cellIndex;
|
||||||
|
|
||||||
public ExpressionComparisonRowFilter(Evaluable evaluable, int cellIndex) {
|
public ExpressionNumberComparisonRowFilter(Evaluable evaluable, int cellIndex) {
|
||||||
_evaluable = evaluable;
|
_evaluable = evaluable;
|
||||||
_cellIndex = cellIndex;
|
_cellIndex = cellIndex;
|
||||||
}
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package com.metaweb.gridlock.browsing.filters;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import com.metaweb.gridlock.expr.Evaluable;
|
||||||
|
import com.metaweb.gridlock.model.Cell;
|
||||||
|
import com.metaweb.gridlock.model.Project;
|
||||||
|
import com.metaweb.gridlock.model.Row;
|
||||||
|
|
||||||
|
abstract public class ExpressionStringComparisonRowFilter implements RowFilter {
|
||||||
|
final protected Evaluable _evaluable;
|
||||||
|
final protected int _cellIndex;
|
||||||
|
|
||||||
|
public ExpressionStringComparisonRowFilter(Evaluable evaluable, int cellIndex) {
|
||||||
|
_evaluable = evaluable;
|
||||||
|
_cellIndex = cellIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean filterRow(Project project, int rowIndex, Row row) {
|
||||||
|
if (_cellIndex < row.cells.size()) {
|
||||||
|
Cell cell = row.cells.get(_cellIndex);
|
||||||
|
if (cell != null) {
|
||||||
|
Properties bindings = new Properties();
|
||||||
|
|
||||||
|
bindings.put("cell", cell);
|
||||||
|
bindings.put("value", cell.value);
|
||||||
|
|
||||||
|
Object value = _evaluable.evaluate(bindings);
|
||||||
|
if (value != null) {
|
||||||
|
if (value.getClass().isArray()) {
|
||||||
|
Object[] a = (Object[]) value;
|
||||||
|
for (Object v : a) {
|
||||||
|
if (checkValue(v instanceof String ? ((String) v) : v.toString())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (checkValue(value instanceof String ? ((String) value) : value.toString())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract protected boolean checkValue(String s);
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Gridlock</title>
<link type="text/css" rel="stylesheet" href="http://freebaselibs.com/static/suggest/1.0.3/suggest.min.css" />
<link type="text/css" rel="stylesheet" href="externals/jquery-ui/css/ui-lightness/jquery-ui-1.7.2.custom.css" />
<link rel="stylesheet" href="/styles/common.css" />
<link rel="stylesheet" href="/styles/project.css" />
<link rel="stylesheet" href="/styles/history.css" />
<link rel="stylesheet" href="/styles/browsing.css" />
<link rel="stylesheet" href="/styles/process.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript" src="http://freebaselibs.com/static/suggest/1.0.3/suggest.min.js"></script>
<script type="text/javascript" src="externals/jquery-ui/jquery-ui-1.7.2.custom.min.js"></script>
<script type="text/javascript" src="scripts/util/misc.js"></script>
<script type="text/javascript" src="scripts/util/url.js"></script>
<script type="text/javascript" src="scripts/util/string.js"></script>
<script type="text/javascript" src="scripts/util/ajax.js"></script>
<script type="text/javascript" src="scripts/util/menu.js"></script>
<script type="text/javascript" src="scripts/util/dialog.js"></script>
<script type="text/javascript" src="scripts/project.js"></script>
<script type="text/javascript" src="scripts/project/list-facet.js"></script>
<script type="text/javascript" src="scripts/project/range-facet.js"></script>
<script type="text/javascript" src="scripts/project/browsing-engine.js"></script>
<script type="text/javascript" src="scripts/project/data-table-view.js"></script>
<script type="text/javascript" src="scripts/project/history-widget.js"></script>
<script type="text/javascript" src="scripts/project/process-widget.js"></script>
<script type="text/javascript" src="scripts/project/recon-dialog.js"></script>
</head>
<body>
<div id="header">
<h1 id="title">Gridlock</h1>
</div>
<div id="body">
Loading ...
</div>
</body>
</html>
|
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Gridlock</title>
<link type="text/css" rel="stylesheet" href="http://freebaselibs.com/static/suggest/1.0.3/suggest.min.css" />
<link type="text/css" rel="stylesheet" href="externals/jquery-ui/css/ui-lightness/jquery-ui-1.7.2.custom.css" />
<link rel="stylesheet" href="/styles/common.css" />
<link rel="stylesheet" href="/styles/project.css" />
<link rel="stylesheet" href="/styles/history.css" />
<link rel="stylesheet" href="/styles/browsing.css" />
<link rel="stylesheet" href="/styles/process.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript" src="http://freebaselibs.com/static/suggest/1.0.3/suggest.min.js"></script>
<script type="text/javascript" src="externals/jquery-ui/jquery-ui-1.7.2.custom.min.js"></script>
<script type="text/javascript" src="scripts/util/misc.js"></script>
<script type="text/javascript" src="scripts/util/url.js"></script>
<script type="text/javascript" src="scripts/util/string.js"></script>
<script type="text/javascript" src="scripts/util/ajax.js"></script>
<script type="text/javascript" src="scripts/util/menu.js"></script>
<script type="text/javascript" src="scripts/util/dialog.js"></script>
<script type="text/javascript" src="scripts/project.js"></script>
<script type="text/javascript" src="scripts/project/list-facet.js"></script>
<script type="text/javascript" src="scripts/project/range-facet.js"></script>
<script type="text/javascript" src="scripts/project/text-search-facet.js"></script>
<script type="text/javascript" src="scripts/project/browsing-engine.js"></script>
<script type="text/javascript" src="scripts/project/data-table-view.js"></script>
<script type="text/javascript" src="scripts/project/history-widget.js"></script>
<script type="text/javascript" src="scripts/project/process-widget.js"></script>
<script type="text/javascript" src="scripts/project/recon-dialog.js"></script>
</head>
<body>
<div id="header">
<h1 id="title">Gridlock</h1>
</div>
<div id="body">
Loading ...
</div>
</body>
</html>
|
@ -25,6 +25,9 @@ BrowsingEngine.prototype.addFacet = function(type, config, options) {
|
|||||||
case "range":
|
case "range":
|
||||||
facet = new RangeFacet(div, config, options);
|
facet = new RangeFacet(div, config, options);
|
||||||
break;
|
break;
|
||||||
|
case "text":
|
||||||
|
facet = new TextSearchFacet(div, config, options);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
facet = new ListFacet(div, config, options);
|
facet = new ListFacet(div, config, options);
|
||||||
}
|
}
|
||||||
|
@ -234,12 +234,37 @@ DataTableView.prototype._createMenuForColumnHeader = function(column, index, elm
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{},
|
||||||
{
|
{
|
||||||
label: "By Simple Text Search",
|
label: "By Simple Text Search",
|
||||||
click: function() {}
|
click: function() {
|
||||||
|
ui.browsingEngine.addFacet(
|
||||||
|
"text",
|
||||||
|
{
|
||||||
|
"name" : column.headerLabel,
|
||||||
|
"cellIndex" : column.cellIndex,
|
||||||
|
"mode" : "text",
|
||||||
|
"caseSensitive" : false
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "By Custom Expression",
|
label: "By Regular Expression",
|
||||||
|
click: function() {
|
||||||
|
ui.browsingEngine.addFacet(
|
||||||
|
"text",
|
||||||
|
{
|
||||||
|
"name" : column.headerLabel,
|
||||||
|
"cellIndex" : column.cellIndex,
|
||||||
|
"mode" : "regex",
|
||||||
|
"caseSensitive" : true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "By Custom Expression ...",
|
||||||
click: function() {
|
click: function() {
|
||||||
var expression = window.prompt("Enter expression", 'value');
|
var expression = window.prompt("Enter expression", 'value');
|
||||||
if (expression != null) {
|
if (expression != null) {
|
||||||
@ -247,6 +272,7 @@ DataTableView.prototype._createMenuForColumnHeader = function(column, index, elm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{},
|
||||||
{
|
{
|
||||||
label: "By Reconciliation Features",
|
label: "By Reconciliation Features",
|
||||||
submenu: [
|
submenu: [
|
||||||
|
81
src/main/webapp/scripts/project/text-search-facet.js
Normal file
81
src/main/webapp/scripts/project/text-search-facet.js
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
function TextSearchFacet(div, config, options) {
|
||||||
|
this._div = div;
|
||||||
|
this._config = config;
|
||||||
|
this._options = options;
|
||||||
|
|
||||||
|
this._setDefaults();
|
||||||
|
this._timerID = null;
|
||||||
|
|
||||||
|
this._initializeUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
TextSearchFacet.prototype._setDefaults = function() {
|
||||||
|
this._query = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
TextSearchFacet.prototype.getJSON = function() {
|
||||||
|
var o = cloneDeep(this._config);
|
||||||
|
o.type = "text";
|
||||||
|
o.query = this._query;
|
||||||
|
return o;
|
||||||
|
};
|
||||||
|
|
||||||
|
TextSearchFacet.prototype.hasSelection = function() {
|
||||||
|
return this._query != null;
|
||||||
|
};
|
||||||
|
|
||||||
|
TextSearchFacet.prototype._initializeUI = function() {
|
||||||
|
var self = this;
|
||||||
|
var container = this._div.empty();
|
||||||
|
|
||||||
|
var headerDiv = $('<div></div>').addClass("facet-title").appendTo(container);
|
||||||
|
$('<span></span>').text(this._config.name).appendTo(headerDiv);
|
||||||
|
|
||||||
|
var removeButton = $('<a href="javascript:{}"></a>').addClass("facet-choice-link").text("remove").click(function() {
|
||||||
|
self._remove();
|
||||||
|
}).prependTo(headerDiv);
|
||||||
|
|
||||||
|
var bodyDiv = $('<div></div>').addClass("facet-text-body").appendTo(container);
|
||||||
|
|
||||||
|
var input = $('<input />').appendTo(bodyDiv);
|
||||||
|
input.keypress(function(evt) {
|
||||||
|
self._query = this.value;
|
||||||
|
self._scheduleUpdate();
|
||||||
|
});
|
||||||
|
input[0].focus();
|
||||||
|
};
|
||||||
|
|
||||||
|
TextSearchFacet.prototype.updateState = function(data) {
|
||||||
|
};
|
||||||
|
|
||||||
|
TextSearchFacet.prototype.render = function() {
|
||||||
|
this._setRangeIndicators();
|
||||||
|
};
|
||||||
|
|
||||||
|
TextSearchFacet.prototype._reset = function() {
|
||||||
|
this._setDefaults();
|
||||||
|
this._updateRest();
|
||||||
|
};
|
||||||
|
|
||||||
|
TextSearchFacet.prototype._remove = function() {
|
||||||
|
ui.browsingEngine.removeFacet(this);
|
||||||
|
|
||||||
|
this._div = null;
|
||||||
|
this._config = null;
|
||||||
|
this._options = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
TextSearchFacet.prototype._scheduleUpdate = function() {
|
||||||
|
if (this._timerID == null) {
|
||||||
|
var self = this;
|
||||||
|
this._timerID = window.setTimeout(function() {
|
||||||
|
self._timerID = null;
|
||||||
|
self._updateRest();
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TextSearchFacet.prototype._updateRest = function() {
|
||||||
|
ui.browsingEngine.update();
|
||||||
|
ui.dataTableView.update(true);
|
||||||
|
};
|
@ -77,3 +77,12 @@ a.facet-choice-link:hover {
|
|||||||
margin: 5px 0px;
|
margin: 5px 0px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.facet-text-body {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.facet-text-body input {
|
||||||
|
width: 98%;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user