Change-Id: Ia2d357b77842bef188ae1f2a25e4a6a1c0a86dd0feature/vaadin8-book
/* | |||||
* Copyright 2000-2014 Vaadin Ltd. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||||
* use this file except in compliance with the License. You may obtain a copy of | |||||
* the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||||
* License for the specific language governing permissions and limitations under | |||||
* the License. | |||||
*/ | |||||
package com.vaadin.client.connectors.fields; | |||||
import com.google.gwt.core.client.Scheduler; | |||||
import com.google.gwt.event.dom.client.ChangeEvent; | |||||
import com.google.gwt.event.dom.client.ChangeHandler; | |||||
import com.google.gwt.user.client.Command; | |||||
import com.google.gwt.user.client.ui.TextBox; | |||||
import com.vaadin.client.communication.StateChangeEvent; | |||||
import com.vaadin.client.ui.AbstractComponentConnector; | |||||
import com.vaadin.shared.ui.Connect; | |||||
import com.vaadin.shared.ui.Connect.LoadStyle; | |||||
import com.vaadin.shared.ui.components.fields.TextFieldServerRpc; | |||||
import com.vaadin.shared.ui.components.fields.TextFieldState; | |||||
@Connect(value = com.vaadin.ui.components.fields.TextField.class, loadStyle = LoadStyle.EAGER) | |||||
public class TextFieldConnector extends AbstractComponentConnector { | |||||
@Override | |||||
protected void init() { | |||||
getWidget().addChangeHandler(new ChangeHandler() { | |||||
@Override | |||||
public void onChange(ChangeEvent event) { | |||||
getRpcProxy(TextFieldServerRpc.class) | |||||
.setText(getWidget().getValue()); | |||||
} | |||||
}); | |||||
} | |||||
@Override | |||||
public TextFieldState getState() { | |||||
return (TextFieldState) super.getState(); | |||||
} | |||||
@Override | |||||
public TextBox getWidget() { | |||||
return (TextBox) super.getWidget(); | |||||
} | |||||
@Override | |||||
public void onStateChanged(StateChangeEvent stateChangeEvent) { | |||||
// TODO Split into separate @OnStateChanged methods | |||||
super.onStateChanged(stateChangeEvent); | |||||
final TextBox w = getWidget(); | |||||
final TextFieldState state = getState(); | |||||
w.setReadOnly(state.readOnly); | |||||
if (state.placeholder != null) { | |||||
w.getElement().setAttribute("placeholder", state.placeholder); | |||||
} else { | |||||
w.getElement().removeAttribute("placeholder"); | |||||
} | |||||
if (state.maxLength >= 0) { | |||||
w.setMaxLength(state.maxLength); | |||||
} else { | |||||
w.getElement().removeAttribute("maxlength"); | |||||
} | |||||
w.setValue(state.text); | |||||
if (state.selectionStart != -1) { | |||||
/* | |||||
* Gecko defers setting the text so we need to defer the selection. | |||||
*/ | |||||
Scheduler.get().scheduleDeferred(new Command() { | |||||
@Override | |||||
public void execute() { | |||||
w.setSelectionRange(state.selectionStart, | |||||
state.selectionLength); | |||||
} | |||||
}); | |||||
} | |||||
} | |||||
} |
/* | |||||
* Copyright 2000-2014 Vaadin Ltd. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||||
* use this file except in compliance with the License. You may obtain a copy of | |||||
* the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||||
* License for the specific language governing permissions and limitations under | |||||
* the License. | |||||
*/ | |||||
package com.vaadin.ui.components.fields; | |||||
import java.util.Collection; | |||||
import org.jsoup.nodes.Attributes; | |||||
import org.jsoup.nodes.Element; | |||||
import com.vaadin.event.FieldEvents.BlurEvent; | |||||
import com.vaadin.event.FieldEvents.BlurListener; | |||||
import com.vaadin.event.FieldEvents.FocusEvent; | |||||
import com.vaadin.event.FieldEvents.FocusListener; | |||||
import com.vaadin.event.FieldEvents.TextChangeEvent; | |||||
import com.vaadin.event.FieldEvents.TextChangeListener; | |||||
import com.vaadin.event.handler.Handler; | |||||
import com.vaadin.event.handler.Registration; | |||||
import com.vaadin.shared.ui.components.fields.TextFieldServerRpc; | |||||
import com.vaadin.shared.ui.components.fields.TextFieldState; | |||||
import com.vaadin.ui.AbstractComponent; | |||||
import com.vaadin.ui.components.HasValue; | |||||
import com.vaadin.ui.declarative.DesignAttributeHandler; | |||||
import com.vaadin.ui.declarative.DesignContext; | |||||
/** | |||||
* Abstract base class for text input components. | |||||
* | |||||
* @author Vaadin Ltd. | |||||
*/ | |||||
public abstract class AbstractTextField extends AbstractComponent | |||||
implements HasValue<String> { | |||||
protected AbstractTextField() { | |||||
registerRpc(new TextFieldServerRpc() { | |||||
@Override | |||||
public void blur() { | |||||
fireEvent(new BlurEvent(AbstractTextField.this)); | |||||
} | |||||
@Override | |||||
public void focus() { | |||||
fireEvent(new FocusEvent(AbstractTextField.this)); | |||||
} | |||||
@Override | |||||
public void setText(String text) { | |||||
if (!isReadOnly()) { | |||||
setValue(text); | |||||
fireEvent(new TextChangeEvent(AbstractTextField.this) { | |||||
@Override | |||||
public String getText() { | |||||
return text; | |||||
} | |||||
@Override | |||||
public int getCursorPosition() { | |||||
return 0; // TODO | |||||
} | |||||
}); | |||||
} | |||||
} | |||||
}); | |||||
} | |||||
@Override | |||||
protected TextFieldState getState() { | |||||
return (TextFieldState) super.getState(); | |||||
} | |||||
@Override | |||||
protected TextFieldState getState(boolean markAsDirty) { | |||||
return (TextFieldState) super.getState(markAsDirty); | |||||
} | |||||
/** | |||||
* Returns the maximum number of characters in the field. Value -1 is | |||||
* considered unlimited. Terminal may however have some technical limits. | |||||
* | |||||
* @return the maxLength | |||||
*/ | |||||
public int getMaxLength() { | |||||
return getState(false).maxLength; | |||||
} | |||||
/** | |||||
* Sets the maximum number of characters in the field. Value -1 is | |||||
* considered unlimited. Terminal may however have some technical limits. | |||||
* | |||||
* @param maxLength | |||||
* the maxLength to set | |||||
*/ | |||||
public void setMaxLength(int maxLength) { | |||||
getState().maxLength = maxLength; | |||||
} | |||||
/** | |||||
* Returns the current placeholder text. | |||||
* | |||||
* @see #setPlaceholder(String) | |||||
* @return the placeholder text | |||||
*/ | |||||
public String getPlaceholder() { | |||||
return getState(false).placeholder; | |||||
} | |||||
/** | |||||
* Sets the placeholder text. The placeholder is text that is displayed when | |||||
* the field would otherwise be empty, to prompt the user for input. | |||||
* | |||||
* @param placeholder | |||||
* the placeholder text to set | |||||
*/ | |||||
public void setPlaceholder(String placeholder) { | |||||
getState().placeholder = placeholder; | |||||
} | |||||
@Override | |||||
public void setValue(String text) { | |||||
// TODO Accept nulls or not? | |||||
getState().text = text; | |||||
} | |||||
@Override | |||||
public String getValue() { | |||||
return getState(false).text; | |||||
} | |||||
@Override | |||||
public Registration onChange(Handler<String> handler) { | |||||
TextChangeListener l = e -> handler | |||||
.handleEvent(new com.vaadin.event.handler.Event<String>(this, | |||||
e.getText(), true)); | |||||
addListener(TextChangeListener.EVENT_ID, TextChangeEvent.class, l, | |||||
TextChangeListener.EVENT_METHOD); | |||||
return () -> removeListener(TextChangeEvent.class, l); | |||||
} | |||||
/** | |||||
* Selects all text in the field. | |||||
* | |||||
*/ | |||||
public void selectAll() { | |||||
// TODO Do we need this API? Or provide as extension? | |||||
setSelection(0, getValue().length()); | |||||
} | |||||
/** | |||||
* Sets the range of text to be selected. | |||||
* | |||||
* As a side effect the field will become focused. | |||||
* | |||||
* @param pos | |||||
* the position of the first character to be selected | |||||
* @param length | |||||
* the number of characters to be selected | |||||
*/ | |||||
public void setSelection(int start, int length) { | |||||
// TODO Do we need this API? Or provide as extension? | |||||
getState().selectionStart = start; | |||||
getState().selectionLength = length; | |||||
focus(); | |||||
} | |||||
/** | |||||
* Sets the cursor position in the field. As a side effect the field will | |||||
* become focused. | |||||
* | |||||
* @param pos | |||||
* the position for the cursor | |||||
*/ | |||||
public void setCursorPosition(int pos) { | |||||
setSelection(pos, 0); | |||||
} | |||||
@Deprecated | |||||
public void addFocusListener(FocusListener listener) { | |||||
addListener(FocusEvent.EVENT_ID, FocusEvent.class, listener, | |||||
FocusListener.focusMethod); | |||||
} | |||||
@Deprecated | |||||
public void removeFocusListener(FocusListener listener) { | |||||
removeListener(FocusEvent.EVENT_ID, FocusEvent.class, listener); | |||||
} | |||||
@Deprecated | |||||
public void addBlurListener(BlurListener listener) { | |||||
addListener(BlurEvent.EVENT_ID, BlurEvent.class, listener, | |||||
BlurListener.blurMethod); | |||||
} | |||||
@Deprecated | |||||
public void removeBlurListener(BlurListener listener) { | |||||
removeListener(BlurEvent.EVENT_ID, BlurEvent.class, listener); | |||||
} | |||||
@Override | |||||
public void readDesign(Element design, DesignContext designContext) { | |||||
super.readDesign(design, designContext); | |||||
Attributes attr = design.attributes(); | |||||
if (attr.hasKey("maxlength")) { | |||||
setMaxLength(DesignAttributeHandler.readAttribute("maxlength", attr, | |||||
Integer.class)); | |||||
} | |||||
} | |||||
@Override | |||||
protected Collection<String> getCustomAttributes() { | |||||
Collection<String> customAttributes = super.getCustomAttributes(); | |||||
customAttributes.add("maxlength"); | |||||
customAttributes.add("max-length"); // to prevent this appearing in | |||||
// output | |||||
customAttributes.add("cursor-position"); | |||||
return customAttributes; | |||||
} | |||||
@Override | |||||
public void writeDesign(Element design, DesignContext designContext) { | |||||
super.writeDesign(design, designContext); | |||||
AbstractTextField def = (AbstractTextField) designContext | |||||
.getDefaultInstance(this); | |||||
Attributes attr = design.attributes(); | |||||
DesignAttributeHandler.writeAttribute("maxlength", attr, getMaxLength(), | |||||
def.getMaxLength(), Integer.class); | |||||
} | |||||
} |
/* | |||||
* Copyright 2000-2014 Vaadin Ltd. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||||
* use this file except in compliance with the License. You may obtain a copy of | |||||
* the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||||
* License for the specific language governing permissions and limitations under | |||||
* the License. | |||||
*/ | |||||
package com.vaadin.ui.components.fields; | |||||
import org.jsoup.nodes.Attributes; | |||||
import org.jsoup.nodes.Element; | |||||
import com.vaadin.data.Property; | |||||
import com.vaadin.ui.TextArea; | |||||
import com.vaadin.ui.declarative.DesignAttributeHandler; | |||||
import com.vaadin.ui.declarative.DesignContext; | |||||
/** | |||||
* A component for editing textual data that fits on a single line. For a | |||||
* multi-line textarea, see the {@link TextArea} component. | |||||
* | |||||
* @author Vaadin Ltd. | |||||
*/ | |||||
@SuppressWarnings("serial") | |||||
public class TextField extends AbstractTextField { | |||||
/** | |||||
* Constructs an empty <code>TextField</code> with no caption. | |||||
*/ | |||||
public TextField() { | |||||
clear(); | |||||
} | |||||
/** | |||||
* Constructs an empty <code>TextField</code> with given caption. | |||||
* | |||||
* @param caption | |||||
* the caption <code>String</code> for the editor. | |||||
*/ | |||||
public TextField(String caption) { | |||||
this(); | |||||
setCaption(caption); | |||||
} | |||||
/** | |||||
* Constructs a new <code>TextField</code> with the given caption and | |||||
* initial text contents. The editor constructed this way will not be bound | |||||
* to a Property unless | |||||
* {@link com.vaadin.data.Property.Viewer#setPropertyDataSource(Property)} | |||||
* is called to bind it. | |||||
* | |||||
* @param caption | |||||
* the caption <code>String</code> for the editor. | |||||
* @param value | |||||
* the initial text content of the editor. | |||||
*/ | |||||
public TextField(String caption, String value) { | |||||
setValue(value); | |||||
setCaption(caption); | |||||
} | |||||
/** | |||||
* Clears the value of this TextField. | |||||
*/ | |||||
public void clear() { | |||||
setValue(""); | |||||
} | |||||
@Override | |||||
public void readDesign(Element design, DesignContext designContext) { | |||||
super.readDesign(design, designContext); | |||||
Attributes attr = design.attributes(); | |||||
if (attr.hasKey("value")) { | |||||
String text = DesignAttributeHandler.readAttribute("value", attr, | |||||
String.class); | |||||
getState(false).text = text; | |||||
} | |||||
} | |||||
@Override | |||||
public void writeDesign(Element design, DesignContext designContext) { | |||||
super.writeDesign(design, designContext); | |||||
AbstractTextField def = (AbstractTextField) designContext | |||||
.getDefaultInstance(this); | |||||
Attributes attr = design.attributes(); | |||||
DesignAttributeHandler.writeAttribute("value", attr, getValue(), | |||||
def.getValue(), String.class); | |||||
} | |||||
} |
/* | |||||
* Copyright 2000-2014 Vaadin Ltd. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||||
* use this file except in compliance with the License. You may obtain a copy of | |||||
* the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||||
* License for the specific language governing permissions and limitations under | |||||
* the License. | |||||
*/ | |||||
package com.vaadin.shared.ui.components.fields; | |||||
import com.vaadin.shared.communication.FieldRpc.FocusAndBlurServerRpc; | |||||
public interface TextFieldServerRpc extends FocusAndBlurServerRpc { | |||||
public void setText(String text); | |||||
} |
/* | |||||
* Copyright 2000-2014 Vaadin Ltd. | |||||
* | |||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not | |||||
* use this file except in compliance with the License. You may obtain a copy of | |||||
* the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||||
* License for the specific language governing permissions and limitations under | |||||
* the License. | |||||
*/ | |||||
package com.vaadin.shared.ui.components.fields; | |||||
import com.vaadin.shared.AbstractFieldState; | |||||
import com.vaadin.shared.annotations.NoLayout; | |||||
public class TextFieldState extends AbstractFieldState { | |||||
{ | |||||
primaryStyleName = "v-textfield"; | |||||
} | |||||
/** | |||||
* Maximum character count in text field. | |||||
*/ | |||||
@NoLayout | |||||
public int maxLength = -1; | |||||
/** | |||||
* Number of visible columns in the TextField. | |||||
*/ | |||||
public int columns = 0; | |||||
/** | |||||
* The prompt to display in an empty field. Null when disabled. | |||||
*/ | |||||
@NoLayout | |||||
public String placeholder = null; | |||||
/** | |||||
* The text in the field | |||||
*/ | |||||
@NoLayout | |||||
public String text = ""; | |||||
public int selectionStart = -1; | |||||
public int selectionLength = 0; | |||||
} |