如何在XPage中切换新建文档表单并动态刷新页面?
我之前做Domino XPage开发时也碰到过一模一样的情况,切换单选按钮选了新表单,但页面还是死死显示默认表单的字段,折腾了好一会儿才搞定。下面给你一步步讲怎么实现:
1. 配置单选按钮组的 onChange 事件
首先,把单选按钮组绑定到一个会话变量(比如sessionScope.selectedForm),这样切换时能保存选中的表单名称。然后在onChange事件里做两件关键的事:更新新文档的Form字段,让数据源重新加载表单定义,再刷新页面的内容区域。
示例代码:
<xp:radioGroup id="rg_formSelector" value="#{sessionScope.selectedForm}"> <xp:selectItem itemLabel="客户表单" itemValue="Customer"></xp:selectItem> <xp:selectItem itemLabel="订单表单" itemValue="Order"></xp:selectItem> <!-- 可添加更多表单选项 --> <xp:eventHandler event="onchange" submit="true" refreshMode="partial" refreshId="pnl_formContent"> <xp:this.action><![CDATA[#{javascript: // 假设你的数据源是document1,更新它的Form字段 var selectedForm = sessionScope.selectedForm; document1.replaceItemValue("Form", selectedForm); // 核心操作:让数据源重新加载新表单的字段定义 document1.setForm(selectedForm); document1.reload(); }]]></xp:this.action> </xp:eventHandler> </xp:radioGroup>
2. 用面板包裹动态字段区域
把所有根据表单显示的字段放到一个xp:panel里,给它设置唯一ID(比如上面的pnl_formContent),这样单选按钮切换时只刷新这个面板,不用全页面刷新,用户体验更流畅。
这里提供两种常见的动态渲染方式:
方式A:用自定义控件加载对应表单
这种方式更清晰易维护,给每个表单做一个独立的自定义控件(比如cc_Customer.xsp、cc_Order.xsp),然后通过xp:include动态加载:
<xp:panel id="pnl_formContent"> <xp:include> <xp:this.pageName><![CDATA[#{javascript: // 根据选中的表单拼接自定义控件路径 return "cc_" + sessionScope.selectedForm + ".xsp"; }]]></xp:this.pageName> </xp:include> </xp:panel>
方式B:用 rendered 属性控制字段显示
如果字段数量不多,也可以给每个字段加rendered属性,判断当前选中的表单来决定是否显示:
<xp:panel id="pnl_formContent"> <!-- 客户表单专属字段 --> <xp:inputText id="txt_custName" value="#{document1.CustomerName}" rendered="#{sessionScope.selectedForm == 'Customer'}"></xp:inputText> <xp:inputText id="txt_custPhone" value="#{document1.CustomerPhone}" rendered="#{sessionScope.selectedForm == 'Customer'}"></xp:inputText> <!-- 订单表单专属字段 --> <xp:inputText id="txt_orderNo" value="#{document1.OrderNo}" rendered="#{sessionScope.selectedForm == 'Order'}"></xp:inputText> <xp:inputText id="txt_orderDate" value="#{document1.OrderDate}" rendered="#{sessionScope.selectedForm == 'Order'}"></xp:inputText> </xp:panel>
3. 初始化默认表单值
在XPage的beforePageLoad事件里设置默认选中的表单,避免页面刚加载时没有表单值导致显示异常:
<xp:this.beforePageLoad><![CDATA[#{javascript: if (!sessionScope.selectedForm) { // 设置默认表单,比如"Customer" sessionScope.selectedForm = "Customer"; // 初始化数据源的Form字段 document1.setForm(sessionScope.selectedForm); document1.reload(); } }]]></xp:this.beforePageLoad>
4. 保存文档的注意事项
保存时,文档的Form字段已经通过前面的步骤正确设置了,直接调用数据源的save()方法即可:
<xp:button value="保存新建文档" id="btn_save"> <xp:eventHandler event="onclick" submit="true" refreshMode="complete"> <xp:this.action><![CDATA[#{javascript: document1.save(); // 保存后可跳回视图页面或刷新当前页面 context.redirectToPage("yourViewPage.xsp"); }]]></xp:this.action> </xp:eventHandler> </xp:button>
为什么之前切换后不更新?
核心原因是你只切换了表单选择,但没有让数据源重新加载新表单的字段定义,也没有刷新显示字段的区域。上面的document1.setForm(selectedForm)和document1.reload()就是让数据源重新读取新表单的配置,而partial refresh面板则让页面重新渲染对应表单的内容。
内容的提问来源于stack exchange,提问作者lucas

