Primefaces数据表格行编辑器:只允许编辑一行。

19

我正在使用JSF 2.1.6和Primefaces 3.4.1工作,有一个问题。

我有一个可编辑的数据表格和行编辑器。您可以单击每行的铅笔按钮,该行将变为可编辑状态。 但默认情况下可能会单击多个铅笔按钮,因此会导致多行处于可编辑状态。

但我只想有一行处于编辑模式。

这是我的代码示例:

<p:dataTable value="rows" var="row" editable="true" 
 id="myTable" widgetVar="myTableVar" styleClass="myTableStyle">

    <p:ajax event="rowEdit" listener="#{myBean.onUpdateRow}" />
    <p:ajax event="rowEditCancel" />

    <p:columnGroup type="header">
        <p:column headerText="Name" />
        <p:column headerText="Age" />
        ...
        <p:column headerText="Edit" />
    </p:columnGroup>

    <p:column>
        <p:cellEditor>
        <f:facet name="output">
                <h:outputText value="#{row.name}" />
            </f:facet>
            <f:facet name="output">
                 <h:inputText value="#{row.name}" /> 
            </f:facet>
        </p:cellEditor>
    </p:column>

    <p:column>
        <p:cellEditor>
        <f:facet name="output">
                <h:outputText value="#{row.age}" />
            </f:facet>
            <f:facet name="output">
                 <h:inputText value="#{row.age}" /> 
            </f:facet>
        </p:cellEditor>
    </p:column>

    ...

    <p:column>
        <p:commandLink update="myTable">
            <p:rowEditor />
        </p:commandLink>
    </p:column>

</p:dataTable>

<p:commandButton icon="ui-icon-plus" action="#{myBean.addNewRow}" update="myTable"
 oncomplete="$('.myTableStyle tbody.ui-datatable-data tr:last-child td span.ui-row-editor span.ui-icon-pencil').click()"
 title="Add new row" />

我已经将行编辑组件封装在一个命令链接组件中,因为现在我可以在单击行编辑器时添加Javascript代码。

我尝试将此Javascript代码添加到commandLink中:

onclick="$('.myTableStyle tbody.ui-datatable-data tr td span.ui-row-editor span.ui-icon-cancel').click()"

但这样会造成太多的递归并且不能正常工作。

行编辑器有三个span链接:一个用于打开编辑模式(ui-icon-pencil),另一个用于保存编辑(ui-icon-check),还有一个用于取消编辑(ui-icon-close)。保存时有一个ajax事件(rowEdit),取消时有另一个事件(rowEditCancel)。

在未激活编辑模式的文件中,行编辑器的span是这样的:

<span class="ui-icon ui-icon-pencil"></span>
<span class="ui-icon ui-icon-check" style="display:none"></span>
<span class="ui-icon ui-icon-close" style="display:none"></span>

当编辑模式激活时,行编辑器像这样覆盖文件:

 <span class="ui-icon ui-icon-pencil" style="display:none"></span>
 <span class="ui-icon ui-icon-check"></span>
 <span class="ui-icon ui-icon-close"></span>

如何只点击编辑模式激活的行?或者有一个函数或属性可以仅允许一个行处于编辑模式? 我能否仅使用jQuery单击display inline的带有ui-icon-close图标的span,而不是其他display none的span?

更新:我找到的解决方案

我刚刚找到了一个自制的解决方案。这是它: 我给链接添加了一个onstart函数,但这会生成性能问题:它既被调用保存、编辑和取消。我还更改了添加行按钮的oncomplete函数。

<p:dataTable value="rows" var="row" editable="true" 
 id="myTable" widgetVar="myTableVar" styleClass="myTableStyle">

    <p:ajax event="rowEdit" listener="#{myBean.onUpdateRow}" />
    <p:ajax event="rowEditCancel" />

    <p:columnGroup type="header">
        <p:column headerText="Name" />
        <p:column headerText="Age" />
        ...
        <p:column headerText="Edit" />
    </p:columnGroup>

    <p:column>
        <p:cellEditor>
        <f:facet name="output">
                <h:outputText value="#{row.name}" />
            </f:facet>
            <f:facet name="output">
                 <h:inputText value="#{row.name}" /> 
            </f:facet>
        </p:cellEditor>
    </p:column>

    <p:column>
        <p:cellEditor>
        <f:facet name="output">
                <h:outputText value="#{row.age}" />
            </f:facet>
            <f:facet name="output">
                 <h:inputText value="#{row.age}" /> 
            </f:facet>
        </p:cellEditor>
    </p:column>

    ...

    <p:column>
        <p:commandLink update="myTable" onstart="$('.myTableStyle tbody.ui-datatable-data tr td .ui-cell-editor-input').hide(); $('.myTableStyle tbody.ui-datatable-data tr td .ui-cell-editor-output').show(); $('.myTableStyle tbody.ui-datatable-data tr td span.ui-row-editor span.ui-icon-pencil').show();  $('.myTableStyle tbody.ui-datatable-data tr td span.ui-row-editor span.ui-icon-check').hide(); $('.myTableStyle tbody.ui-datatable-data tr td span.ui-row-editor span.ui-icon-close').hide(); $('.myTableStyle tbody.ui-datatable-data tr').removeClass('ui-state-highlight'); return false;">
            <p:rowEditor />
        </p:commandLink>
    </p:column>

