diff --git a/src/main/java/com/metaweb/gridworks/operations/MassEditOperation.java b/src/main/java/com/metaweb/gridworks/operations/MassEditOperation.java index 901cf4f5d..2808554d8 100644 --- a/src/main/java/com/metaweb/gridworks/operations/MassEditOperation.java +++ b/src/main/java/com/metaweb/gridworks/operations/MassEditOperation.java @@ -31,10 +31,14 @@ public class MassEditOperation extends EngineDependentMassCellOperation { static public class Edit implements Jsonizable { final public List from; + final public boolean fromBlank; + final public boolean fromError; final public Serializable to; - public Edit(List from, Serializable to) { + public Edit(List from, boolean fromBlank, boolean fromError, Serializable to) { this.from = from; + this.fromBlank = fromBlank; + this.fromError = fromError; this.to = to; } @@ -42,6 +46,8 @@ public class MassEditOperation extends EngineDependentMassCellOperation { throws JSONException { writer.object(); + writer.key("fromBlank"); writer.value(fromBlank); + writer.key("fromError"); writer.value(fromError); writer.key("from"); writer.array(); for (String s : from) { @@ -72,14 +78,22 @@ public class MassEditOperation extends EngineDependentMassCellOperation { for (int i = 0; i < editCount; i++) { JSONObject editO = editsA.getJSONObject(i); - JSONArray fromA = editO.getJSONArray("from"); - int fromCount = fromA.length(); - - List from = new ArrayList(fromCount); - for (int j = 0; j < fromCount; j++) { - from.add(fromA.getString(j)); + List from = null; + if (editO.has("from") && !editO.isNull("from")) { + JSONArray fromA = editO.getJSONArray("from"); + int fromCount = fromA.length(); + + from = new ArrayList(fromCount); + for (int j = 0; j < fromCount; j++) { + from.add(fromA.getString(j)); + } + } else { + from = new ArrayList(); } - + + boolean fromBlank = editO.has("fromBlank") && editO.getBoolean("fromBlank"); + boolean fromError = editO.has("fromError") && editO.getBoolean("fromError"); + Serializable to = (Serializable) editO.get("to"); if (editO.has("type")) { String type = editO.getString("type"); @@ -88,7 +102,7 @@ public class MassEditOperation extends EngineDependentMassCellOperation { } } - edits.add(new Edit(from, to)); + edits.add(new Edit(from, fromBlank, fromError, to)); } return edits; @@ -136,10 +150,21 @@ public class MassEditOperation extends EngineDependentMassCellOperation { Properties bindings = ExpressionUtils.createBindings(project); Map fromTo = new HashMap(); + Serializable fromBlankTo = null; + Serializable fromErrorTo = null; + for (Edit edit : _edits) { for (String s : edit.from) { fromTo.put(s, edit.to); } + + // the last edit wins + if (edit.fromBlank) { + fromBlankTo = edit.to; + } + if (edit.fromError) { + fromErrorTo = edit.to; + } } return new RowVisitor() { @@ -147,41 +172,59 @@ public class MassEditOperation extends EngineDependentMassCellOperation { Properties bindings; List cellChanges; Evaluable eval; + Map fromTo; + Serializable fromBlankTo; + Serializable fromErrorTo; public RowVisitor init( int cellIndex, Properties bindings, List cellChanges, Evaluable eval, - Map fromTo + Map fromTo, + Serializable fromBlankTo, + Serializable fromErrorTo ) { this.cellIndex = cellIndex; this.bindings = bindings; this.cellChanges = cellChanges; this.eval = eval; this.fromTo = fromTo; + this.fromBlankTo = fromBlankTo; + this.fromErrorTo = fromErrorTo; return this; } public boolean visit(Project project, int rowIndex, Row row, boolean includeContextual, boolean includeDependent) { Cell cell = row.getCell(cellIndex); - + Cell newCell = null; + ExpressionUtils.bind(bindings, row, rowIndex, _columnName, cell); Object v = eval.evaluate(bindings); - if (v != null) { + if (ExpressionUtils.isError(v)) { + if (fromErrorTo != null) { + newCell = new Cell(fromErrorTo, (cell != null) ? cell.recon : null); + } + } else if (ExpressionUtils.isNonBlankData(v)) { String from = v.toString(); Serializable to = fromTo.get(from); if (to != null) { - Cell newCell = new Cell(to, (cell != null) ? cell.recon : null); - CellChange cellChange = new CellChange(rowIndex, cellIndex, cell, newCell); - cellChanges.add(cellChange); + newCell = new Cell(to, (cell != null) ? cell.recon : null); + } + } else { + if (fromBlankTo != null) { + newCell = new Cell(fromBlankTo, (cell != null) ? cell.recon : null); } } + if (newCell != null) { + CellChange cellChange = new CellChange(rowIndex, cellIndex, cell, newCell); + cellChanges.add(cellChange); + } return false; } - }.init(column.getCellIndex(), bindings, cellChanges, eval, fromTo); + }.init(column.getCellIndex(), bindings, cellChanges, eval, fromTo, fromBlankTo, fromErrorTo); } } diff --git a/src/main/webapp/scripts/facets/list-facet.js b/src/main/webapp/scripts/facets/list-facet.js index f81ab9983..a0e404e63 100644 --- a/src/main/webapp/scripts/facets/list-facet.js +++ b/src/main/webapp/scripts/facets/list-facet.js @@ -249,7 +249,7 @@ ListFacet.prototype._update = function(resetScroll) { ); // edit link - if (renderEdit && customLabel === undefined) { + if (renderEdit) { html.push(''); } @@ -377,22 +377,36 @@ ListFacet.prototype._editChoice = function(choice, choiceDiv) { MenuSystem.showMenu(menu, function(){}); MenuSystem.positionMenuLeftRight(menu, choiceDiv); - var originalContent = choice.v.v; + var originalContent; + if (choice === this._blankChoice) { + originalContent = "(blank)"; + } else if (choice === this._errorChoice) { + originalContent = "(error)"; + } else { + originalContent = choice.v.v; + } + var commit = function() { var text = elmts.textarea[0].value; MenuSystem.dismissAll(); + var edit = { to : text }; + if (choice === self._blankChoice) { + edit.fromBlank = true; + } else if (choice === self._errorChoice) { + edit.fromError = true; + } else { + edit.from = [ originalContent ] + } + Gridworks.postProcess( "mass-edit", {}, { columnName: self._config.columnName, expression: "value", - edits: JSON.stringify([{ - from: [ originalContent ], - to: text - }]) + edits: JSON.stringify([ edit ]) }, { // limit edits to rows constrained only by the other facets