我有一个显示数据的单元格。我想编辑单元格以提供多行信息。
实施例: 键1 =值|在下一行添加anoter键: 键2 =值|
编辑值后,当显示/重绘单元格时,信息应如上所示显示在单元格中。
答案 0 :(得分:1)
我已经解决了部分问题。我正在使用CellTable和自定义TextAreaEditCell。现在我可以输入多行数据。但是当它进入数据库或者当celltable显示信息时,信息是按顺序形式的。
当我在TestAreaCell中输入这样的数据时: A B C D 在下一行中,输入efgh然后输入
ABCDEFGH
问题:似乎没有考虑输入密钥:
我的TextAreaEditCell类如下。如果需要进行任何更正,请告诉我。
我已经解决了部分问题。我正在使用CellTable和自定义TextAreaEditCell。现在我可以输入多行数据。但是当它进入数据库或者当celltable显示信息时,信息是按顺序形式的。
当我在TestAreaCell中输入这样的数据时: A B C D 在下一行中,输入efgh然后输入
ABCDEFGH
问题:似乎没有考虑输入密钥:
我的TestAreaEditCell类如下。如果需要进行任何更正,请告诉我。
import com.google.gwt.cell.client.AbstractEditableCell;
import com.google.gwt.cell.client.Cell.Context;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.dom.client.InputElement;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.TextAreaElement;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.text.shared.SafeHtmlRenderer;
import com.google.gwt.text.shared.SimpleSafeHtmlRenderer;
/**
* An editable text cell. Click to edit, escape to cancel, return to commit.
*/
public class TextAreaEditCell extends
AbstractEditableCell<String, TextAreaEditCell .ViewData> {
interface Template extends SafeHtmlTemplates {
//@Template("<input type=\"text\" value=\"{0}\" tabindex=\"-1\"></input>")
//SafeHtml input(String value);
//using textarea (instead of text) to add multiple lines of data in a cell.
@Template("<textarea tabindex=\"-1\" rows=\"{1}\" cols=\"{2}\" >{0}</textarea>")
SafeHtml input(String value, Integer rows, Integer cols);
}
/**
* The view data object used by this cell. We need to store both the text and
* the state because this cell is rendered differently in edit mode. If we did
* not store the edit state, refreshing the cell with view data would always
* put us in to edit state, rendering a text box instead of the new text
* string.
*/
static class ViewData {
private boolean isEditing;
/**
* If true, this is not the first edit.
*/
private boolean isEditingAgain;
/**
* Keep track of the original value at the start of the edit, which might be
* the edited value from the previous edit and NOT the actual value.
*/
private String original;
private String text;
/**
* Construct a new ViewData in editing mode.
*
* @param text the text to edit
*/
public ViewData(String text) {
this.original = text;
this.text = text;
this.isEditing = true;
this.isEditingAgain = false;
}
@Override
public boolean equals(Object o) {
if (o == null) {
return false;
}
ViewData vd = (ViewData) o;
return equalsOrBothNull(original, vd.original)
&& equalsOrBothNull(text, vd.text) && isEditing == vd.isEditing
&& isEditingAgain == vd.isEditingAgain;
}
public String getOriginal() {
return original;
}
public String getText() {
return text;
}
@Override
public int hashCode() {
return original.hashCode() + text.hashCode()
+ Boolean.valueOf(isEditing).hashCode() * 29
+ Boolean.valueOf(isEditingAgain).hashCode();
}
public boolean isEditing() {
return isEditing;
}
public boolean isEditingAgain() {
return isEditingAgain;
}
public void setEditing(boolean isEditing) {
boolean wasEditing = this.isEditing;
this.isEditing = isEditing;
// This is a subsequent edit, so start from where we left off.
if (!wasEditing && isEditing) {
isEditingAgain = true;
original = text;
}
}
public void setText(String text) {
this.text = text;
}
private boolean equalsOrBothNull(Object o1, Object o2) {
return (o1 == null) ? o2 == null : o1.equals(o2);
}
}
private static Template template;
private int inputWidth;
private int inputLength;
public int getInputWidth() {
return inputWidth;
}
public void setInputWidth(int inputWidth) {
this.inputWidth = inputWidth;
}
public int getInputLength() {
return inputLength;
}
public void setInputLength(int inputLength) {
this.inputLength = inputLength;
}
private final SafeHtmlRenderer<String> renderer;
/**
* Construct a new EditTextCell that will use a
* {@link SimpleSafeHtmlRenderer}.
*/
public TextAreaEditCell() {
this(SimpleSafeHtmlRenderer.getInstance(), 1, 20);
this.inputWidth = 10;
this.inputLength =2;
}
private int rows, cols;
/**
* Construct a new TextAreaEditCell that will use a given {@link SafeHtmlRenderer}
* to render the value when not in edit mode.
*
* @param renderer a {@link SafeHtmlRenderer SafeHtmlRenderer<String>}
* instance
*/
public TextAreaEditCell(SafeHtmlRenderer<String> renderer, int r, int c) {
super("click", "keyup", "keydown", "blur");
rows = r;
cols = c;
if (template == null) {
template = GWT.create(Template.class);
}
if (renderer == null) {
throw new IllegalArgumentException("renderer == null");
}
this.renderer = renderer;
}
@Override
public boolean isEditing(Context context, Element parent, String value) {
ViewData viewData = getViewData(context.getKey());
return viewData == null ? false : viewData.isEditing();
}
@Override
public void onBrowserEvent(Context context, Element parent, String value,
NativeEvent event, ValueUpdater<String> valueUpdater) {
Object key = context.getKey();
ViewData viewData = getViewData(key);
if (viewData != null && viewData.isEditing()) {
// Handle the edit event.
editEvent(context, parent, value, viewData, event, valueUpdater);
} else {
String type = event.getType();
int keyCode = event.getKeyCode();
boolean enterPressed = "keyup".equals(type) ;
// && keyCode == KeyCodes.KEY_ENTER;
if ("click".equals(type) || enterPressed) {
// Go into edit mode.
if (viewData == null) {
viewData = new ViewData(value);
setViewData(key, viewData);
} else {
viewData.setEditing(true);
}
edit(context, parent, value);
}
}
}
@Override
public void render(Context context, String value, SafeHtmlBuilder sb) {
// Get the view data.
Object key = context.getKey();
ViewData viewData = getViewData(key);
if (viewData != null && !viewData.isEditing() && value != null
&& value.equals(viewData.getText())) {
clearViewData(key);
viewData = null;
}
if (viewData != null) {
String text = viewData.getText();
if (viewData.isEditing()) {
/*
* Do not use the renderer in edit mode because the value of a text
* input element is always treated as text. SafeHtml isn't valid in the
* context of the value attribute.
*/
sb.append(template.input(text, inputLength, inputWidth));
}
else {
// The user pressed enter, but view data still exists.
sb.append(renderer.render(text));
}
} else if (value != null) {
sb.append(renderer.render(value));
}
}
@Override
public boolean resetFocus(Context context, Element parent, String value) {
if (isEditing(context, parent, value)) {
getInputElement(parent).focus();
return true;
}
return false;
}
/**
* Convert the cell to edit mode.
*
* @param context the {@link Context} of the cell
* @param parent the parent element
* @param value the current value
*/
protected void edit(Context context, Element parent, String value) {
setValue(context, parent, value);
TextAreaElement input = getInputElement(parent);
input.focus();
input.select();
}
/**
* Convert the cell to non-edit mode.
*
* @param context the context of the cell
* @param parent the parent Element
* @param value the value associated with the cell
*/
private void cancel(Context context, Element parent, String value) {
clearInput(getInputElement(parent));
setValue(context, parent, value);
}
/**
* Clear selected from the input element. Both Firefox and IE fire spurious
* onblur events after the input is removed from the DOM if selection is not
* cleared.
*
* @param input the input element
*/
private native void clearInput(Element input) /*-{
if (input.selectionEnd)
input.selectionEnd = input.selectionStart;
else if ($doc.selection)
$doc.selection.clear();
}-*/;
/**
* Commit the current value.
*
* @param context the context of the cell
* @param parent the parent Element
* @param viewData the {@link ViewData} object
* @param valueUpdater the {@link ValueUpdater}
*/
private void commit(Context context, Element parent, ViewData viewData,
ValueUpdater<String> valueUpdater) {
String value = updateViewData(parent, viewData, false);
clearInput(getInputElement(parent));
setValue(context, parent, viewData.getOriginal());
if (valueUpdater != null) {
valueUpdater.update(value);
}
}
private void editEvent(Context context, Element parent, String value,
ViewData viewData, NativeEvent event, ValueUpdater<String> valueUpdater) {
String type = event.getType();
boolean keyUp = "keyup".equals(type);
boolean keyDown = "keydown".equals(type);
if (keyUp || keyDown) {
int keyCode = event.getKeyCode();
/* if (keyUp && keyCode == KeyCodes.KEY_ENTER) {
// Commit the change.
commit(context, parent, viewData, valueUpdater);
}
else*/
if (keyUp && keyCode == KeyCodes.KEY_ESCAPE) {
// Cancel edit mode.
String originalText = viewData.getOriginal();
if (viewData.isEditingAgain()) {
viewData.setText(originalText);
viewData.setEditing(false);
} else {
setViewData(context.getKey(), null);
}
cancel(context, parent, value);
} else {
// Update the text in the view data on each key.
updateViewData(parent, viewData, true);
}
} else if ("blur".equals(type)) {
// Commit the change. Ensure that we are blurring the input element and
// not the parent element itself.
EventTarget eventTarget = event.getEventTarget();
if (Element.is(eventTarget)) {
Element target = Element.as(eventTarget);
if ("textarea".equals(target.getTagName().toLowerCase())) {
commit(context, parent, viewData, valueUpdater);
}
}
}
}
/**
* Get the input element in edit mode.
*/
private TextAreaElement getInputElement(Element parent) {
return parent.getFirstChild().<TextAreaElement> cast();
}
/**
* Update the view data based on the current value.
*
* @param parent the parent element
* @param viewData the {@link ViewData} object to update
* @param isEditing true if in edit mode
* @return the new value
*/
private String updateViewData(Element parent, ViewData viewData,
boolean isEditing) {
TextAreaElement input = (TextAreaElement) parent.getFirstChild();
String value = input.getValue();
viewData.setText(value);
viewData.setEditing(isEditing);
return value;
}
}
答案 1 :(得分:0)
我做了类似的事情;虽然不完全一样。所以也许像这样的SOMETHING会起作用。
您需要提供自己的render()方法。所以在下面的render()方法中,你可以添加你想要的任何内容。
列selectCheckBoxColumn = new Column(new MyCheckBoxCell()){
@Override
public String getValue(MyJSONObject object) {
return object.getInternalId();
}
};
MyCellTable.addColumn(selectCheckBoxColumn, "Display title");
.....
.....
.....
private class MyCheckBoxCell extends AbstractCell<String> {
@Override
public void render(Context context, String value, SafeHtmlBuilder sb) {
/*
* Always do a null check on the value. Cell widgets can pass null to
* cells if the underlying data contains a null, or if the data arrives
* out of order.
*/
if (value == null) {
return;
}
sb.appendHtmlConstant("<input type='checkbox' name='" + htmlDOMId1 + "'" +
" id='" + htmlDOMId1 + "'" +
" value='" + value + "'" +
"></input>");
}
}
答案 2 :(得分:0)
您必须将换行符(\ n)转换为HTML换行符(&lt; BR&gt;)
您可以在后端保存数据时执行此操作,也可以在 TextAreaEditCell
的渲染方法中执行此操作类似的东西:
@Override
public void render(Context context, String value, SafeHtmlBuilder sb) {
// Get the view data.
Object key = context.getKey();
ViewData viewData = getViewData(key);
if (viewData != null && !viewData.isEditing() && value != null
&& value.equals(viewData.getText())) {
clearViewData(key);
viewData = null;
}
if (viewData != null) {
String text = viewData.getText();
if (viewData.isEditing()) {
/*
* Do not use the renderer in edit mode because the value of a text
* input element is always treated as text. SafeHtml isn't valid in the
* context of the value attribute.
*/
sb.append(template.input(text, inputLength, inputWidth));
}
else {
// The user pressed enter, but view data still exists.
String escaped_text = text.replace("\n","<BR>").replace("\r","");
sb.append(renderer.render(escaped_text));
}
} else if (value != null) {
String escaped_text = value.replace("\n","<BR>").replace("\r","");
sb.append(renderer.render(escaped_text));
}
}
答案 3 :(得分:0)
这是render方法的工作解决方案,它将在TextAreaEditCell中显示多行。基本上,您将基于\ n字符拆分存储的字符串,然后将它们连接起来,将该标记作为SafeBuilder的HTML常量附加。
@覆盖 public void render(Context context,String value,SafeHtmlBuilder sb){
// Get the view data.
Object key = context.getKey();
ViewData viewData = getViewData(key);
if (viewData != null && !viewData.isEditing() && value != null
&& value.equals(viewData.getText())) {
clearViewData(key);
viewData = null;
/*
* Render a blank space to force the rendered element to have a height.
* Otherwise it is not clickable.
*/
sb.appendHtmlConstant("\u00A0");
}
if (viewData != null) {
String text = viewData.getText();
if (viewData.isEditing()) {
/*
* Do not use the renderer in edit mode because the value of a text
* input element is always treated as text. SafeHtml isn't valid in the
* context of the value attribute.
*/
sb.append(template.input(text, inputLength, inputWidth));
}
else {
// The user pressed enter, but view data still exists.
String[] items = text.split("\n");
for (String item : items) {
sb.append(renderer.render(item));
sb.appendHtmlConstant("<br/>");
}
sb.appendHtmlConstant("\u00A0");
}
} else if (value != null) {
String[] items = value.split("\n");
for (String item : items) {
sb.append(renderer.render(item));
sb.appendHtmlConstant("<br/>");
}
/*
* Render a blank space to force the rendered element to have a height.
* Otherwise it is not clickable.
*/
sb.appendHtmlConstant("\u00A0");
}
}