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

发布于 2024-11-14 02:14:24 字数 1041 浏览 2 评论 0原文

假设接下来的情况:创建一个视图,其中表单控件使用 DHTML 呈现(即,每次用户按下按钮时,都会创建一个包含字段的新行,并且生成字段标识符并将其分配给具有相同 DHTML 的字段如“form1control1”等),但该控件尚未与 ViewRoot 中的任何 UIComponent 相关(因为它们是由客户端动态创建的,因此服务器不知道它们位于表单中)如何我可以处理 a) 查找控件和 b) 使用该名称在 JSF 中进行验证和处理吗?

使用 JSP 方法,可以控制名称和名称。值随 HttpRequest 一起提供,通过调用请求对象并使用使用模式搜索所有对象的算法可以轻松处理这些项目,因此如果存在名为“form1control1”的对象,我将使用 ie 找到它request.getParameterNames() 和 request.getParameter("form"+N+"control"+M),用于稍后通过使用所有命名参数的代码来处理验证和转换。

据我了解,对于 JSF,我需要通过使用一个标签在 JSP 中声明该控件来将一个控件与一个 UIComponent 关联起来,因此,将任何一个或两个验证器或转换器附加到该控件,以便 RootView 知道该控件在那里并且有一个关联的名称,并且它将期望管理该控件,但我不需要 JSP 声明的控件,而是由客户端使用 JavaScript 动态创建的控件,稍后发送到服务器并被视为任何其他 JSP 声明的 UIComponent,因此我可以重新启动我的问题:如何处理未在任何 JSP 中声明并由客户端使用 DHTML 动态构建的控件,以进行验证、转换和处理?

我想我可以通过 AJAX 来完成此操作每当我使用新控件创建新行并通过以编程方式将任何控件添加到树中来更新它时,都会调用 ViewRoot,但是,我认为这种方法非常昂贵,因为我需要 a) 生成 AJAX 请求,b) 提供工作每当我使用暗示使用处理时间和分配内存资源的表单执行操作时,服务器;因此,我希望避免使用 AJAX 来更新 ViewRoot 并创建/删除任何新控件,显然,如果强制使用 AJAX 来更新 ViewRoot 来达到该行为,我不会关闭。如果我能避免这最后一种方法,那就太受欢迎了。

非常感谢您提前提供反馈。

Suppose this next situation: making a view where the form controls are rendered with DHTML (that is, each time the user press a button, a new row with fields is created and field identifiers are both generated and asigned to the fields with the same DHTML as 'form1control1' and so on), but where that controls are not related yet to any UIComponent in the ViewRoot (as they are created dynamically by the client and so the server don't know they are in the form) How can I deal with a) finding that controls and b) using that names for validation and processing within JSF?

With a JSP approach, that controls names & values are coming with the HttpRequest and is easy to deal with those items by calling the request object and using an algorythm that search all the objects with a pattern, so where an object named 'form1control1' is there, I will find it by using i.e. request.getParameterNames() and request.getParameter("form"+N+"control"+M), for later dealing with making validations and convertions by using code for all the named parameters.

As I understand, with JSF I need to associate one control with one UIComponent by declaring the control within the JSP with one tag and therefore, to attach any either or both validator or converter to this control, so the RootView knows the control is there and has an associated name, and it will expect to manage that control, but I need not a JSP-declared control, but one created by the client dynamically with JavaScript, later sent to the server and treated as any other JSP-declared UIComponent, so I can relaunch my question as: How do I deal with controls not declared within any JSP and built dynamically by the client with DHTML, for validation, conversion and processing?

I suppose I can do it with AJAX by calling the ViewRoot any time I do a new row with new controls and updating it with adding any control programatically to the tree, but, I think that approach is very expensive as I need a) generate an AJAX request, b) to give work to the server anytime I do an action withing the form that implies using processing time and assigning memory resources; so, prefered, I would desire to avoid using AJAX for updating the ViewRoot with any new control created/deleted, Obviously I'm not closed if it is mandatory to use AJAX for updating the ViewRoot to reach that behavior. If I can avoid this last approach, it is too welcome.

Thanks so much for your feedback in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

毁梦 2024-11-21 02:14:24

这是可能的,但您需要对 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 为 Metawidget 所做的工作特别感兴趣: http://metawidget.org/

此外,我'我们提出了一个问题,将这种动态(服务器端)组件创建添加到 JSF 规范中。如果您认为这对您的用例很重要,请在以下位置投票:http://java .net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1007

This is possible, but you need to have a relatively good understanding of the JSF API as its not exactly trivial. The way to do it is to have a Java based custom component in the component tree that serves as a container for the dynamic HTML you will be creating on the client.

Via either UIComponent#decode or Renderer#decode (if you use a separate renderer) your Java custom component can inspect the request after a postback and populate itself with the raw values that the dynamically created components post to the server.

A good way to get an idea how this works is just to inspect existing renderers. E.g. a simplified example from the 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);

}

Inside the decode method you're handling all your 'virtual components' and JSF then sees everything as one component.

It's also more or less possible to dynamically create a server side representation of the components that have been dynamically created on the client. I say more or less since Mojarra (the JSF reference implementation) currently has some bugs that prevent this working well in all situations. See e.g. http://java.net/jira/browse/JAVASERVERFACES-1826 MyFaces seems to work correctly though.

You might be specifically interested in the work done by Richard for Metawidget: http://metawidget.org/

Furthermore, I've opened an issue to have this dynamic (server side) component creation added to the JSF spec. If you think this is important for your use case, please give it a vote at: http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1007

阳光的暖冬 2024-11-21 02:14:24

我不知道有什么方法可以在客户端上创建组件,然后在提交回服务器时自动绑定到视图状态。我认为你需要 ajax 来完成这个任务。

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

I am not aware of any way to create components on the client that would then be automatically bound to viewstate when submitted back to the server. I think you would need ajax to accomplish that.

You can of course create input elements dynamically and still obtain the values entered by an end user directly from HttpServletRequest, but for JSF the whole paradigm revolves around maintaining viewstate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文