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.ListFacet;
|
||||
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.model.Project;
|
||||
|
||||
@ -54,6 +55,8 @@ public class Engine implements Jsonizable {
|
||||
facet = new ListFacet();
|
||||
} else if ("range".equals(type)) {
|
||||
facet = new RangeFacet();
|
||||
} else if ("text".equals(type)) {
|
||||
facet = new TextSearchFacet();
|
||||
}
|
||||
|
||||
if (facet != null) {
|
||||
|
@ -7,7 +7,7 @@ import org.json.JSONObject;
|
||||
import org.json.JSONWriter;
|
||||
|
||||
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.expr.Evaluable;
|
||||
import com.metaweb.gridlock.expr.Parser;
|
||||
@ -69,19 +69,19 @@ public class RangeFacet implements Facet {
|
||||
@Override
|
||||
public RowFilter getRowFilter() {
|
||||
if ("min".equals(_mode)) {
|
||||
return new ExpressionComparisonRowFilter(_eval, _cellIndex) {
|
||||
return new ExpressionNumberComparisonRowFilter(_eval, _cellIndex) {
|
||||
protected boolean checkValue(double d) {
|
||||
return d >= _min;
|
||||
};
|
||||
};
|
||||
} else if ("max".equals(_mode)) {
|
||||
return new ExpressionComparisonRowFilter(_eval, _cellIndex) {
|
||||
return new ExpressionNumberComparisonRowFilter(_eval, _cellIndex) {
|
||||
protected boolean checkValue(double d) {
|
||||
return d <= _max;
|
||||
};
|
||||
};
|
||||
} else {
|
||||
return new ExpressionComparisonRowFilter(_eval, _cellIndex) {
|
||||
return new ExpressionNumberComparisonRowFilter(_eval, _cellIndex) {
|
||||
protected boolean checkValue(double d) {
|
||||
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.Row;
|
||||
|
||||
abstract public class ExpressionComparisonRowFilter implements RowFilter {
|
||||
abstract public class ExpressionNumberComparisonRowFilter implements RowFilter {
|
||||
final protected Evaluable _evaluable;
|
||||
final protected int _cellIndex;
|
||||
|
||||
public ExpressionComparisonRowFilter(Evaluable evaluable, int cellIndex) {
|
||||
public ExpressionNumberComparisonRowFilter(Evaluable evaluable, int cellIndex) {
|
||||
_evaluable = evaluable;
|
||||
_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":
|
||||
facet = new RangeFacet(div, config, options);
|
||||
break;
|
||||
case "text":
|
||||
facet = new TextSearchFacet(div, config, options);
|
||||
break;
|
||||
default:
|
||||
facet = new ListFacet(div, config, options);
|
||||
}
|
||||
|
@ -234,12 +234,37 @@ DataTableView.prototype._createMenuForColumnHeader = function(column, index, elm
|
||||
);
|
||||
}
|
||||
},
|
||||
{},
|
||||
{
|
||||
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() {
|
||||
var expression = window.prompt("Enter expression", 'value');
|
||||
if (expression != null) {
|
||||
@ -247,6 +272,7 @@ DataTableView.prototype._createMenuForColumnHeader = function(column, index, elm
|
||||
}
|
||||
}
|
||||
},
|
||||
{},
|
||||
{
|
||||
label: "By Reconciliation Features",
|
||||
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;
|
||||
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