如何使用DHTML动态创建表单控件并使用JSF处理所有这些控件?

时间:2011-06-02 18:59:05

标签: javascript ajax jsf dhtml web-controls

假设下一种情况:创建一个使用DHTML呈现表单控件的视图(也就是说,每次用户按下按钮时,都会创建一个包含字段的新行,并且生成字段标识符并将其分配给字段与'form1control1'等相同的DHTML,但是那些控件与ViewRoot中的任何UIComponent都没有关系(因为它们是由客户端动态创建的,因此服务器不知道它们在表单中)< strong>我如何处理a)找到控件和b)在JSF中使用这些名称进行验证和处理?

使用JSP方法控制名称和值来自HttpRequest并且通过调用请求对象并使用搜索具有模式的所有对象的algorythm很容易处理这些项目,因此在那里有一个名为'form1control1'的对象,我将通过使用ie找到它request.getParameterNames()和request.getParameter(“form”+ N +“control”+ M),以便稍后通过使用所有命名参数的代码来处理验证和转换。

据我所知,使用JSF我需要将一个控件与一个UIComponent关联,方法是在JSP中使用一个标签声明控件,因此,要将任何一个或两个验证器或转换器连接到此控件,因此RootView知道控件在那里并且有一个相关的名称,它将期望管理该控件,但我不需要JSP声明的控件,而是由客户端使用JavaScript动态创建的控件,稍后发送到服务器并作为任何其他JSP声明处理UIComponent,所以我可以重新提出我的问题:如何处理未在任何JSP中声明并由客户端使用DHTML动态构建的控件,以进行验证,转换和处理?

我想我可以通过调用ViewRoot来调用ViewRoot,只要我用新控件执行新行并通过以编程方式向树添加任何控件来更新它,但我认为这种方法非常昂贵,因为我需要一个)生成一个AJAX请求,b)在我执行动作时随时向服务器提供工作,其形式意味着使用处理时间和分配内存资源;所以,首选,我希望避免使用AJAX来更新ViewRoot并创建/删除任何新控件。显然,如果必须使用AJAX更新ViewRoot以达到该行为,我就不会关闭。如果我能避免这种最后的方法,那就太受欢迎了。

非常感谢您的反馈。

2 个答案:

答案 0 :(得分:2)

这是可能的,但您需要对JSF API有一个相对较好的理解,因为它并非完全无关紧要。这样做的方法是在组件树中使用基于Java的自定义组件,该组件用作您将在客户端上创建的动态HTML的容器。

通过UIComponent#decodeRenderer#decode(如果使用单独的渲染器),Java自定义组件可以在回发后检查请求,并使用动态创建的组件发布到的原始值填充自身。服务器

了解其工作原理的一个好方法就是检查现有的渲染器。例如。 CheckboxRenderer的简化示例:

public void decode(FacesContext context, UIComponent component) {

    clientId = component.getClientId(context);

    // Convert the new value
    Map<String, String> requestParameterMap = context.getExternalContext().getRequestParameterMap();
    boolean isChecked = isChecked(requestParameterMap.get(clientId));
    setSubmittedValue(component, isChecked);
}

private static boolean isChecked(String value) {

    return "on".equalsIgnoreCase(value)
           || "yes".equalsIgnoreCase(value)
           || "true".equalsIgnoreCase(value);

}

在解码方法中,您正在处理所有“虚拟组件”,然后JSF将所有内容视为一个组件。

动态创建已在客户端上动态创建的组件的服务器端表示也或多或少成为可能。我或多或少地说,因为Mojarra(JSF参考实现)目前有一些错误阻止它在所有情况下都能很好地工作。参见例如http://java.net/jira/browse/JAVASERVERFACES-1826 MyFaces似乎可以正常工作。

您可能对Richard for Metawidget所做的工作特别感兴趣:http://metawidget.org/

此外,我已经解决了将这个动态(服务器端)组件创建添加到JSF规范的问题。如果您认为这对您的用例很重要,请在以下网址进行投票:http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1007

答案 1 :(得分:1)

我不知道在客户端上创建组件的任何方法,然后在提交回服务器时会自动绑定到viewstate。我认为你需要ajax才能实现这一目标。

您当然可以动态创建输入元素,并且仍然可以直接从HttpServletRequest获取最终用户输入的值,但对于JSF,整个范例围绕维护视图状态。