如何在GWT单元格中添加多行文本EditTextCell



我有一个显示数据的单元格表。我想编辑单元格以在多行中提供信息。

的例子:key1=value1|在下一行添加另一个键:key2 = value2 |

编辑值后,当单元格表被显示/重绘时,信息应该像上面那样显示在单元格中。

我已经解决了部分问题。我使用自定义TextAreaEditCell的CellTable。现在我可以输入多行数据了。但是当它进入数据库或当celltable显示信息时,信息是顺序的。

例子:

当我在TestAreaCell中输入这样的数据:abcd在下一行中,输入efgh,然后输入

显示时输出为:

abcdefgh

问题:回车键似乎没有得到考虑:

我的TextAreaEditCell类如下。如果有需要修改的地方,请告诉我。

我已经解决了部分问题。我使用自定义TextAreaEditCell的CellTable。现在我可以输入多行数据了。但是当它进入数据库或当celltable显示信息时,信息是顺序的。

例子:

当我在TestAreaCell中输入这样的数据:abcd在下一行中,输入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; 
    } 
} 

我也做过类似的事情;虽然不完全一样。所以也许这样做会有用。

您需要提供自己的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>");
      }
   }

必须将换行符(n)转换为HTML换行符(
)

你可以在你的后端保存数据时做到这一点,也可以在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)); 
    } 
} 

这是渲染方法的一个工作解决方案,它将在TextAreaEditCell中显示多行。基本上,您是基于n字符分割存储的字符串,然后将它们连接起来,并将
标记作为SafeBuilder的HTML常量。

@Overridepublic 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");
    }
} 

相关内容

  • 没有找到相关文章

最新更新