]> source.dussan.org Git - vaadin-framework.git/commitdiff
Text selection methods for TextField. Fixes #5217
authorMatti Tahvonen <matti.tahvonen@itmill.com>
Thu, 17 Jun 2010 14:49:46 +0000 (14:49 +0000)
committerMatti Tahvonen <matti.tahvonen@itmill.com>
Thu, 17 Jun 2010 14:49:46 +0000 (14:49 +0000)
svn changeset:13751/svn branch:6.4

src/com/vaadin/terminal/gwt/client/ui/VTextField.java
src/com/vaadin/ui/TextField.java
tests/src/com/vaadin/tests/components/textfield/SelectionAndCursorPosition.java [new file with mode: 0644]

index 7594bde3b13668932ac06474b877e7d33619a87d..50c81e19bdf06f5a8c002ade5c7aa3ebafa4c0ce 100644 (file)
@@ -55,9 +55,11 @@ public class VTextField extends TextBoxBase implements Paintable, Field,
 
     private static final String CLASSNAME_PROMPT = "prompt";
     private static final String ATTR_INPUTPROMPT = "prompt";
+    private static final String VAR_CURSOR = "c";
 
     private String inputPrompt = null;
     private boolean prompting = false;
+    private int lastCursorPos = -1;
 
     public VTextField() {
         this(DOM.createInputText());
@@ -142,6 +144,19 @@ public class VTextField extends TextBoxBase implements Paintable, Field,
         }
 
         valueBeforeEdit = uidl.getStringVariable("text");
+
+        if (uidl.hasAttribute("selpos")) {
+            final int pos = uidl.getIntAttribute("selpos");
+            final int length = uidl.getIntAttribute("sellen");
+            /*
+             * Gecko defers setting the text so we need to defer the selection.
+             */
+            DeferredCommand.addCommand(new Command() {
+                public void execute() {
+                    setSelectionRange(pos, length);
+                }
+            });
+        }
     }
 
     private void setMaxLength(int newMaxLength) {
@@ -197,12 +212,35 @@ public class VTextField extends TextBoxBase implements Paintable, Field,
                 valueBeforeEdit = newText;
             }
 
+            /*
+             * also send cursor position, no public api yet but for easier
+             * extension
+             */
+            updateCursorPosition();
+
             if (sendBlurEvent || sendValueChange) {
                 client.sendPendingVariableChanges();
             }
         }
     }
 
+    /**
+     * Updates the cursor position variable if it has changed since the last
+     * update.
+     * 
+     * @return true iff the value was updated
+     */
+    protected boolean updateCursorPosition() {
+        int cursorPos = getCursorPos();
+        if (lastCursorPos != cursorPos) {
+            client.updateVariable(id, VAR_CURSOR, cursorPos, false);
+            lastCursorPos = cursorPos;
+            return true;
+        } else {
+            return false;
+        }
+    }
+
     private static VTextField focusedTextField;
 
     public static void flushChangesFromFocusedTextField() {
index aa4c7c86611060a84dc5f7da2a25cdbcad164e85..fff0beaf0c91d72b847d2abbbac9e65a284edf4f 100644 (file)
@@ -90,6 +90,10 @@ public class TextField extends AbstractField implements
      */
     private int maxLength = -1;
 
+    private int selectionPosition = -1;
+
+    private int selectionLength;
+
     /* Constructors */
 
     /**
@@ -174,6 +178,11 @@ public class TextField extends AbstractField implements
         if (inputPrompt != null) {
             target.addAttribute("prompt", inputPrompt);
         }
+        if (selectionPosition != -1) {
+            target.addAttribute("selpos", selectionPosition);
+            target.addAttribute("sellen", selectionLength);
+            selectionPosition = -1;
+        }
 
         // Adds the number of column and rows
         final int columns = getColumns();
@@ -635,4 +644,46 @@ public class TextField extends AbstractField implements
         removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener);
     }
 
+    /**
+     * Selects all text in the field.
+     * 
+     * @since 6.4
+     */
+    public void selectAll() {
+        String text = getValue() == null ? "" : getValue().toString();
+        setSelectionRange(0, text.length());
+    }
+
+    /**
+     * Sets the range of text to be selected.
+     * 
+     * As a side effect the field will become focused.
+     * 
+     * @since 6.4
+     * 
+     * @param pos
+     *            the position of the first character to be selected
+     * @param length
+     *            the number of characters to be selected
+     */
+    public void setSelectionRange(int pos, int length) {
+        selectionPosition = pos;
+        selectionLength = length;
+        focus();
+        requestRepaint();
+    }
+
+    /**
+     * Sets the cursor position in the field. As a side effect the field will
+     * become focused.
+     * 
+     * @since 6.4
+     * 
+     * @param pos
+     *            the position for the cursor
+     * */
+    public void setCursorPosition(int pos) {
+        setSelectionRange(pos, 0);
+    }
+
 }
