2010-05-19 14 views
14

Necesito un campo de texto muy similar en comportamiento al Número de Campo de Gxt. Lamentablemente, no estoy usando Gxt en mi aplicación y GWT 2.0 aún no tiene una implementación de campo de texto numérico.Solución para Campo de Texto Numérico en GWT

Por lo tanto, actualmente me deja la opción de simular un NumberField filtrando las pulsaciones de teclas no numéricas con un keyboardHandler.

¿Es esta la mejor manera de abordar el problema? ¿Alguien aquí tiene una mejor solución/enfoque en mente?

Gracias de antemano :)

+0

Guess, este es un requisito muy frecuente en applicati CRUD ons. Me gustaría saber cómo lo han implementado. –

+1

El filtrado a través de uno de los controladores "Key * Handler" parece bastante sencillo: ¿qué más necesita/espera? También puedes consultar el código fuente de GXT para ver cómo implementaron NumberField, volver a implementarlo en GWT debería ser muy fácil. –

Respuesta

13

Aquí puede encontrar el código que utilizo en una de mis clases. Las características son mucho más limitadas que las de GXT, pero deberían ubicarte en el camino correcto.

Es un widget realmente básico, pero hace lo que necesito.

public class ValueTextBox extends TextBox { 

    private int min = 0; 
    private int max = 100; 
    private boolean minConstrained = true; 
    private boolean maxConstrained = true; 
    private int minDigits = 1; 
    private int step = 1; 

    private KeyUpHandler keyUpHandler = new KeyUpHandler() { 

     @Override 
     public void onKeyUp(KeyUpEvent event) { 
      if (isReadOnly() || !isEnabled()) { 
       return; 
      } 

      int keyCode = event.getNativeEvent().getKeyCode(); 

      boolean processed = false; 

      switch (keyCode) { 
      case KeyCodes.KEY_LEFT: 
      case KeyCodes.KEY_RIGHT: 
      case KeyCodes.KEY_BACKSPACE: 
      case KeyCodes.KEY_DELETE: 
      case KeyCodes.KEY_TAB: 
       if (getText().isEmpty()) { 
        setValue(formatValue(min)); 
       } 
       return; 
      case KeyCodes.KEY_UP: 
       if (step != 0) { 
        increaseValue(); 
        processed = true; 
       } 
       break; 
      case KeyCodes.KEY_DOWN: 
       if (step != 0) { 
        decreaseValue(); 
        processed = true; 
       } 
       break; 
      } 

      if (processed) { 
       cancelKey(); 
      } 
     } 

    }; 

    private KeyPressHandler keyPressHandler = new KeyPressHandler() { 
     @Override 
     public void onKeyPress(KeyPressEvent event) { 

      if (isReadOnly() || !isEnabled()) { 
       return; 
      } 

      int keyCode = event.getNativeEvent().getKeyCode(); 

      switch (keyCode) { 
      case KeyCodes.KEY_LEFT: 
      case KeyCodes.KEY_RIGHT: 
      case KeyCodes.KEY_BACKSPACE: 
      case KeyCodes.KEY_DELETE: 
      case KeyCodes.KEY_TAB: 
      case KeyCodes.KEY_UP: 
      case KeyCodes.KEY_DOWN: 
       return; 
      } 

      int index = getCursorPos(); 
      String previousText = getText(); 
      String newText; 
      if (getSelectionLength() > 0) { 
       newText = previousText.substring(0, getCursorPos()) 
         + event.getCharCode() 
         + previousText.substring(getCursorPos() 
           + getSelectionLength(), previousText.length()); 
      } else { 
       newText = previousText.substring(0, index) 
         + event.getCharCode() 
         + previousText.substring(index, previousText.length()); 
      } 
      cancelKey(); 

      setValue(newText, true); 
     } 
    }; 

    public ValueTextBox(int value) { 
     this(value, 0, 100); 
    } 

    public ValueTextBox(int value, int min, int max) { 
     this(value, min, max, true); 
    } 

