How to conditionally render plain HTML elements like <div>s?

这一生的挚爱 提交于 2019-11-26 07:34:41

问题


I\'m trying to implement a composite component which either displays the information details of a user in plain text or displays them through editable input texts fields if the desired details are those of the user currently connected.

I know that al UI Components can be rendered via the rendered attribute but what about the ones which are not UI Components (for example divs)

<div class = \"userDetails\" rendered = \"#{cc.attrs.value.id != sessionController.authUser.id}\">
    Name: #{cc.attrs.value.name}
    Details: #{cc.attrs.value.details}
</div>

<div class = \"userDetails\" rendered = \"#{cc.attrs.value.id == sessionController.authUser.id}\">
    <h:form>
        ...
    </h:form>
</div>

I know that the div doesn\'t have the rendered attribute and probably I\'m not taknig the right approach at all. I could very easily use an JSTL tag but I want to avoid that.


回答1:


The right JSF component to represent a HTML <div> element is the <h:panelGroup> with the layout attribute set to block. So, this should do:

<h:panelGroup layout="block" ... rendered="#{someCondition}">
    ...
</h:panelGroup>

Alternatively, wrap it in an <ui:fragment>:

<ui:fragment rendered="#{someCondition}">
    <div>
        ...
    </div>
</ui:fragment>

Do note that when you'd like to ajax-update a conditionally rendered component, then you should be ajax-updating its parent component instead.

See also:

  • Alternative to ui:fragment in JSF
  • Conditional rendering of non-JSF components (plain vanilla HTML and template text)
  • Ajax update/render does not work on a component which has rendered attribute
  • Why do I need to nest a component with rendered="#{some}" in another component when I want to ajax-update it?



回答2:


This has been easy since JSF 2.2. By using pass-through elements, any HTML element can be converted to a JSF component, which has the rendered attribute.

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:jsf="http://xmlns.jcp.org/jsf">
    <div class="userDetails" jsf:rendered="#{cc.attrs.value.id != sessionController.authUser.id}">
        Name: #{cc.attrs.value.name}
        Details: #{cc.attrs.value.details}
    </div>
</html>

Read more at https://jsflive.wordpress.com/2013/08/08/jsf22-html5/#elements




回答3:


I would just wrap your HTML with <h:panelGroup>

<h:panelGroup rendered = "#{cc.attrs.value.id != sessionController.authUser.id}">
    <div class = "userDetails">
        Name: #{cc.attrs.value.name}
        Details: #{cc.attrs.value.details}
    </div>
</h:panelGroup>

<h:panelGroup  rendered = "#{cc.attrs.value.id == sessionController.authUser.id}">
    <div class = "userDetails">
        <h:form>
           ...
        </h:form>
    </div>
</h:panelGroup>

Another option is to use components from either Seam (<s:div>) or Tomahawk (<t:htmlTag>) libraries if you already have them in your project.

See: http://www.jsftoolbox.com/documentation/seam/09-TagReference/seam-div.html

<s:div styleClass = "userDetails" rendered = "#{cc.attrs.value.id != sessionController.authUser.id}">
    Name: #{cc.attrs.value.name}
    Details: #{cc.attrs.value.details}
</s:div>

<s:div styleClass = "userDetails" rendered = "#{cc.attrs.value.id == sessionController.authUser.id}">
    <h:form>
        ...
    </h:form>
</s:div>

Or: http://myfaces.apache.org/tomahawk-project/tomahawk12/tagdoc/t_htmlTag.html

<t:htmlTag value="div" styleClass = "userDetails" rendered = "#{cc.attrs.value.id != sessionController.authUser.id}">
    Name: #{cc.attrs.value.name}
    Details: #{cc.attrs.value.details}
</t:htmlTag>

<t:htmlTag value="div" styleClass = "userDetails" rendered = "#{cc.attrs.value.id == sessionController.authUser.id}">
    <h:form>
        ...
    </h:form>
</t:htmlTag>



回答4:


You could use another composite components. There are no divs or other additional tags, just exactly the one you need. See this example:

<table>
    <tr>...</tr>
    <my:cc rendered="false">
        <tr>...</tr>
    </my:cc>
    <my:cc rendered="true">
        <tr>...</tr>
    </my:cc>
</table>

And the my:cc component:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:cc="http://xmlns.jcp.org/jsf/composite">

    <cc:interface>
    </cc:interface>

    <cc:implementation>
        <cc:insertChildren />
    </cc:implementation>
</html>

Produces following HTML, no additional tags at all, working with ajax.

<table><tr>...</tr><tr>...</tr></table>


来源:https://stackoverflow.com/questions/8816212/how-to-conditionally-render-plain-html-elements-like-divs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!