</p:dataTable>

<p:commandButton icon="ui-icon-plus" action="#{myBean.addNewRow}" update="myTable"
 oncomplete="$('.myTableStyle tbody.ui-datatable-data tr:last-child td .ui-cell-editor-input').show(); $('.myTableStyle tbody.ui-datatable-data tr:last-child td .ui-cell-editor-output').hide(); $('.myTableStyle tbody.ui-datatable-data tr:last-child td span.ui-row-editor span.ui-icon-pencil').hide();  $('.myTableStyle tbody.ui-datatable-data tr:last-child  td span.ui-row-editor span.ui-icon-check').show(); $('.myTableStyle tbody.ui-datatable-data tr:last-child  td span.ui-row-editor span.ui-icon-close').show(); $('.myTableStyle tbody.ui-datatable-data tr:last-child').addClass('ui-state-highlight'); return false;
 title="Add new row" />
Update-2: 最终我找到了解决性能问题的方法。我的问题在于,当单击编辑、保存和取消行编辑时,JavaScript动作被调用。为了防止这种情况,我将onstart函数更改为onclick函数,并在单击“编辑行”按钮(铅笔图标)时仅将其他行更改为不可编辑。为此,我使用event.target来知道点击了哪个元素。由于行编辑、行编辑保存和行编辑取消按钮具有不同的类(ui-icon-pencil、ui-icon-check和ui-icon-close),因此你可以区分按下的是哪个按钮。因此,以下是替换onstart函数的函数:
onclick="$(if($(event.target).hasClass('ui-icon-pencil')) {'.myTableStyle tbody.ui-datatable-data tr td .ui-cell-editor-input').hide(); $('.myTableStyle tbody.ui-datatable-data tr td .ui-cell-editor-output').show(); $('.myTableStyle tbody.ui-datatable-data tr td span.ui-row-editor span.ui-icon-pencil').show(); $('.myTableStyle tbody.ui-datatable-data tr td span.ui-row-editor span.ui-icon-check').hide(); $('.myTableStyle tbody.ui-datatable-data tr td span.ui-row-editor span.ui-icon-close').hide(); $('.myTableStyle tbody.ui-datatable-data tr').removeClass('ui-state-highlight');} return false;"

我刚找到了一个自制的解决方案,但我认为它有点粗糙。 - Víctor Pariente
我已将此解决方案添加到问题中。 - Víctor Pariente
我已经添加了另一个解决方案来改进其他问题。 - Víctor Pariente
7 个投票却没有任何评论或回答? - l2aelba
1
@VíctorPariente 您可以将您的解决方案添加为答案,并将您首选的解决方案标记为已接受。 - Nelson
在这种情况下,将更新1和2作为答案添加,然后稍后将第二个标记为已接受,是否更正确? - Víctor Pariente
2个回答

7

对我来说,上面的解决方案没有用。作为一种替代方案,在我编辑行时,我只使用CSS隐藏了编辑按钮(铅笔)。

<p:ajax event="rowEditInit" oncomplete="$('.ui-row-editor span.ui-icon-pencil').each(function(){$(this).css('visibility','hidden')});" />

<p:ajax event="rowEdit" oncomplete="$('.ui-row-editor span.ui-icon-pencil').each(function(){$(this).css('visibility','visible')});"/>   

<p:ajax event="rowEditCancel" onstart="$('.ui-row-editor span.ui-icon-pencil').each(function(){$(this).css('visibility','visible')});"/>

3
这会隐藏铅笔图标,但如果您单击空白区域,仍会执行行编辑功能。我建议将 $(this).css('visibility','hidden') 更改为 $(this).hide() ,将 $(this).css('visibility','visible') 更改为 **$(this).show()**。 - Ramiro Arizpe Giacomelli
@Elí Giacomelli是正确的,UI元素只是不可见的,但当您单击铅笔单元格时,操作仍在起作用,因此我建议按照他提出的更新进行。 - Shessuky

1
你需要遍历元素,并取消任何其他编辑。
$('.myTableStyle tbody.ui-datatable-data tr td span.ui-row-editor span.ui-icon-cancel').each(function(){
  $(this).click();
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接