    public ValueTextBox(int value, int min, int max, boolean constrained) { 
     this(value, min, max, constrained, constrained); 
    } 

    public ValueTextBox(int value, int min, int max, boolean minConstrained, 
      boolean maxConstrained) { 
     super(); 

     addKeyPressHandler(keyPressHandler); 
     addKeyUpHandler(keyUpHandler); 

     this.min = min; 
     this.max = max; 
     this.minConstrained = minConstrained; 
     this.maxConstrained = maxConstrained; 

     setValue(formatValue(value), false); 
     setTextAlignment(TextBoxBase.ALIGN_CENTER); 
     setStyleName(Resources.INSTANCE.css().fwFormEntry()); 
    } 

    public void setMinDigits(int minDigits) { 
     if (minDigits > 0) { 
      this.minDigits = minDigits; 

      String value = getText(); 
      long newValue = parseValue(value); 

      setText(formatValue(newValue)); 
     } 
    } 

    public void setSteps(int step) { 
     this.step = step; 
    } 

    protected void increaseValue() { 
     if (step != 0) { 
      String value = getText(); 
      long newValue = parseValue(value); 
      newValue += step; 
      if (maxConstrained && (newValue > max)) { 
       return; 
      } 
      setValue(formatValue(newValue)); 
     } 
    } 

    protected void decreaseValue() { 
     if (step != 0) { 
      String value = getText(); 
      long newValue = parseValue(value); 
      newValue -= step; 
      if (minConstrained && (newValue < min)) { 
       return; 
      } 
      setValue(formatValue(newValue)); 
     } 
    } 

    /** 
    * @param value 
    *   the value to format 
    * @return the formatted value 
    */ 
    protected String formatValue(long value) { 
     String newValue = String.valueOf(value); 

     if (minDigits > newValue.length()) { 
      String leading = StringUtils.repeat("0", (minDigits - newValue 
        .length())); 
      newValue = leading + newValue; 
     } 

     return newValue; 
    } 

    @Override 
    public void setValue(String value) { 
     setValue(value, false); 
    } 

    @Override 
    public void setValue(String value, boolean fireEvents) { 
     try { 
      long newValue = parseValue(value); 
      if ((maxConstrained && (newValue > max)) 
        || (minConstrained && (newValue < min))) { 
       return; 
      } 
      String prevText = getValue(); 
      super.setText(formatValue(newValue)); 
      if (fireEvents) { 
       ValueChangeEvent.fireIfNotEqual(this, getValue(), prevText); 
      } 
     } catch (Exception ex) { 
      // Do Nothing 
      System.out.println(ex.getMessage()); 
     } 
    } 

    /** 
    * @param value 
    *   the value to parse 
    * @return the parsed value 
    */ 
    protected long parseValue(String value) { 
     return Long.valueOf(value); 
    } 
} 

actualización: El código está disponible en https://github.com/ctasada/GWT-Eureka

+0

Gracias Carlos, Implementé mi versión en NumberField siguiendo líneas similares completamente en KeyPressHandler ya que no necesitaba las funciones keyUp y KeyDown - spinner.Me gusta especialmente su técnica FormatValue, ya que también transmite sutilmente el límite máximo del campo, planificando su idea; Publicaré mi versión tan pronto como llegue a mi estación de trabajo de desarrollo. Gracias :) –

+0

Eso ayuda mucho, ¿puedo usar comercialmente ese código? Y si es así, ¿bajo qué condiciones? – slartidan

+2

@slartidan. Solo vote si le ayudó;) Solo póngase en contacto conmigo si necesita ayuda adicional. –

0

Aquí está mi aplicación de NumberField. Muy similar en funcionalidad a la versión de Carlos, pero con soporte adicional para entrada decimal y filtrado de clave no numérico.