diff --git a/tests/src/com/vaadin/tests/components/textfield/SelectionAndCursorPosition.java b/tests/src/com/vaadin/tests/components/textfield/SelectionAndCursorPosition.java
new file mode 100644 (file)
index 0000000..3a9f35f
--- /dev/null
@@ -0,0 +1,104 @@
+package com.vaadin.tests.components.textfield;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.FormLayout;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Panel;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+
+public class SelectionAndCursorPosition extends TestBase {
+
+    TextField tf = new TextField();
+
+    @Override
+    protected void setup() {
+
+        tf.setCaption("Text field");
+        tf.setValue("So we have some text to select");
+        tf.setWidth("400px");
+
+        FormLayout fl = new FormLayout();
+        Panel panel = new Panel(fl);
+        panel.setCaption("Hackers panel");
+        CheckBox ml = new CheckBox("Multiline");
+        ml.setImmediate(true);
+        ml.addListener(new Property.ValueChangeListener() {
+            public void valueChange(ValueChangeEvent event) {
+                if (tf.getHeight() < 0) {
+                    tf.setHeight("50px");
+                } else {
+                    tf.setSizeUndefined();
+                    tf.setRows(0);
+                }
+                tf.setWidth("400px");
+            }
+        });
+        fl.addComponent(ml);
+
+        Button b = new Button("Select all ( selectAll() )");
+        b.addListener(new ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                tf.selectAll();
+            }
+        });
+        fl.addComponent(b);
+
+        HorizontalLayout selectRange = new HorizontalLayout();
+        selectRange
+                .setCaption("Select range of text ( setSelectionRange(int start, int lengt) )");
+        final TextField start = new TextField("From:");
+        final TextField length = new TextField("Selection length:");
+        b = new Button("select");
+        b.addListener(new ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                int startPos = Integer.parseInt((String) start.getValue());
+                int lenght = Integer.parseInt((String) length.getValue());
+                tf.setSelectionRange(startPos, lenght);
+            }
+        });
+
+        selectRange.addComponent(start);
+        selectRange.addComponent(length);
+        selectRange.addComponent(b);
+        fl.addComponent(selectRange);
+
+        HorizontalLayout setCursorPosition = new HorizontalLayout();
+        final TextField pos = new TextField("Position:");
+        b = new Button("set");
+        b.addListener(new ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                int startPos = Integer.parseInt((String) pos.getValue());
+                tf.setCursorPosition(startPos);
+            }
+        });
+
+        setCursorPosition.addComponent(pos);
+        setCursorPosition.addComponent(b);
+        setCursorPosition
+                .setCaption("Set cursor position ( setCursorPosition(int pos) )");
+        fl.addComponent(setCursorPosition);
+
+        getLayout().addComponent(tf);
+        getLayout().addComponent(panel);
+
+    }
+
+    @Override
+    protected String getDescription() {
+        return "For usability reasons it is often essential that developer "
+                + "can hint how to select the text in the "
+                + "field or where to set the cursor position.";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 2058;
+    }
+
+}