2013-10-23 14 views
28

セルが編集されたら、PrimeFaces Datatableを再レンダリングするのが難しいです。あるセルの値を変更すると、他のセルのエントリが変更される可能性があるため、テーブル全体をリフレッシュする必要があります。ここで<p:ajax event = "cellEdit">完了時に<p:dataTable>全体を更新

は、JSFページがあります:

<h:form id="testForm"> 
    <p:outputPanel id="testContainer"> 

     <p:dataTable id="testTable" value="#{tableBean.data}" var="entry" editable="true" editMode="cell"> 

      <p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" /> 

      <p:column headerText="Col1"> 
       <p:cellEditor> 
        <f:facet name="output"><h:outputText value="#{entry.col1}" /></f:facet> 
        <f:facet name="input"><p:inputText value="#{entry.col1}" /></f:facet> 
       </p:cellEditor> 
      </p:column> 

      <p:column headerText="Col2"> 
       <p:cellEditor> 
        <f:facet name="output"><h:outputText value="#{entry.col2}" /></f:facet> 
        <f:facet name="input"><p:inputText value="#{entry.col2}" /></f:facet> 
       </p:cellEditor> 
      </p:column> 

     </p:dataTable> 

     <p:commandButton id="refreshButton" value="Redisplay" update="testContainer" /> 

    </p:outputPanel>          
</h:form> 

そしてここでは、バッキングBeanです:更新を含む

@ManagedBean(name = "tableBean", eager = false) 
@ViewScoped 
public class TableBean { 

    public TableBean() { 
     RowData entry = new RowData("a1", "b1"); 
     entries.add(entry); 
     entry = new RowData("a2", "b2"); 
     entries.add(entry); 
     entry = new RowData("a3", "b3"); 
     entries.add(entry); 
    } 

    public class RowData { 

     private String col1; 
     private String col2; 

     public RowData(String col1, String col2) { 
      this.col1 = col1; 
      this.col2 = col2; 
     } 

     public String getCol1() { 
      return col1; 
     } 

     public void setCol1(String col1) { 
      this.col1 = col1; 
     } 

     public String getCol2() { 
      return col2; 
     } 

     public void setCol2(String col2) { 
      this.col2 = col2; 
     } 
    } 

    private ArrayList<RowData> entries = new ArrayList<RowData>(); 

    public List<RowData> getData() { 
     return entries; 
    } 

    public void onCellEdit(CellEditEvent event) { 
     entries.get(event.getRowIndex()).setCol1("Dummy Col 1"); 
     entries.get(event.getRowIndex()).setCol2("Dummy Col 2");   
    } 
} 

= ":TESTFORM:TESTCONTAINER" cellEdit AJAXイベント内、セル値の削除を変更します画面上のデータテーブルは、(ボタンと一緒に)セルの内容だけをレンダリングします - なぜこれが理解できません。更新属性が指定されていない場合、テーブルはアクティブなセルが更新されたまま画面上に残りますが、他のセルは更新されません(期待どおり)。

AJAX cellEditイベント内で更新属性を指定せず、セルの値を編集した後に再表示ボタンをクリックすることで、(非自動化で)目的の動作を実現できます。どのように私はこれを自動化された方法で達成することができますか?なぜ私は期待どおりに更新属性が機能しませんか?

私はPrimeFaces 4.0を使用しています。

+0

update = ":testForm:testTable"によってupdate = ":testForm:testContainer"を変更しようとしましたか? –

+0

試しましたが、現在のセルだけが更新されています。 – Franzl

答えて

47

rowEditcellEditイベントは、update属性で明示的に指定されていない場合でも、現在の行以外は何も更新/再描画されません。これは、PrimeFacesのレスポンスサイズを最小限に抑えるための徹底的な試みの結果です。ほとんどの場合、これは理にかなっていますが、具体的にはそうではありません。それは問題報告の価値がある。

一方、この動作を修正するまでは、<p:remoteCommand>を使用して、目的のリスナメソッドを呼び出してテーブルを完全に更新することをお勧めします。

書き換え

<p:dataTable ...> 
    <p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" /> 
    ... 
</p:dataTable> 

<p:remoteCommand name="onCellEdit" action="#{tableBean.onCellEdit}" update="testContainer" /> 
<p:dataTable ...> 
    <p:ajax event="cellEdit" oncomplete="onCellEdit()" /> 
    ... 
</p:dataTable> 
+0

@BalusCあなたが指導したとおりにしましたが、 'Glassfish Server'は、' Tim Long'というこのメソッドに 'CellEditEvent'パラメタが含まれていると言及する必要があるので、' not not FOUND'メソッドでエラーを表示します。私は、**セル**が編集されたときに、 'datataatable全体を更新する 'ことを望んでいました。私を助けてくれますか? – elgolondrino

+0

誰もこの問題をPrimefaceに報告しましたか?私たちはPrimefaces PROを持っており、エスカレートする意思があります。 –

+3

すぐに素早く叫び、「ありがとう」。私は狂ったと思った。私にとっては、ajaxの 'cellEdit'リスナーをそのまま残しておき、' remote''属性に 'remote''属性を' remoteCommand'に移しました。のためのajaxイベントを使用しています。 – Doug

0

私はあなたのコードをテストしました。最初にp:commandButtonをp:outputPanelから移動しました。ここに修正コードがあります:

<h:form id="testForm"> 
      <p:outputPanel id="testContainer"> 

       <p:dataTable id="testTable" value="#{tableBean.data}" var="entry" editable="true" editMode="cell"> 

        <p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" /> 

        (...) 

       </p:dataTable> 
      </p:outputPanel> 
      <p:commandButton id="refreshButton" value="Redisplay" update="testContainer" /> 
     </h:form> 

私はこのコードが正しく動作しないと思います。テーブル内の何かを変更すると、毎回p:ajaxがフルテーブルを描画します。そのため、プログラムはTableBeanのコンストラクタから基本データを読み込み、新しいデータを削除します。

basic data

私はあなたのpを省略した場合:AJAXコードを画面から任意の新しいデータがdisapearsされていません。 refreshButton p:commandButtonが正しく機能します。

更新など=「TESTFORM:TESTCONTAINER」cellEdit AJAXイベント内、セルの値を変更すると、画面上のデータテーブルを削除し のみ(ボタンと共に)細胞コンテンツをレンダリングする - 私はありませんこれはなぜ が理解していますか?それは(何度もテーブルにプログラムの更新ので、二度目は、セルを編集できませんでした、正しく初めての仕事)exeptedとしてよりもあなたoutputPanel多くを更新しているため

私はそれが悪いデザインだと思いますが、AJAXにupdate=":testForm:testContainer"を追加します。

あなたの目標は何か分かりません。あなたがcommandButtonのないレンダリングテーブルを必要とする場合は、javascriptイベントまたはp:メッセージを1つ指定すれば、これが消えてテーブルをレンダリングできます。

p:ajaxの更新を省略したり、1つのp:メッセージの更新を指定して、testContainerのp.commandButtonをコード開始が正しく動作すると思います。

17

にBaLusCソリューションは私のために直接働いていません。 onCellEditには、パラメータとしてCellEditEventが必要です。

<p:remoteCommand name="onCellEdit" update="testContainer" /> 
<p:dataTable ...> 
    <p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" oncomplete="onCellEdit()" /> 
    ... 
</p:dataTable> 
+0

メソッドは機能しますが、1つの 'cell'を編集するだけですか?これを修正するには? – elgolondrino

+0

私のケースでは、BaLusCのソリューションは、編集可能なテーブル内にあるinputTextのために働いています。変更がセル内のautoCompleteコントロールで行われると、テーブル全体が更新されませんでした。 remoteCommandソリューションを使用すると、正常に動作します。 –

5

のソリューションのどれもあなたのために働いていない場合は、これが私のために

<p:dataTable ... id="theId" widgetVar="theWidget" ...> 
       <p:ajax event="rowEdit" listener="#{...}" 
         oncomplete="PF('theWidget').filter()"/> 
.... 

を働いていた私は、任意の方法、完全なAJAXにPFウィジェット上でフィルタメソッドを呼んでいる:私の問題を回避するには、以下の通りですそれはテーブルの "リロード"が機能するはずですが、私のテーブルはカラムフィルターを持っていたのでフィルターを使用しました。

関連する問題