public class NumberBox extends TextBox 
{ 
private boolean isDecimal = false; 

public NumberBox() 
{ 
} 

public boolean isDecimal() 
{ 
    return isDecimal; 
} 

public void setDecimal(boolean isDecimal) 
{ 
    this.isDecimal = isDecimal; 
} 

public Integer getIntegerValue() 
{ 
    return (StringUtil.isEmpty(getSanitizedValue())) ? null : Integer.parseInt(getSanitizedValue()); 
} 

@Override 
protected void initialize() 
{ 
    super.initialize(); 
    addStyleName("number"); 

    this.addKeyPressHandler(new KeyPressHandler() 
    { 
     public void onKeyPress(KeyPressEvent event) 
     { 
      if (!isEnabled() || isReadOnly()) 
       return; 

      int keyCode = event.getNativeEvent().getKeyCode(); 

      // allow special keys 
      if ((keyCode == KeyCodes.KEY_BACKSPACE) 
        || (keyCode == KeyCodes.KEY_DELETE) 
        || (keyCode == KeyCodes.KEY_ENTER) || (keyCode == KeyCodes.KEY_ESCAPE) || (keyCode == KeyCodes.KEY_RIGHT) 
        || (keyCode == KeyCodes.KEY_LEFT) || (keyCode == KeyCodes.KEY_TAB)) 
       return; 

      // check for decimal '.' 
      if (isDecimal() && '.' == (char)keyCode && !getValue().contains(".")) 
       return; 

      // filter out non-digits 
      if (Character.isDigit(charCode)) 
       return; 

      cancelKey(); 
     } 
    }); 
} 

}


PS: Superclase cuadro de texto es una clase personalizada que se extiende GWT cuadro de texto con algunas características específicas de aplicación adicionales. El método initialize() se invoca básicamente dentro del constructor TextBox, y getSanitizedValue realiza algunas comprobaciones básicas de cordura con el recorte.

5

Aquí hay un KeyPressHandler simple que permite al usuario ingresar números decimales;

public void onKeyPress(KeyPressEvent event){ 
    TextBox sender = (TextBox)event.getSource(); 

    if (sender.isReadOnly() || !sender.isEnabled()) { 
     return; 
    } 

    Character charCode = event.getCharCode(); 
    int unicodeCharCode = event.getUnicodeCharCode(); 

    // allow digits, '.' and non-characters 
    if (!(Character.isDigit(charCode) || charCode == '.' || unicodeCharCode == 0)){ 
     sender.cancelKey(); 
    } 
} 
+0

Esta solución permite puntos decimales múltiples, lo que produce un número de punto decimal no válido. – Alicia

1

Carlos Tasada obras respuesta, pero contiene un error: se debe añadir event.isShiftKeyDown() Llegada manejador onKeyPress antes del bloque switch/case. Ya pasará algunos símbolos como '(' lo contrario

+0

Pero todavía pasará 'y. símbolos, por lo que debe comprobar event.getCharCode() también – HtonS

3

No sabe cuando se añadieron estas clases para GWT, pero funcionan muy bien para mí sin ningún código adicional:.

com.google.gwt.user.client.ui.DoubleBox 
com.google.gwt.user.client.ui.IntegerBox 
com.google.gwt.user.client.ui.LongBox 

Para la validación más avanzada que lo desea, puede sobrescribir su ValueBox clase base con un poco de analizador personalizado ...

1

sobre la base de Julian Downes respuesta que puede hacer esto:

text.addKeyPressHandler(new KeyPressHandler() { 

     @Override 
     public void onKeyPress(KeyPressEvent event) { 
      TextBox sender = (TextBox) event.getSource(); 

      if (sender.isReadOnly() || !sender.isEnabled()) { 
       return; 
      } 
      if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER){ 
       return; 
      } 

      Character charCode = event.getCharCode(); 

      try{ 
       Double.parseDouble(sender.getText().concat(charCode.toString())); 
      } 
      catch(Exception e){ 
       sender.cancelKey(); 
      } 
     } 
    }); 
Cuestiones relacionadas