`

【zk开发】ZkUtils 1.2

    博客分类:
  • ZK
阅读更多

 

ZkUtils 是zk开发中的一些工具方法集合,将散落在zk 工具类中的常用方法集中到此类中,并添加详尽注释,方便理解与使用

 

更新内容         源码见附件

 

本版是ZkUtils1.1的重写,添加更详尽的注释,及示例代码

 

 

 

package com.linktel.linkFax.web.zk.util;

import java.io.IOException;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Desktop;
import org.zkoss.zk.ui.Execution;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.Page;
import org.zkoss.zk.ui.Session;
import org.zkoss.zk.ui.Sessions;
import org.zkoss.zk.ui.WebApp;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.ForwardEvent;
import org.zkoss.zk.ui.event.GenericEventListener;
import org.zkoss.zk.ui.sys.ExecutionCtrl;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.impl.api.InputElement;

/**
 * ZkUtils集合了zk中常用的一些功能,方便开发中的使用
 * 
 * 
 * @author sunflower
 * 
 * 
 *         Email:zhangxuehuaemail # gmail 点 com
 *@since zk5.0+
 */
public class ZkUtils {
	/**
	 * 
	 * 获得当前Execution
	 * <p>
	 * 客户端请求的执行器(例如ServletRequest),当客户端发送一个请求后,
	 * 服务端负责构造这个Execution对象,获取当前执行的信息,然后服务这个请求
	 * <p>
	 * 一个客户端请求, 例如, HttpServletRequest, 或许关联多个请求 request (
	 * {@link org.zkoss.zk.au.AuRequest}). 但是, 这些 ZK 请求来自的页面 ({@link Page}
	 * )必须具有相同的desktop
	 * 
	 * <p>
	 * 因为一个请求也许来自http或其他协议,Execution通常一个隔离层
	 * 
	 * 
	 * @return 当前execution
	 * @see Execution
	 */
	public static final Execution getCurrentExecution() {
		return Executions.getCurrent();
	}

	/**
	 * 返回当前Exection桌面对象
	 * 
	 * @return
	 * @see Execution#getDesktop()
	 */
	public static final Desktop getCurrentDesktop() {
		return getCurrentExecution().getDesktop();
	}

	/**
	 * 获得当前Execution所属的会话
	 * <p>
	 * <b>注</b>该Session不同于HttpSession,该session为zk定义的session作用域
	 * 
	 * @return
	 * @see Session
	 */
	public static final Session getCurrentSession() {
		return Sessions.getCurrent();
	}

	/**
	 * 返回本地session对象,如果不可用返回null,返回的对象依赖客户端类型,如果是就http的
	 * ,那么返回javax.servlet.http.HttpSession的一个实例
	 * ,如果是portlet,那么返回javax.portlet.PortletSession的实例
	 */
	public static final Object getNativeSession() {
		return getCurrentSession().getNativeSession();
	}

	/**
	 * 返回本地请求对象,如果不可用返回null
	 * 
	 * @return 返回的对象依赖web容器,如果web容器时一个servlet容器,那么返回的对象为ServletRequest
	 */
	public static final Object getNativeRequest() {
		return getCurrentExecution().getNativeRequest();
	}

	/**
	 * 返回本地响应对象,如果不可用返回null
	 * 
	 * @return 返回的对象依赖web容器,如果web容器时一个servlet容器,那么返回的对象为ServletResponse
	 */
	public static final Object getNativeResponse() {
		return getCurrentExecution().getNativeResponse();
	}

	/**
	 * 获得WebApp对象
	 * 
	 * @return
	 * @see Desktop#getWebApp()
	 * @see WebApp
	 */
	public static final WebApp getWebApp() {
		return getCurrentDesktop().getWebApp();
	}

	public static final String getRealPath(String path) {
		return getWebApp().getRealPath(path);
	}

	/**
	 * 获得当前请求来自的页面
	 * 
	 * @return
	 */
	public static final Page getCurrentPage() {
		return ((ExecutionCtrl) getCurrentExecution()).getCurrentPage();
	}

	/**
	 * 返回execution作用域内参数
	 * 
	 * @return
	 * @see Execution#getArg()
	 */
	public static final Map getExecutionArgs() {
		return getCurrentExecution().getArg();
	}

	/**
	 * 获得当前Execution作用域内的属性
	 * 
	 * @see Execution#getAttributes()
	 */
	public static final Map getExectionAttributes() {
		return getCurrentExecution().getAttributes();
	}

	/**
	 * 设置请求属性值
	 * 
	 * @param name
	 *            请求属性
	 * @param value
	 *            属性值
	 */
	public static final void setExecutionAttribute(String name, Object value) {
		getCurrentExecution().setAttribute(name, value);
	}

	/**
	 * 设置Execution作用域属性值或其父作用域的值
	 * 
	 * @param name
	 *            请求属性
	 * @param value
	 *            属性值
	 * @param recurse
	 *            检查父作用域是否存在该属性,如果存在将替换父作用域的值
	 * 
	 */
	public static final void setExecutionAttribute(String name, Object value,
			boolean recurse) {
		getCurrentExecution().setAttribute(name, value, recurse);
	}

	/**
	 * 获得请求参数
	 * 
	 * @return 参数map
	 */
	public static final Map getExecutionParameterMap() {
		return getCurrentExecution().getParameterMap();
	}

	/**
	 * 获得请求参数值
	 * 
	 * @param name
	 *            请求参数的名字
	 * @return 指定名字的参数值
	 */
	public static final String getExecutionParameter(String name) {
		return getCurrentExecution().getParameter(name);
	}

	/**
	 * 获得请求参数值
	 * 
	 * @param name
	 *            参数的名字
	 * @return 字符数组
	 */
	public static final String[] getExecutionParameterValues(String name) {
		return getCurrentExecution().getParameterValues(name);
	}

	/**
	 * 获得当前请求消息头
	 * 
	 * @param name
	 *            消息头名字
	 * @return 消息头值
	 */
	public static final String getRequestHeader(String name) {
		return getCurrentExecution().getHeader(name);
	}

	/**
	 * 返回指定请求头名字的所有值
	 * 
	 * @param name
	 *            请求头的名字
	 * @return
	 */
	public static final Iterator getRequestHeaders(String name) {
		return getCurrentExecution().getHeaders(name);
	}

	/**
	 *返回所有请求头名字
	 * 
	 * @return
	 */
	public static final Iterator getRequestHeaderNames() {
		return getCurrentExecution().getHeaderNames();
	}

	/**
	 * 添加一个指定名称和值的相应头,允许相应头具有多值
	 * 
	 * @param name
	 * @param value
	 */
	public static final void addResponseHeader(String name, String value) {
		getCurrentExecution().addResponseHeader(name, value);
	}

	/**
	 * 添加一个指定名称和日期值的响应头
	 * 
	 * @param name
	 * @param value
	 */
	public static final void addResponseHeader(String name, Date value) {
		getCurrentExecution().addResponseHeader(name, value);
	}

	/**
	 * 返回接收请求的本地ip地址
	 * 
	 * @return
	 */
	public static final String getLocalAddr() {
		return getCurrentExecution().getLocalAddr();
	}

	/**
	 * 获得接收请求的本地host name
	 * 
	 * @return
	 */
	public static final String getLocalName() {
		return getCurrentExecution().getLocalName();
	}

	/**
	 * 获得接收请求的本地端口
	 * 
	 * @return
	 */
	public static final int getLocalPort() {
		return getCurrentExecution().getLocalPort();
	}

	/**
	 * 获得发送请求的客户端ip
	 * 
	 * @return
	 */
	public static final String getRemoteAddr() {
		return getCurrentExecution().getRemoteAddr();
	}

	/**
	 * 获得发送请求的客户端的host name
	 * 
	 * @return
	 */
	public static final String getRemoteHost() {
		return getCurrentExecution().getRemoteHost();
	}

	/**
	 * 设置session 属性
	 * 
	 * @param name
	 *            属性名
	 * @param value
	 *            属性值
	 */
	public static final void setSessionAttribute(String name, Object value) {
		getCurrentSession().setAttribute(name, value);
	}

	/**
	 * 设置session或父作用域 属性
	 * 
	 * @param name
	 *            属性名
	 * @param value
	 *            属性值
	 * @param recurse
	 *            是否查询父作用域包含name名字的属性,如果包含将替换该值
	 */
	public static final void setSessionAttribute(String name, Object value,
			boolean recurse) {
		getCurrentSession().setAttribute(name, value, recurse);
	}

	/**
	 * 返回session作用域对象
	 * 
	 * @param name
	 *            属性名
	 * @param recurse
	 *            是否检索父作用域,如果为true, 并且当前作用域没声明这个属性,那么将搜索父作用域
	 * @return
	 */
	public static final Object getSessionAttribute(String name, boolean recurse) {
		return getCurrentSession().getAttribute(name, recurse);
	}

	/**
	 * 返回session作用域对象
	 * 
	 * @param name
	 *            属性名
	 * @return
	 */
	public static final Object getSessionAttribute(String name) {
		return getCurrentSession().getAttribute(name);
	}

	/**
	 * 获得所有session作用域对象
	 * 
	 * @return map 类型的作用域所有对象
	 */
	public static final Map getSessionAttributes() {
		return getCurrentSession().getAttributes();
	}

	/**
	 * 获得会话超时事件,单位秒
	 * 
	 * @return
	 */
	public static final int getSessionMaxInactiveInterval() {
		return getCurrentSession().getMaxInactiveInterval();
	}

	/**
	 * 指定失效事件,单位秒,负值表示永不过期
	 * 
	 * @param interval
	 */
	public static final void setSessionMaxInactiveInterval(int interval) {
		getCurrentSession().setMaxInactiveInterval(interval);
	}

	/**
	 * 销毁当前session
	 */
	public static final void invalidateSession() {
		getCurrentSession().invalidate();
	}

	/**
	 * 设置页面作用域属性
	 * 
	 * @param name
	 *            属性名
	 * @param value
	 *            属性值
	 */
	public static final void setPageAttribute(String name, Object value) {
		getCurrentPage().setAttribute(name, value);
	}

	/**
	 * 
	 * 设置page或父作用域属性
	 * 
	 * @param name
	 * @param value
	 * @param recurse
	 *            是否检索父作用域,如果为true, 并且当前作用域没声明这个属性,那么将搜索父作用域 ,并替换
	 */
	public static final void setPageAttribute(String name, Object value,
			boolean recurse) {
		getCurrentPage().setAttribute(name, value, recurse);
	}

	/**
	 * 获得当前请求来自的页面
	 * 
	 * @return
	 */
	public static final String getRequestPagePath() {
		return getCurrentPage().getRequestPath();
	}

	/**
	 * 获得桌面作用域属性
	 * 
	 * @param name
	 * @return
	 */
	public static final Object getDesktopAttribute(String name) {
		return getCurrentDesktop().getAttribute(name);
	}

	/**
	 * 获得指定id的桌面
	 * <p>
	 * 需要注意到是:例如在page1中包含iframe,iframe包含的页面为page2,那么zk将为page2新建一个桌面对象desktop2,
	 * 因此page1与page2属于不同的桌面, 当你在page2的一个按钮或所属的其他组件触发的事件中
	 * 使用该方法获得page1的子页面的时候,当前动作请求所属桌面为desktop2,而不是page1所属的desktop1,
	 * 因此你无法从desktop2中查找属于desktop1的页面
	 * 
	 * @param pageId
	 *            页面的id
	 * @return 页面对戏那个
	 * @see Desktop#getPage(String)
	 */
	public static final Page getPage(String pageId) {
		return getCurrentDesktop().getPage(pageId);
	}

	public static final void forward(String page) throws IOException {
		Executions.forward(page);
	}

	public static final void sendRedirect(String page) {
		Executions.sendRedirect(page);
	}

	/**
	 *向当前execution提交一个事件
	 * <p>
	 * 将事件提交到事件队列末尾,然后立即返回。 队列中排在前面的事件处理完毕后执行该动作提交的事件。
	 * 
	 * @param event
	 */
	public static final void postEvent(Event event) {
		Events.postEvent(event);
	}

	/**
	 *向当前execution提交一个事件,可以设置事件的优先级
	 * <p>
	 * 将事件提交到事件队列末尾,然后立即返回。 队列中排在前面的事件处理完毕后执行该动作提交的事件。
	 * 
	 * @priority
	 * @param event
	 */
	public static final void postEvent(int priority, Event event) {
		Events.postEvent(priority, event);

	}

	/**
	 *向目标组件发送指定名称的事件
	 * <p>
	 * 将事件提交到事件队列末尾,然后立即返回。 队列中排在前面的事件处理完毕后执行该动作提交的事件。
	 */
	public static final void postEvent(String name, Component target,
			Object data) {
		Events.postEvent(name, target, data);
	}

	/**
	 * 向当前execution发送一个事件
	 * <p>
	 * 事件处理线程和调用该方法的线程为同一线程,即二者为相同线程,所以必须等待事件处理完毕,该方法才会返回。
	 * <p>
	 * 如果目标事件的的处理器,是一个长操作,那么当前线程将长事件阻塞,而在客户端表现为:左上角一直出现"正在处理,请稍候..."等字样的提示,
	 * 所以在使用前注意
	 * 
	 * @param event
	 */
	public static final void sendEvent(Event event) {
		Events.sendEvent(event);
	}

	/**
	 * 向指定组件发送事件
	 * <p>
	 * 事件处理线程和调用该方法的线程为同一线程,即二者为相同线程,所以必须等待事件处理完毕,该方法才会返回
	 * <p>
	 * 如果目标事件的的处理器,是一个长操作,那么当前线程将长事件阻塞,而在客户端表现为:左上角一直出现"正在处理,请稍候..."等字样的提示,
	 * 所以在使用前注意
	 * 
	 * @param comp
	 *            目标组件
	 * @param event
	 */
	public static final void sendEvent(Component comp, Event event) {
		Events.sendEvent(comp, event);
	}

	/**
	 * 向目标组件发送指定名称的事件
	 * 
	 * <p>
	 * 事件处理线程和调用该方法的线程为同一线程,即二者为相同线程,所以必须等待事件处理完毕,该方法才会返回
	 * <p>
	 * 如果目标事件的的处理器,是一个长操作,那么当前线程将长事件阻塞,而在客户端表现为:左上角一直出现"正在处理,请稍候..."等字样的提示,
	 * 所以在使用前注意
	 * 
	 * @param name
	 *            事件名称
	 * @param target
	 *            目标组件
	 * @param data
	 *            事件携带的数据,可以调用在事件监听器中使用<code>Event.getData()</code>获得该数据
	 */
	public static final void sendEvent(String name, Component target,
			Object data) {
		Events.sendEvent(name, target, data);
	}

	public static final Event getRealOrigin(ForwardEvent event) {
		return Events.getRealOrigin(event);
	}

	/**
	 * <p>
	 * 给指定的组件添加controller对象中定义的onXxx事件处理器,该controller是一个
	 * 包含onXxx方法的POJO对象,该工具方法将onXxx方法注册给指定组件,因此你不用通过{@link EventListener}
	 * 一个一个的向组件注册了
	 * </p>
	 * 
	 * <p>
	 * 所有在controller对象中以"on"开头的公共方法被作为事件处理器,并且相关事件同时也被监听,例如,
	 * 如果controller对象有一个名字为onOk的方法,那么 onOk事件将被监听,然后当接收到onOk事件的时候, onOk方法被调用
	 * 
	 * @param comp
	 *            the component to be registered the events
	 * @param controller
	 *            a POJO file with onXxx methods(event handlers)
	 * @since 3.0.6
	 * @see GenericEventListener
	 */
	public static final void addEventListeners(Component comp, Object controller) {
		Events.addEventListeners(comp, controller);
	}

	/**
	 * 检测名称时候一个合法的zk事件名
	 * 
	 * @param name
	 * @return
	 */
	public static final boolean isValidEventName(String name) {
		return Events.isValid(name);
	}

	/**
	 * 判断一个指定事件的组件是否有事件处理器或监听器
	 * 
	 * @param comp
	 * @param evtnm
	 * @param asap
	 *            是否仅检测非延迟事件监听器,例如实现org.zkoss.zk.ui.event.Deferrable或
	 *            org.zkoss.zk.ui.event.Deferrable.isDeferrable 返回 false的监听器
	 * @return
	 */
	public static final boolean isListened(Component comp, String evtnm,
			boolean asap) {
		return Events.isListened(comp, evtnm, asap);
	}

	/**
	 * 从uri指定的文件创建组件
	 * 
	 * @param uri
	 * @param parent
	 *            创建的组件所属的父组件F
	 * @param args
	 *            创建组件传递的参数
	 * @return 创建的组件,该组件对象为uri页面的第一个组件(zk节点除外)
	 */
	public static final Component createComponents(String uri,
			Component parent, Map args) {
		return Executions.createComponents(uri, parent, args);
	}

	/**
	 * 从zul格式字符串创建组件
	 * 
	 * @param content
	 *            zul格式内容的字符串
	 * @param parent
	 *            父组件,如果为null,那么组件所属的页面为当前页面,当前页面由execution上下文决定。另外新的组件将作为当前页面的根组件
	 * @param args
	 *            一个map类型的参数, 传递的参数可以使用Executions.getArgs()获得
	 * @return 根据content创建的组件第一个组件
	 */
	public static final Component createComponentsDirectly(String content,
			Component parent, Map args) {
		return Executions
				.createComponentsDirectly(content, "zul", parent, args);
	}

	/**
	 * 重绘组件
	 * <p>
	 * 仅允许在<b>请求处理阶段</b>和<b>事件处理阶段</b>调用, 不允许在<b>呈现阶段</b>调用
	 * 
	 * @param comp
	 */
	public static final void redraw(Component comp) {
		comp.invalidate();
	}

	/**
	 * 重绘页面
	 * <p>
	 * 仅允许在<b>请求处理阶段</b>和<b>事件处理阶段</b>调用, 不允许在<b>呈现阶段</b>调用
	 * 
	 * @param page
	 */
	public static final void redrawPage(Page page) {
		page.invalidate();
	}

	/**
	 * 弹出消息提示框
	 * 
	 * @param message
	 *            提示消息
	 * @param title
	 *            提示框标题
	 */
	public static final void showInformation(String message, String title) {
		try {
			Messagebox.show(message, title, Messagebox.OK,
					Messagebox.INFORMATION);
		} catch (InterruptedException e) {
			// ignore
		}
	}

	/**
	 * 弹出警告提示框
	 * 
	 * @param message
	 *            提示消息
	 * @param title
	 *            提示框标题
	 */
	public static final void showExclamation(String message, String title) {
		try {
			Messagebox.show(message, title, Messagebox.OK,
					Messagebox.EXCLAMATION);
		} catch (InterruptedException e) {
			// ignore
		}
	}

	/**
	 * 弹出消息提示框
	 * 
	 * @param message
	 *            提示消息
	 * @param title
	 *            提示框标题
	 */
	public static final void showError(String message, String title) {
		try {
			Messagebox.show(message, title, Messagebox.OK, Messagebox.ERROR);
		} catch (InterruptedException e) {
			// ignore
		}
	}

	/**
	 * 询问提示框
	 * <p>
	 * 如果禁用事件处理线程,该方法会立即返回,返回值永远为true。 如果作为if判断语句的条件,
	 * 那么else部分永远不会执行,启用和开启事件处理请查看zk.xml配置: <br />
	 * &lt;system-config&gt;<br />
	 * &lt;disable-event-thread&gt;false&lt;/disable-event-thread&gt;<br />
	 * &lt;/system-config&gt;
	 * 
	 * @param message
	 *            提示消息 提示框标题
	 * @return 禁用事件处理线程该方法永远返回true,启用事件处理相称时,如果用户点击ok按钮,返回true,反之false
	 */
	public static final boolean showQuestion(String message, String title) {
		try {
			return Messagebox.OK == Messagebox.show(message, title,
					Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION);
		} catch (InterruptedException e) {
			// ignore
			return false;
		}
	}

	/**
	 * 询问提示框
	 * <p>
	 * 该方法是一个类似 {@link #showQuestion(String, String)}
	 * 的方法,但与其不同的是,当禁用事件处理线程时,该方法非常有用。
	 * <p>
	 * 
	 * <p>
	 * 示例:<br />
	 * <hr>
	 * 
	 * <pre>
	 * ZkUtils.showQuestion(&quot;您确定删除该记录吗?&quot;, &quot;询问&quot;, new EventListener() {
	 * 	&#064;Override
	 * 	public void onEvent(Event event) throws Exception {
	 * 		int clickedButton = (Integer) event.getData();
	 * 		if (clickedButton == Messagebox.OK) {
	 * 			// 用户点击的是确定按钮
	 * 		} else {
	 * 			// 用户点击的是取消按钮
	 * 		}
	 * 	}
	 * 
	 * });
	 * </pre>
	 * 
	 * <hr>
	 * <p>
	 * 
	 * <table border="1">
	 *<tr>
	 * <td>按钮名称</td>
	 * <td>事件名称</td>
	 * </tr>
	 *<tr>
	 * <td>确定</td>
	 * <td>onOK</td>
	 * </tr>
	 *<tr>
	 * <td>取消</td>
	 * <td>onCancel</td>
	 * </tr>
	 *</table>
	 * 
	 * @param message
	 * @param title
	 * @param eventListener
	 */
	public static final void showQuestion(String message, String title,
			EventListener eventListener) {
		try {
			Messagebox.show(message, title, Messagebox.OK | Messagebox.CANCEL,
					Messagebox.QUESTION, eventListener);
		} catch (InterruptedException e) {
			// ignore
		}

	}

	/**
	 *给指定组件添加错误提示
	 * <p>
	 * 清除错误,需要使用{@link #clearWrongValue(Component)}
	 * 
	 * @param comp
	 * @param message
	 *            错误提示消息
	 * @see #clearWrongValue(Component)
	 */
	public static final void wrongValue(Component comp, String message) {
		Clients.wrongValue(comp, message);
	}

	/**
	 * 清除指定组件的错误提示
	 * 
	 * @param comp
	 */
	public static final void clearWrongValue(Component comp) {
		Clients.clearWrongValue(comp);
	}

	/**
	 * 清除列表中组件的错误提示
	 */
	public static final void clearWrongValue(List comps) {
		Clients.clearWrongValue(comps);

	}

	/**
	 *设置或删除widget的事件监听器,如果已经有同样的事件监听,那么上一个将被替换
	 * 
	 * @param comp
	 * @param evtName
	 *            事件名称,例如onClick
	 * @param script
	 *            javascript脚本代码,书写格式可按照html事件中js代码格式,如果为空,那么事件处理程序被删除
	 */
	public static final void setWidgetEventListener(Component comp,
			String evtName, String script) {
		comp.setWidgetListener(evtName, script);
	}

	/**
	 * 
	 * 向指定组件事件追加事件监听器
	 * 
	 * <pre>
	 * 
	 * ZkUtils.addWidgetEventListener(txtAge, &quot;onKeyPress&quot;, &quot;&quot;
	 * 		+ &quot;    if(event.keyCode&lt;48||event.keyCode&gt;57){         &quot;
	 * 		+ &quot;       return false;                                 &quot; + &quot;     }   &quot;
	 * 		+ &quot;   &quot;);
	 * </pre>
	 * 
	 * @param comp
	 * @param evtnm
	 *            事件名称,例如onClick
	 * @param script
	 *            javascript脚本代码,书写格式可按照html事件中js代码格式
	 */
	public static final void addWidgetEventListener(Component comp,
			String evtnm, String script) {
		if (script == null || "".equals(script.trim())) {
			return;
		}
		String oldScript = comp.getWidgetListener(evtnm);
		if (oldScript == null) {
			oldScript = "";
		}
		comp.setWidgetListener(evtnm, oldScript + script);

	}

	/**
	 * 验证表单
	 * <p>
	 * 需要input元素的constraint属性的支持
	 * <p>
	 * 
	 * 例如 年龄&lt;textbox constraint=&quot;/^[0-9]*$/:仅允许输入数字&quot;/&gt;
	 * 
	 * @param formContainer
	 *            Input元素公共
	 * @return 如果验证成功返回true,否则返回false
	 */
	public static boolean validateForm(Component formContainer) {
		return validateForm(formContainer, true);
	}

	/**
	 * 验证表单
	 * <p>
	 * 需要input元素的constraint属性的支持
	 * 
	 * 例如 年龄 &lt;textbox constraint=&quot;/^[0-9]*$/:仅允许输入数字&quot;/&gt;
	 * 
	 * @param formContainer
	 *            Input元素公共组件,即需要验证的输入元素所在的公共容器组件
	 * @param showError
	 *            是否显示错误提示
	 * @return 如果验证成功返回true,否则返回false
	 */
	public static boolean validateForm(Component formContainer,
			boolean showError) {
		try {
			validateForm0(formContainer, showError);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	private static void validateForm0(Component formContainer, boolean showError) {
		List<Component> cList = formContainer.getChildren();
		if (cList == null || cList.size() < 1) {
			return;
		} else {
			for (Component c : cList) {
				if (c instanceof InputElement && !((InputElement) c).isValid()) {
					if (showError) {
						((InputElement) c).getText();
					}
					throw new RuntimeException("表单输入不正确!");
				} else {
					validateForm0(c, showError);
				}
			}
		}
	}

	/**
	 * 结束常操作处理
	 * <p>
	 * 一个业务操作可能要一段时间可以处理完成,在处理期间,又不想让用户操作界面,影响业务处理等,
	 * 那么可以在前台事件中调用zk.startProcessing(),此时左上角出现提示框,"正在处理,请稍候..."
	 * 
	 */
	public static final void endProcessing() {
		Clients.evalJavaScript("zk.endProcessing();");
	}
}

 

分享到:
评论

相关推荐

    MongoDB分片集群搭建教程:副本集创建与数据分片

    内容概要:本文提供了详细的MongoDB分片集群的搭建指导,涵盖了从环境准备、配置文件编写、副本集的建立、主节点的选择、配置服务器和数据分片服务器的配置到最后的路由节点的搭建与操作整个流程,以及对数据库的哈希与范围两种分片策略的应用介绍和具体命令执行。 适合人群:熟悉NoSQL数据库概念并对MongoDB有一定了解的技术人员,尤其是在大型数据管理和分布式数据库架构设计中有需求的开发者。 使用场景及目标:帮助技术人员掌握构建高效能、高可用性的MongoDB分片集群的方法,适用于处理大规模、实时性强的数据存储与读取场景。 其他说明:文中通过实例演示了每个步骤的具体操作方法,便于跟随文档实操,同时也介绍了可能遇到的问题及其解决方案,如在没有正确配置的情况下试图写入数据时出现错误等情况的处理。

    CPPC++_嵌入式硬件的物联网解决方案blinker库与Arduino ESP8266 ESP32一起工作.zip

    CPPC++_嵌入式硬件的物联网解决方案blinker库与Arduino ESP8266 ESP32一起工作

    CPPC++_逆向调用QQ Mojo IPC与WeChat XPlugin.zip

    CPPC++_逆向调用QQ Mojo IPC与WeChat XPlugin

    CPPC++_现代活动指标.zip

    CPPC++_现代活动指标

    CPPC++_Xournal是一款手写笔记软件,支持PDF注释,使用C语言编写,支持GTK3,支持Linux,如Ubu.zip

    CPPC++_Xournal是一款手写笔记软件,支持PDF注释,使用C语言编写,支持GTK3,支持Linux,如Ubu

    基于SSM学生实习管理系统前台小程序与后台管理系统开发实践

    资源概述: 本资源提供了一套完整的学生实习管理系统解决方案,涵盖了前台小程序页面与后台管理系统两大模块。前台小程序页面设计简洁直观,用户可根据不同身份(学生或企业)进行登录。学生用户能够方便地浏览并投递感兴趣的实习岗位,而企业用户则能轻松发布实习信息,吸引优秀人才。后台管理系统功能全面,包括个人中心、首页、学生管理、教师管理、企业管理、招聘管理、评分管理以及实习管理等多个方面,为管理员提供了强大的数据管理和操作工具。 技术栈亮点: SSM框架:系统后台采用Spring、Spring MVC和MyBatis Plus(简称SSM)作为核心开发框架,确保了系统的稳定性、可扩展性和可维护性。Spring作为控制反转(IoC)和面向切面编程(AOP)的容器,为系统提供了强大的业务逻辑处理能力;Spring MVC则负责处理Web请求和响应,实现了前后端的分离;MyBatis Plus作为持久层框架,简化了数据库操作,提高了开发效率。 MySQL数据库:系统采用MySQL作为数据库存储解决方案,支持大数据量的存储和高效查询。 如有侵权请联系我删除,谢谢

    微服务闪聚支付项目.zip

    微服务闪聚支付项目

    Rust 与 Java 互调实战示例

    博客链接 https://blog.csdn.net/weixin_47560078/article/details/143714557 文章从原理介绍出发,实现了 Rust 与 Java 的互调。利用 JNI 技术,可以充分发挥 Rust 的性能优势,同时保持 Java 的跨平台特性。这种技术组合适用于对性能要求较高的应用场景,如图像处理、数据分析和系统级编程等。

    CPPC++_这是我翻译的艾根中文文档.zip

    cppc++

    Matlab实现斑马优化算法ZOA-TCN-Multihead-Attention多输入单输出回归预测算法研究.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    Matlab实现雪融优化算法SAO-TCN-Multihead-Attention多输入单输出回归预测算法研究.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    分布式事务lcn.zip

    分布式事务lcn

    基于Simulink的正弦波PWM技术和三次谐波注入PWM技术研究.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    【风电功率预测】基于BiTCN的风电功率多变量输入预测研究附Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    CPPC++_这是由一块迷你带OV2640双DRV8833驱动TypeC接口PSRAM的ESP32PicoD4开发板驱.zip

    cppc++

    JAVA安卓手机与电脑的socket通信源码数据库 其他源码类型 WinForm

    安卓手机与电脑的socket通信源码

    Anaconda:JupyterNotebook使用教程.docx

    Anaconda:JupyterNotebook使用教程.docx

    Amazon S3:S3静态网站托管教程.docx

    Amazon S3:S3静态网站托管教程.docx

    Python商品销售数据分析可视化项目源码(期末大作业).zip

    Python商品销售数据分析可视化项目源码(期末大作业).zip,个人经导师指导并认可通过的98分大作业设计项目。主要针对计算机相关专业的正在做期末大作业设计的学生和需要项目实战练习的学习者,可作为课程设计、期末大作业,代码资料完整下载可用。 Python商品销售数据分析可视化项目源码(期末大作业).zip,个人经导师指导并认可通过的98分大作业设计项目。主要针对计算机相关专业的正在做期末大作业设计的学生和需要项目实战练习的学习者,可作为课程设计、期末大作业,代码资料完整下载可用。Python商品销售数据分析可视化项目源码(期末大作业).zip,个人经导师指导并认可通过的98分大作业设计项目。主要针对计算机相关专业的正在做期末大作业设计的学生和需要项目实战练习的学习者,可作为课程设计、期末大作业,代码资料完整下载可用。Python商品销售数据分析可视化项目源码(期末大作业).zip,个人经导师指导并认可通过的98分大作业设计项目。主要针对计算机相关专业的正在做期末大作业设计的学生和需要项目实战练习的学习者,可作为课程设计、期末大作业,代码资料完整下载可用。Python商品销售数据分析

Global site tag (gtag.js) - Google Analytics