/* * Ext GWT - Ext for GWT * Copyright(c) 2007-2009, Ext JS, LLC. * licensing@extjs.com * * http://extjs.com/license */ package com.extjs.gxt.ui.client.widget.form; import com.extjs.gxt.ui.client.GXT; import com.extjs.gxt.ui.client.core.El; import com.extjs.gxt.ui.client.core.XDOM; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.InputElement; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.AbstractImagePrototype; import com.extjs.gxt.ui.client.util.BaseEventPreview; import com.extjs.gxt.ui.client.util.Rectangle; import com.extjs.gxt.ui.client.widget.ComponentHelper; import com.extjs.gxt.ui.client.widget.button.Button; import com.extjs.gxt.ui.client.event.ComponentEvent; /** * A file upload filed. When using this field, the containing form panel's * encoding must be set to MULTIPART using @link * {@link FormPanel#setEncoding(Encoding)}. In addition, the method should be * set to POST using * {@link FormPanel#setMethod(com.extjs.gxt.ui.client.widget.form.FormPanel.Method)} * . */ public class FileUploadField extends TextField<String> { public class FileUploadFieldMessages extends TextFieldMessages { private String browseText = GXT.MESSAGES.uploadField_browseText(); /** * Returns the browse text. * * @return the browse text */ public String getBrowseText() { return browseText; } /** * Sets the browse text. * * @param browseText the browse text */ public void setBrowseText(String browseText) { this.browseText = browseText; } } private Button button; private AbstractImagePrototype buttonIcon; private int buttonOffset = 3; private El file; private BaseEventPreview focusPreview; private El input; private El wrap; /** * Creates a new file upload field. */ public FileUploadField() { focusPreview = new BaseEventPreview(); focusPreview.setAutoHide(false); messages = new FileUploadFieldMessages(); } /** * Returns the button icon class. */ public AbstractImagePrototype getButtonIconStyle() { return buttonIcon; } /** * Returns the button offset. */ public int getButtonOffset() { return buttonOffset; } /** * Returns the file input element. */ public InputElement getFileInput() { return (InputElement) file.dom.cast(); } @Override public FileUploadFieldMessages getMessages() { return (FileUploadFieldMessages) messages; } @Override public String getName() { if (rendered) { String n = file.dom.getAttribute("name"); if (!n.equals("")) { return n; } } return super.getName(); } @Override public void onComponentEvent(ComponentEvent ce) { super.onComponentEvent(ce); switch (ce.getEventTypeInt()) { case Event.ONCHANGE: onChange(ce); break; } } @Override public void reset() { super.reset(); getFileInput().setValue(null); } /** * Sets the button icon class. * * @param buttonIconStyle the button icon style */ public void setButtonIcon(AbstractImagePrototype buttonIconStyle) { this.buttonIcon = buttonIconStyle; } /** * Sets the number of pixels between the input element and the browser button * (defaults to 3). */ public void setButtonOffset(int buttonOffset) { this.buttonOffset = buttonOffset; } @Override public void setName(String name) { super.setName(name); if (rendered) { file.dom.removeAttribute("name"); getInputEl().dom.removeAttribute("name"); if (name != null) { file.setElementAttribute("name", name); } } } @Override public void setReadOnly(boolean readOnly) { this.readOnly = readOnly; if (button != null) { button.setEnabled(!readOnly); } if (file != null) { file.setEnabled(!readOnly); } } @Override protected void afterRender() { super.afterRender(); wrap.removeStyleName(fieldStyle); } @Override protected void doAttachChildren() { super.doAttachChildren(); ComponentHelper.doAttach(button); } @Override protected void doDetachChildren() { super.doDetachChildren(); ComponentHelper.doDetach(button); } @Override protected El getFocusEl() { return input; } @Override protected El getInputEl() { return input; } @Override protected El getStyleEl() { return input; } @Override protected void onBlur(ComponentEvent ce) { Rectangle rec = button.el().getBounds(); if (rec.contains(BaseEventPreview.getLastXY())) { ce.stopEvent(); return; } super.onBlur(ce); focusPreview.remove(); } protected void onChange(ComponentEvent ce) { setValue(getFileInput().getValue()); } @Override protected void onDetach() { super.onDetach(); if (focusPreview != null) { focusPreview.remove(); } } @Override protected void onFocus(ComponentEvent ce) { super.onFocus(ce); focusPreview.add(); } @Override protected void onRender(Element target, int index) { wrap = new El(DOM.createDiv()); wrap.addStyleName("x-form-field-wrap"); wrap.addStyleName("x-form-file-wrap"); input = new El(DOM.createInputText()); input.addStyleName(fieldStyle); input.addStyleName("x-form-file-text"); input.setId(XDOM.getUniqueId()); if (GXT.isIE && target.getTagName().equals("TD")) { input.setStyleAttribute("position", "static"); } file = new El((Element) Document.get().createFileInputElement().cast()); file.setElementAttribute("size", 1); file.addStyleName("x-form-file"); file.addEventsSunk(Event.ONCHANGE | Event.FOCUSEVENTS); file.setId(XDOM.getUniqueId()); wrap.appendChild(input.dom); wrap.appendChild(file.dom); setElement(wrap.dom, target, index); button = new Button(getMessages().getBrowseText()); button.addStyleName("x-form-file-btn"); button.setIcon(buttonIcon); button.render(wrap.dom); super.onRender(target, index); super.setReadOnly(true); setName(getName()); if (width == null) { setWidth(150); } } @Override protected void onResize(int width, int height) { super.onResize(width, height); input.setWidth(adjustWidth("input", width - button.el().getWidth() - buttonOffset), true); } }