/* * 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; import com.extjs.gxt.ui.client.core.El; import com.extjs.gxt.ui.client.data.Loader; import com.extjs.gxt.ui.client.event.ComponentEvent; import com.extjs.gxt.ui.client.event.ContainerEvent; import com.extjs.gxt.ui.client.event.HtmlContainerEvent; import com.google.gwt.http.client.Request; import com.google.gwt.http.client.RequestBuilder; import com.google.gwt.http.client.RequestCallback; import com.google.gwt.http.client.Response; import com.google.gwt.http.client.RequestBuilder.Method; 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.Widget; /** * A specialized container whose contents can be specified as an existing * element, an html fragment, or a remote url. When adding children a css * selector is used to identify the element the child will be inserted into. * * <p /> * Code snippet: * * <pre>{@code HtmlContainer hc = new HtmlContainer( "<div class=text style='padding:5px'>" + "<h1>Heading1</h1>" + "<i>Some text</i></br>" + "<div class=b1></div>" + "<u>Final text</u></div>"); hc.add(new Button("Test"), "div.b1"); hc.setBorders(true); hc.setSize(200, 100); hc.setPosition(10, 10); RootPanel.get().add(hc); * }</pre> * * <dl> * <dt>Inherited Events:</dt> * <dd>Container BeforeAdd</dd> * <dd>Container Add</dd> * <dd>Container BeforeRemove</dd> * <dd>Container Remove</dd> * <dd>BoxComponent Move</dd> * <dd>BoxComponent Resize</dd> * <dd>Component Enable</dd> * <dd>Component Disable</dd> * <dd>Component BeforeHide</dd> * <dd>Component Hide</dd> * <dd>Component BeforeShow</dd> * <dd>Component Show</dd> * <dd>Component Attach</dd> * <dd>Component Detach</dd> * <dd>Component BeforeRender</dd> * <dd>Component Render</dd> * <dd>Component BrowserEvent</dd> * <dd>Component BeforeStateRestore</dd> * <dd>Component StateRestore</dd> * <dd>Component BeforeStateSave</dd> * <dd>Component SaveState</dd> * </dl> */ public class HtmlContainer extends Container<Component> { /** * The method used when requesting remote content (defaults to * RequestBuilder.GET). Only applies when specifying a {@link #setUrl(String)} * . */ public Method httpMethod = RequestBuilder.GET; /** * True to defer remote requests until the component is rendered (defauls to * false). */ public boolean deferDownload; /** * The request data to be used in remote calls (defaults to null). */ public String requestData; private Element elem; private String html; private String tagName = "div"; private String url; private RequestBuilder requestBuilder; private RequestCallback callback; /** * Creates a new container. */ public HtmlContainer() { } /** * Creates a new container. * * @param elem the component's element */ public HtmlContainer(Element elem) { this.elem = elem; this.elem.getStyle().setProperty("display", "block"); } /** * Creates a new container. * * @param requestBuilder the request to be used when setting a url */ public HtmlContainer(RequestBuilder requestBuilder) { this.requestBuilder = requestBuilder; } /** * Creates a container. * * @param html the containers inner html */ public HtmlContainer(String html) { this.html = html; } /** * Adds a component to this Container. Fires the <i>BeforeAdd</i> event before * adding, then fires the <i>Add</i> event after the component has been added. * * @param widget the widget to add. If the widget is not a Component it will * be wrapped in a WidgetComponent * @param selector the css selector (ie div.class) used to identify the components parent */ public void add(Widget widget, String selector) { Component component = wrapWidget(widget); if (super.add(component)) { component.setData("selector", selector); if (rendered) { renderItem(component, selector); } } } /** * @return the tagName */ public String getTagName() { return tagName; } /** * Sets the container's inner html. * * @param html the html */ public void setHtml(String html) { this.html = html; if (rendered) { el().removeChildren(); getElement().setInnerHTML(html); renderAll(); } } /** * The HTML tag name that will wrap the text (defaults to 'div'). For inline * behavior set the tag name to 'span'. * * @param tagName the new tag name */ public void setTagName(String tagName) { this.tagName = tagName; } /** * Retrieves and sets the container's content from the given url. * * @param url the url */ public void setUrl(String url) { this.url = url; if (!deferDownload) { requestData(); } } protected void handleError(Request request, Throwable exception) { HtmlContainerEvent hce = new HtmlContainerEvent(this); hce.setException(exception); fireEvent(Loader.LoadException, hce); } protected void handleResponseReceived(Request request, Response response) { HtmlContainerEvent hce = new HtmlContainerEvent(this); hce.setResponse(response); hce.setHtml(response.getText()); fireEvent(Loader.Load, hce); setHtml(hce.getHtml()); } @Override protected void onRender(Element target, int index) { if (elem != null) { setElement(elem); renderAll(); } else { setElement(DOM.createElement(tagName), target, index); if (html != null) { setHtml(html); } else if (url != null && deferDownload) { requestData(); } } } protected void renderAll() { for (Component c : getItems()) { renderItem(c, (String) c.getData("selector")); } } protected void renderItem(Component item, String selector) { El elem = el().selectNode(selector); if (elem != null) { elem.removeChildren(); if (!item.isRendered()) { item.render(elem.dom); } else { getElement().appendChild(item.getElement()); } if (isAttached() && !item.isAttached()) { ComponentHelper.doAttach(item); } } } protected void requestData() { if (requestBuilder == null) { requestBuilder = new RequestBuilder(httpMethod, url); } if (callback == null) { callback = new RequestCallback() { public void onError(Request request, Throwable exception) { handleError(request, exception); } public void onResponseReceived(Request request, Response response) { handleResponseReceived(request, response); } }; } try { requestBuilder.sendRequest(requestData, callback); } catch (Exception e) { } } @Override protected ComponentEvent createComponentEvent(Event event) { return new HtmlContainerEvent(this); } @Override @SuppressWarnings("unchecked") protected ContainerEvent createContainerEvent(Component item) { return new HtmlContainerEvent(this, item); } }