【问题标题】:Primefaces datatable roweditor: only permit one row editingPrimefaces 数据表行编辑器:只允许编辑一行
【发布时间】:2013-10-22 23:55:44
【问题描述】:

我正在使用 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 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点击带有图标ui-icon-close的span,当该span有显示内联时,而不是其他没有显示的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;"

【问题讨论】:

  • 我刚刚找到了一个自制的解决方案,但我认为这是一些拙劣的工作。
  • 我已将此解决方案添加到问题中。
  • 我已经添加了其他解决方案来改善其他问题。
  • 7 投票没有任何评论/答案?
  • @VíctorPariente 您可以将您的解决方案添加为答案,并将您喜欢的解决方案标记为已接受。

标签: jquery jsf primefaces


【解决方案1】:

您需要遍历元素,并取消任何其他编辑。

$('.myTableStyle tbody.ui-datatable-data tr td span.ui-row-editor span.ui-icon-cancel').each(function(){
  $(this).click();
});

【讨论】:

    【解决方案2】:

    上述解决方案对我不起作用。作为替代解决方案,当我使用 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')});"/>
    

    【讨论】:

    • 这会隐藏图标铅笔,但如果您单击空白区域,仍会执行 rowEdit 功能。我建议将 $(this).css('visibility','hidden') 更改为 $(this).hide() 并将 $(this).css('visibility','visible') 更改为 $(this).show()
    • @Elí Giacomelli 是对的,UI 元素是不可见的,但是当您单击铅笔单元格时操作仍然有效,所以我推荐他建议的更新
    猜你喜欢
    • 1970-01-01
    • 2016-04-17
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多