如何根据在另一行中输入的数据 hide/show panelgrid 中的一行

How to hide/show a row in a panelgrid based on data entered in another row

我有一个 panelGrid,其中一行包含 selectCheckBoxMenu,另一行应根据 selection 显示或隐藏。

不需要在 selection 更改时更新整个面板,因为 selectCheckBoxMenu 将被刷新,用户将不得不为他想要的每个项目再次打开下拉列表select.

将控件更新为隐藏或显示也无法解决问题,因为如果之前渲染为 false 而未显示,则无法更新。

因此,我将这些控件包装在一个片段中并更新了这些片段。在功能上没问题,但现在我的布局很丑陋,因为在大多数情况下控件将被隐藏并显示一个小的空行。

是否可以在不再次破坏功能的情况下摆脱那个丑陋的空行?

我的 xhtml 如下所示:

<p:panelGrid id="panel" columns="2" border="0" cellpadding="5"
    cellspacing="2">
    ...
    <h:outputLabel value="Type" />
    <p:selectCheckboxMenu id="deviceTypeMenu" value="#{controller.criteria.dts}" label="All" converter="dtConverter"
          filter="true" filterMatchMode="contains"
          panelStyle="width:300px" valueChangeListener="#{controller.onChange}"
          updateLabel="true">
        <p:ajax update="sclabel scfield" />
        <f:selectItems value="#{deviceTypeBean.alldts}" var="dt"
            itemLabel="#{dt.name}" itemValue="#{dt}"/>
    </p:selectCheckboxMenu>
    ...
    <p:fragment id="sclabel">
        <h:outputText value="Detail" rendered="#{controller.detailRequired}"/>
    </p:fragment>
    <p:fragment id="scfield">
        <p:selectCheckboxMenu rendered="#{controller.detailRequired}" converter="#{detailConverter}"
            value="#{controller.criteria.detail}" label="All details"
            filter="true" filterMatchMode="contains"
            style="width:300px;" scrollHeight="100"
            updateLabel="true">
            <f:selectItems value="#{detailConverter.values}" var="adetail"
                itemLabel="#{adetail.name}" itemValue="#{adetail}" />
        </p:selectCheckboxMenu>
    </p:fragment>
    ...
</p:panelGrid>

原因

空行包含填充。 table 行和 table 单元格 html 元素是由 panelgrid 创建的,因为它会为每一行呈现这些元素,并且一旦有某个子元素就会呈现一行。它们上面有 styleclasses,由 panelgrid 设置并引用包含填充的样式。这些片段,即使它们自己不渲染任何东西也足以触发它。

备注:我们使用的是 Primefaces 的 Modena 主题。因此,填充是摩德纳主题的一部分。 导致问题的 Modena 样式表的摘录:

.ui-panelgrid .ui-panelgrid-cell {
    border-width: 1px;
    border-style: solid;
    border-color: inherit;
    padding: 4px 10px;
}

解决方案

我做了以下更改:

  1. 我使用 primefaces 行和列组件明确指定了行和列,并向我需要隐藏的行的列添加了样式 class "ui-panelgrid-cell-nopadding"。我将下面的样式添加到我的样式表中,这样,该样式 class removes/overrides 来自面板网格添加的单元格的填充。

    .ui-panelgrid .ui-panelgrid-cell-nopadding { 填充:0px 0px; }

  2. 我在单元格中的控件周围添加了一个 div 并将 class ui-panelgrid-cell 应用于它以添加我删除的填充来自细胞。

    备注:我为此首先尝试了一个面板,但后来变得更加复杂,因为 Primefaces 面板还添加了样式classes,这导致与我的 panelgrid 中其他行的布局不一致(字体大小已更改) .

  3. 我在已有的片段和 div 之间添加了第二个片段,并将呈现的属性从单元格内的控件移动到这些片段。因此,如果我不想呈现该行,div 上定义的填充将不再存在。

    一个片段已经不够了,因为我需要一个带有 id 的片段以便能够通过 ajax 更新它,第二个片段带有呈现的属性。如果将这些属性放在同一个片段上,则一旦隐藏就无法再使其可见。将 id 移动到明确定义的列也是不可能的,因为这些单元格的行为可能很奇怪,因为它们在最初呈现 panelgrid 时是空的。当更新单元格使其可见时,我所在行的两个单元格的内容都出现在左侧单元格中,而右侧单元格仍为空。

  4. 之后,我在 div 周围设置了边框,因为这是在我应用于 div 的 Modena 样式中指定的以具有填充我从细胞中取出的因为 div 的内容比单元格小,我有一个额外的边框,我不想要。所以我在我的样式表中添加了一些东西来删除那个边框。

    .ui-panelgrid .ui-panelgrid-cell-nopadding .ui-panelgrid-cell { border:none; border:0px; }

我的 xhtml 现在看起来像这样:

<p:panelGrid id="panel" border="0">
    ...
    <p:row>
        <p:column>
            <h:outputLabel value="Type" />
            <p:selectCheckboxMenu id="deviceTypeMenu" value="#{controller.criteria.dts}" label="All" converter="dtConverter"
        </p:column>
        <p:column>
                filter="true" filterMatchMode="contains"
                panelStyle="width:300px" valueChangeListener="#{controller.onChange}"
                updateLabel="true">
                <p:ajax update="sclabel scfield" />
                <f:selectItems value="#{deviceTypeBean.alldts}" var="dt"
                    itemLabel="#{dt.name}" itemValue="#{dt}"/>
            </p:selectCheckboxMenu>
        </p:column>
    </p:row>
    ...
    <p:row>
        <p:column styleClass="ui-panelgrid-cell-nopadding">
            <p:fragment id="sclabel">
                <p:fragment rendered="#{controller.detailRequired}">
                    <div class="ui-panelgrid-cell">
                        <h:outputText value="Detail"/>
                    </div>
                </p:fragment>
            </p:fragment>
        </p:column>
        <p:column styleClass="ui-panelgrid-cell-nopadding">
            <p:fragment id="scfield">
                <p:fragment rendered="#{controller.detailRequired}">
                    <div class="ui-panelgrid-cell">
                        <p:selectCheckboxMenu converter="#{detailConverter}"
                            value="#{controller.criteria.detail}" label="All details"
                            filter="true" filterMatchMode="contains"
                            style="width:300px;" scrollHeight="100"
                            updateLabel="true">
                            <f:selectItems value="#{detailConverter.values}" var="adetail"
                                itemLabel="#{adetail.name}" itemValue="#{adetail}" />
                        </p:selectCheckboxMenu>
                    </div>
                </p:fragment>
            </p:fragment>
        </p:column>
    <.p:row>
    ...
</p:panelGrid>

例如将 Id 放入行:

在 javascript 中: 如果(你需要的条件) { document.getElementById("form:idEmpresa").style.display = "none";
}

准备就绪