2011-06-08 16 views
11

當字段正在編輯時,如何設置文本框的寬度?EditTextCell FieldUpdater寬度

EditTextCell febCell = new EditTextCell(); 
Column<DTO, String> febColumn = new Column<DTO, String>(febCell){ 
    @Override 
    public String getValue(DTO object) { 
     return (String.valueOf(object.getFeb())); 
    } 
}; 
febColumn.setFieldUpdater(new FieldUpdater<DTO, String>() { 
    public void update(int index, DTO object, String value) { 
     System.out.println("index="+index+" resourceId="+object.getId()+" feb="+value); 
    } 
}); 
febColumn.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LOCALE_END); 
cellTable.addColumn(febColumn, "Feb"); 
cellTable.setColumnWidth(febColumn, 3, Unit.PCT); 

一切正常,但是當我點擊可編輯字段時會出現一個很大的文本框。那麼,我如何定製這個小部件來編輯數據?

如果我設置了類似

cellTable.setColumnWidth(febColumn, 25, Unit.PX); 

在PX,而不是PCT寬度小區不爆炸,同時編輯,但內部文本框仍然具有相同的長寬度和長字符串值隱藏了背後右邊。

好的。也許我需要重新發明的輪子爲每一種EditTextCell的那樣:

MyEditTextCell extends AbstractEditableCell<String, MyEditTextCell.ViewData> ... 
interface MyTemplate extends SafeHtmlTemplates { 
    @Template("<input type=\"text\" value=\"{0}\" tabindex=\"-1\" size=\"{1}\" maxlength=\"{1}\" style=\"{2}\"></input>") 
    SafeHtml input(String value, Integer maxLength, String style); 
} 
... 
@Override public void render(com.google.gwt.cell.client.Cell.Context context, 
          String value, SafeHtmlBuilder sb) {... 

sb.append(template.input(text, maxLegth, style)); 

,並使用控件那樣:

MyEditTextCell febCell = new MyEditTextCell(SimpleSafeHtmlRenderer.getInstance(), 4, "width:35px;"); 

任何想法都歡迎。

+0

好問題。其實,我需要同樣的功能。但我需要把它做大。我可以在不重新實現EditTextCell的情況下做到嗎?有任何想法嗎? – 2011-06-28 15:25:27

+0

我也有同樣的問題。我如何調整EditTextCell的大小? – sap 2011-06-30 20:55:57

+0

@ user491753,我只是複製/粘貼EditTextCell。比,將大小參數添加到模板。將大小設置器添加到我的課程中。並使用渲染方法中的設置值。如果不明確,請在此處填寫,我將提供完整的源代碼。 – 2011-07-01 09:13:09

回答

1

你在正確的軌道上。使用文本區域元素而不是輸入類型=「文本」。我從EditTextCell的源頭開始,並在適當的位置插入textarea元素而不是輸入。請參閱以下代碼

public class TextAreaEditCell extends 
    AbstractEditableCell<String, TextAreaEditCell.ViewData> { 

interface Template extends SafeHtmlTemplates { 
    @Template("<textarea tabindex=\"-1\" rows=\"{1}\" cols=\"{2}\" >{0}</textarea>") 
    SafeHtml input(String value, Integer rows, Integer cols); 
} 
... 
private int rows, cols; 

/** 
* Construct a new EditTextCell that will use a 
* {@link SimpleSafeHtmlRenderer}. 
*/ 
public TextAreaEditCell() { 
    this(SimpleSafeHtmlRenderer.getInstance(), 1, 20); 
} 

/** 
* Construct a new EditTextCell 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; 
... 
} 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())) { 
... 
/** 
* Get the input element in edit mode. 
*/ 
private TextAreaElement getInputElement(Element parent) { 
    return parent.getFirstChild().<TextAreaElement> cast(); 
} 
... 
    private String updateViewData(Element parent, ViewData viewData, 
     boolean isEditing) { 
    TextAreaElement input = (TextAreaElement) parent.getFirstChild(); 
    // InputElement input = (InputElement) parent.getFirstChild(); 
... 
+0

我可以在輸入元素上指定大小來做這件事。任務是在不復制/粘貼或重新實現當前小部件的情況下執行此操作。 – 2011-06-30 12:38:13

4

重新實現的解決方案。請注意0​​方法。

public class JustInPlaceEditCell extends AbstractEditableCell<String, JustInPlaceEditCell.ViewData> { 

    interface Template extends SafeHtmlTemplates { 
     @Template("<input type=\"text\" value=\"{0}\" tabindex=\"-1\" size=\"{1}\"></input>") 
     SafeHtml input(String value, int size); 
    } 

    /** 
    * 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 = 20; 

    public int getInputWidth() { 
     return inputWidth; 
    } 

    public void setInputWidth(int inputWidth) { 
     this.inputWidth = inputWidth; 
    } 

    private final SafeHtmlRenderer<String> renderer; 

    /** 
    * Construct a new EditTextCell that will use a 
    * {@link com.google.gwt.text.shared.SimpleSafeHtmlRenderer}. 
    */ 
    public JustInPlaceEditCell() { 
     this(SimpleSafeHtmlRenderer.getInstance()); 
    } 

    /** 
    * Construct a new EditTextCell that will use a given {@link SafeHtmlRenderer}. 
    * 
    * @param renderer a {@link SafeHtmlRenderer SafeHtmlRenderer<String>} instance 
    */ 
    public JustInPlaceEditCell(SafeHtmlRenderer<String> renderer) { 
     super("click", "keyup", "keydown", "blur"); 
     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(); 
      SafeHtml html = renderer.render(text); 
      if (viewData.isEditing()) { 
       // Note the template will not treat SafeHtml specially 
       sb.append(template.input(html.asString(), inputWidth)); 
      } else { 
       // The user pressed enter, but view data still exists. 
       sb.append(html); 
      } 
     } else if (value != null) { 
      SafeHtml html = renderer.render(value); 
      sb.append(html); 
     } 
    } 

    @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); 
     InputElement 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 ("input".equals(target.getTagName().toLowerCase())) { 
        commit(context, parent, viewData, valueUpdater); 
       } 
      } 
     } 
    } 

    /** 
    * Get the input element in edit mode. 
    */ 
    private InputElement getInputElement(Element parent) { 
     return parent.getFirstChild().<InputElement>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) { 
     InputElement input = (InputElement) parent.getFirstChild(); 
     String value = input.getValue(); 
     viewData.setText(value); 
     viewData.setEditing(isEditing); 
     return value; 
    } 
} 
+0

它的工作!非常感謝。現在,如果我想在創建JustInPlaceEditCell時將寬度作爲參數傳遞,那麼我需要更改哪些內容? – sap 2011-07-01 16:22:12

+1

@ user491753你應該添加構造函數,它將採用'inputWidth'。或者只是在創建後使用setter – 2011-07-01 16:34:48

+0

你在那裏有一個錯誤 - 而不是值= \「{0} \」你需要{0}在textarea標籤之間,否則值將不會顯示 – Vladimir 2012-02-08 20:50:31