📄 modalwindow.java
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 org.apache.wicket.extensions.ajax.markup.html.modal;import org.apache.wicket.Component;import org.apache.wicket.IClusterable;import org.apache.wicket.IPageMap;import org.apache.wicket.Page;import org.apache.wicket.RequestCycle;import org.apache.wicket.ResourceReference;import org.apache.wicket.Session;import org.apache.wicket.WicketRuntimeException;import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;import org.apache.wicket.ajax.AjaxRequestTarget;import org.apache.wicket.ajax.IAjaxCallDecorator;import org.apache.wicket.ajax.calldecorator.CancelEventIfNoAjaxDecorator;import org.apache.wicket.behavior.HeaderContributor;import org.apache.wicket.markup.ComponentTag;import org.apache.wicket.markup.html.WebMarkupContainer;import org.apache.wicket.markup.html.panel.Panel;import org.apache.wicket.markup.html.resources.CompressedResourceReference;import org.apache.wicket.markup.html.resources.JavascriptResourceReference;import org.apache.wicket.model.IModel;import org.apache.wicket.model.Model;import org.apache.wicket.protocol.http.WebRequest;import org.apache.wicket.request.RequestParameters;import org.apache.wicket.settings.IPageSettings;import org.apache.wicket.util.lang.EnumeratedType;import org.apache.wicket.util.string.AppendingStringBuffer;import org.apache.wicket.util.string.Strings;/** * Modal window component. * <p> * Modal window is a draggable window (with either div or iframe content) that prevent user from * interacting the rest of page (using a mask) until the window is closed. * <p> * If you want this to work under IE, don't attach this component to a <span> tag, make sure * you use a <div>. * <p> * The window is draggable and optionally resizable. The content can be either * <ul> * <li><b>a component</b> - you need to add the component to modal window (with id obtained using * <code>{@link #getContentId()}</code>, or * <li><b>a page</b> - you need to pass a <code>{@link PageCreator}</code> instance to a * <code>{@link #setPageCreator(ModalWindow.PageCreator)}</code> method. * </ul> * In case the content is a component, it is not rendered until the window is shown (method * <code>{@link #show(AjaxRequestTarget)})</code>. In case the content is another page, you can * set the desired pagemap name using <code>{@link #setPageMapName(String)}</code>. Setting * pagemap is only needed when wicket multiwindow support is on. * <p> * The window can be made visible from an ajax handler using * <code>{@link #show(AjaxRequestTarget)}</code>. * <p> * To close the window there are multiple options. Static method * <code>{@link #close(AjaxRequestTarget)}</code> can be used to close the window from a handler * of ajax link inside the window. By default the close button in the upper right corner of the * window closes it. This behavior can be altered using * <code>{@link #setCloseButtonCallback(ModalWindow.CloseButtonCallback)}</code>. If you want to * be notified when the window is closed (either using the close button or calling * <code>{@link #close(AjaxRequestTarget)})</code>, you can use * <code>{@link #setWindowClosedCallback(ModalWindow.WindowClosedCallback)}</code>. * <p> * Title is specified using {@link #setTitle(String)}. If the content is a page (iframe), the title * can remain unset, in that case title from the page inside window will be shown. * <p> * There are several options to specify the visual properties of the window. In all methods where * size is expected, width refers to width of entire window (including frame), height refers to the * height of window content (without frame). * <p> * <ul> * <li><code>{@link #setResizable(boolean)}</code> specifies, whether the window can be resized. * <li><code>{@link #setInitialWidth(int)}</code> and <code>{@link #setInitialHeight(int)}</code> * specify the initial width and height of window. If the window is resizable, the unit of these * dimensions is always "px". If the window is not resizable, the unit can be specified using * <code>{@link #setWidthUnit(String)}</code> and <code>{@link #setHeightUnit(String)}</code>. * If the window is not resizable and the content is a component (not a page), the initial height * value can be ignored and the actual height can be determined from the height of the content. To * enable this behavior use <code>{@link #setUseInitialHeight(boolean)}</code>. * <li>The window position (and size if the window is resizable) can be stored in a cookie, so that * it is preserved when window is close. The name of the cookie is specified via * <code>{@link #setCookieName(String)}</code>. If the name is <code>null</code>, position is * not stored (initial width and height are always used). Default cookie name is null (position is * not stored). * <li><code>{@link #setMinimalWidth(int)}</code> and <code>{@link #setMinimalHeight(int)}</code> * set the minimal dimensions of resizable window. * <li>Modal window can chose between two colors of frame. * <code>{@link #setCssClassName(String)}</code> sets the dialog css class, possible values are * <code>{@link #CSS_CLASS_BLUE}</code> for blue frame and <code>{@link #CSS_CLASS_GRAY}</code> * for gray frame. * <li>Mask (element that prevents user from interacting the rest of the page) can be either * transparent or semitransparent. <code>{@link #setMaskType(ModalWindow.MaskType)}</code> alters * this. * </ul> * * @see IPageSettings#setAutomaticMultiWindowSupport(boolean) * @author Matej Knopp */public class ModalWindow extends Panel{ private static final long serialVersionUID = 1L; private static ResourceReference JAVASCRIPT = new JavascriptResourceReference( ModalWindow.class, "res/modal.js"); private static ResourceReference CSS = new CompressedResourceReference(ModalWindow.class, "res/modal.css"); /** * Creates a new modal window component. * * @param id * Id of component */ public ModalWindow(String id) { super(id); setVersioned(false); cookieName = null; add(empty = new WebMarkupContainer(getContentId())); add(new CloseButtonBehavior()); add(new WindowClosedBehavior()); add(HeaderContributor.forJavaScript(JAVASCRIPT)); add(HeaderContributor.forCss(CSS)); } /** * Interface for lazy page creation. The advantage of creating page using this interface over * just passing a page instance is that page created in <code>{@link #createPage()}</code> * will have the pagemap automatically set to the pagemap specified for * <code>{@link ModalWindow}</code>. * * @author Matej Knopp */ public static interface PageCreator extends IClusterable { /** * Creates a new instance of content page. * * @return new page instance */ public Page createPage(); } /** * Callback for close button that contains a method that is invoked after the button has been * clicked. If no callback instance is specified using * <code>{@link #setCloseButtonCallback(ModalWindow.CloseButtonCallback)}</code>, no ajax * request will be fired. Clicking the button will just close the window. * * @author Matej Knopp */ public static interface CloseButtonCallback extends IClusterable { /** * Methods invoked after the button has been clicked. The invocation is done using an ajax * call, so <code>{@link AjaxRequestTarget}</code> instance is available. * * @param target * <code>{@link AjaxRequestTarget}</code> instance bound with the ajax request. * * @return True if the window can be closed (will close the window), false otherwise */ public boolean onCloseButtonClicked(AjaxRequestTarget target); } /** * Callback called after the window has been closed. If no callback instance is specified using * {@link ModalWindow#setWindowClosedCallback(ModalWindow.WindowClosedCallback)}, no ajax * request will be fired. * * @author Matej Knopp */ public static interface WindowClosedCallback extends IClusterable { /** * Called after the window has been closed. * * @param target * <code>{@link AjaxRequestTarget}</code> instance bound with the ajax request. */ public void onClose(AjaxRequestTarget target); } /** * Is this window currently showing. * * @return the shown */ public boolean isShown() { return shown; } /** * Sets the name of the page ma for the content page. This makes only sense when the content is * a page, not a component and if wicket multiwindow support is turned on. * * @param pageMapName * Name of the page map */ public void setPageMapName(String pageMapName) { this.pageMapName = pageMapName; } /** * Returns the page map name. * * @return The page map name. */ public String getPageMapName() { return pageMapName; } /** * Sets the <code>{@link PageCreator}</code> instance. The instance is only used when no * custom component has been added to the dialog. * * @param creator * <code>{@link PageCreator}</code> instance */ public void setPageCreator(PageCreator creator) { pageCreator = creator; } /** * Sets the <code>{@link CloseButtonCallback}</code> instance. * * @param callback * Callback instance */ public void setCloseButtonCallback(CloseButtonCallback callback) { closeButtonCallback = callback; } /** * Sets the <code>@{link {@link WindowClosedCallback}</code> instance. * * @param callback * Callback instance */ public void setWindowClosedCallback(WindowClosedCallback callback) { windowClosedCallback = callback; } /** * Shows the modal window. * * @param target * Request target associated with current ajax request. */ public void show(AjaxRequestTarget target) { if (shown == false) { target.addComponent(this); target.appendJavascript(getWindowOpenJavascript()); shown = true; } } /** * Hides the modal window. This can be called from within the modal window, however, the modal * window must have configured WindowClosedCallback. Otherwise use the * {@link #close(AjaxRequestTarget)} method. * * @param target * Request target associated with current ajax request. */ public static final void closeCurrent(AjaxRequestTarget target) { target.appendJavascript(getCloseJavacript()); } /** * Closes the modal window. * * @param target * Request target associated with current ajax request. */ public void close(AjaxRequestTarget target) { target.appendJavascript(getCloseJavacript()); shown = false; } /** * @return javascript that closes current modal window */ private static String getCloseJavacript() { return "var win;\n" // + "try {\n" + " win = window.parent.Wicket.Window;\n" + "} catch (ignore) {\n" + "}\n" + "if (typeof(win) == \"undefined\" || typeof(win.current) == \"undefined\") {\n" + " try {\n" + " win = window.Wicket.Window;\n" + " } catch (ignore) {\n" + " }\n" + "}\n" + "if (typeof(win) != \"undefined\" && typeof(win.current) != \"undefined\") {\n" + " window.parent.setTimeout(function() {\n" + " win.current.close();\n" + " }, 0);\n" + "}"; } /** * Returns the id of content component. * * <pre> * ModalWindow window = new ModalWindow(parent, "window"); * new MyPanel(window, window.getContentId()); * </pre> * * @return Id of content component. */ public String getContentId() { return "content"; } /** * Sets the minimal width of window. This value is only used if the window is resizable. The * width is specified in pixels and it is the width of entire window (including frame). * * @param minimalWidth * Minimal window width. */ public void setMinimalWidth(int minimalWidth) { this.minimalWidth = minimalWidth; } /** * Returns the minimal width of window (in pixels). * * @return Minimal width of window */ public int getMinimalWidth() { return minimalWidth; } /** * Sets the minimal height of window. This value is only used if window is resizable. The height * is specified in pixels and it is the height of window content (without frame). * * @param minimalHeight * Minimal height */ public void setMinimalHeight(int minimalHeight) { this.minimalHeight = minimalHeight; } /** * Returns the minimal height of window (in pixels). * * @return Minimal height of window */ public int getMinimalHeight() { return minimalHeight; } /** * CSS class for window with blue border. */ public final static String CSS_CLASS_BLUE = "w_blue"; /** * CSS class for window with gray border. */ public final static String CSS_CLASS_GRAY = "w_silver"; /** * Sets the CSS class name for this window. This class affects the look of window frame. * Possible values (if you don't make your style sheet) are <code>{@link #CSS_CLASS_BLUE}</code> * and <code>{@link #CSS_CLASS_GRAY}</code>. * * @param cssClassName */ public void setCssClassName(String cssClassName) { this.cssClassName = cssClassName; } /** * Returns the CSS class name for this window. * * @return CSS class name */ public String getCssClassName() { return cssClassName; } /** * Sets the initial width of the window. The width refers to the width of entire window * (including frame). If the window is resizable, the width unit is always "px". If the window * is not resizable, the unit can be specified using {@link #setWidthUnit(String)}. If cookie * name is set and window is resizable, the initial width may be ignored in favor of width * stored in cookie. * * @param initialWidth * Initial width of the window */ public void setInitialWidth(int initialWidth) { this.initialWidth = initialWidth; } /** * Returns the initial width of the window. * * @return Initial height of the window */ public int getInitialWidth() { return initialWidth; } /** * Sets the initial height of the window. The height refers to the height of window content * (without frame). If the window is resizable, the height unit is always "px". If the window is * not resizable, the unit can be specified using {@link #setHeightUnit(String)}. If cookie * name is set and window is resizable, the initial height may be ignored in favor of height * stored in cookie. * * @param initialHeight * Initial height of the window */ public void setInitialHeight(int initialHeight) { this.initialHeight = initialHeight; } /** * Returns the initial height of the window. * * @return Initial height of the window */ public int getInitialHeight() { return initialHeight; } /** * Sets whether to use initial height or preserve the real content height. This can only be used * if the content is a component (not a page) and the window is not resizable. * * @param useInitialHeight * Whether to use initial height instead of preserving content height instead of * using initial height */ public void setUseInitialHeight(boolean useInitialHeight) { this.useInitialHeight = useInitialHeight; } /** * Returns true if the initial height should be used (in favor of preserving real content * height). * * @return True if initial height should be used, false is real content height should be * preserved (valid only if the window is not resizable and the content is a component * (not a page) */ public boolean isUseInitialHeight() { return useInitialHeight; } /** * Sets whether the user will be able to resize the window. * * @param resizable * Whether the window is resizable */ public void setResizable(boolean resizable) { this.resizable = resizable; } /** * Returns whether the window is resizable. * * @return True if the window is resizable, false otherwise */ public boolean isResizable() { return resizable; } /** * Sets the CSS unit used for initial window width. This is only applicable when the window is
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -