2

PrimeFaces は、p:dataTable に対して非常によくできたフィルターを備えています。フィルター フィールドは列ヘッダーにあるので、UX サイトからは素晴らしいです。フィルター フィールドが何をフィルター処理しているかは疑いなく、ライブで機能しています。私の意見はユーザーが期待するものとまったく同じです)。

ここで、フィルターとして機能するカスタムをヘッダーに配置したいと思います。したがって、私の考えは、ヘッダー ファセットにコンポーネントを配置することでした。

<p:column ...>
  <f:facet name="header">
     <some:myComponent onkeydown="filterAction()"/>
  </f:facet>
</p:column>

問題は、filterActiondataTable コンポーネント全体を更新してはならず (ユーザーが入力しているコンポーネントが再作成されるため)、テーブル本体を更新する必要があることです。

私はPrimeFaces セレクター(jQuery セレクターに基づく) でそれを行うことができると思っていましたが、トピックによるとdataTable のセレクターのみを使用してデータ行を更新する方法は? それは不可能。また、datatable.js には、それを実現するための特殊な Ajax 呼び出しが含まれています (行: PrimeFaces 3.5 リリースの 839):

    options.onsuccess = function(responseXML) {
        var xmlDoc = $(responseXML.documentElement),
        updates = xmlDoc.find("update");
        ....
        $this.tbody.html(content);

私の質問は、PF 内部に深く入り込み、そのような特殊な AJAX ハンドラーを作成することなく、標準フィルターとまったく同じように、テーブル本体のみを更新するような個々のフィルター コンポーネントを使用することは可能ですか?

もちろん、dataTable の外側にフィルターを作成することは可能ですが、それよりも UX が低下します (現在、私のアプリケーションを使用している人々は、現在の設計が非常に気に入っています)。

4

2 に答える 2

3

を使用して、任意のコンポーネントを列ヘッダーに配置できますfacet。ただし、dataTable本体のリフレッシュのみを依頼することはできません。したがって、解決策は、通常のリクエストを送信することですが、レスポンスを引き継いでカスタムコード部分で処理することです。

そのように remoteCommand を作成する場合:

<p:remoteCommand id="refreshDataTable" name="refreshDataTable"
               actionListener="#{carTable.doFilter}" 
               update="dataTable" />

そのコマンドの ID がサーバーに送信されます。それがわかれば、カスタム AJAX リクエストを準備できます。

 var options = {
        source: 'main:tabView:refreshDataTable',
        update: carsTable.id,
        formId: carsTable.cfg.formId
}
options.onsuccess = customHandler
PrimeFaces.ajax.AjaxRequest(options);

customHandler コードは次のようになります。

var xml = $(resp.documentElement)
updates = xml.find('update')
for(var i=0; i < updates.length; i++) {
var update = updates.eq(i),
id = update.attr('id'),
content = update.text();
if(id == carsTable.id){
   var tbody = $(content).find('tbody')
   carsTable.tbody.html(tbody.html());
}
else {
   PrimeFaces.ajax.AjaxUtils.updateElement.call(this, id, content);
}
PrimeFaces.ajax.AjaxUtils.handleResponse.call(this, xml);
var paginator = carsTable.getPaginator();
if(paginator) {
    paginator.setTotalRecords(this.args.totalRecords);
}
if(carsTables.cfg.scrollable) {
    carsTable.alignScrollBody();
}
return true;

Java コードで変数 totalRecords を設定する必要があります。

    RequestContext context = RequestContext.getCurrentInstance();  
    context.addCallbackParam("totalRecords", filteredCars.size());  
于 2013-07-26T17:52:45.190 に答える
1

Primefaces 5 には、Java コードでカスタム フィルタを定義できる新しい属性 filterFunction があります: http://blog.primefaces.org/?p=3084

ただし、フィルター入力は依然として入力テキストの文字列です。

フィルター値を入力するためのカスタム コンポーネントが必要な場合、または Primefaces 4 に行き詰まっている場合 (私は最近のプロジェクトに参加しているため)、何がうまくいったかを説明します。

これらの重要な手順を使用してフィルタリング動作を拡張しました

  • filterBy 属性を使用する代わりに、通常の JSF 入力コンポーネントを列のヘッダー ファセットに配置します。
  • ユーザー入力でトリガーされるこのコンポーネントに JavaScript コールバックをアタッチし、PF('dataTableWidgetVar').filter() を呼び出します。
  • filteredValue 属性を dataTable に追加します。これにより、Java セッターのカスタム フィルターが既存のフィルターの上に適用されます。

重要なことは、filteredValue 属性を利用することです。Primefaces filter() 関数が呼び出されるか、primefaces フィルターが変更されると、filteredValue がフィルター処理された値 (フィルターが適用されていない場合は null) をリストするように設定されます。次に、Primefaces は、filteredValues を getter から読み込んで、dataTable 内のアイテムのリストを更新します。これらの呼び出しの間にフィルターを配置すると (getter または setter のいずれかで、フィルターが変更された場合にのみ呼び出されるため、setter の方が効率的です)、元のフィルター処理されたリストをフィルターで変更し、getter を介して返します。

いくつかのコード:

フィルタ コンポーネントとして inputText を使用したデータ テーブルの定義:

<p:dataTable filteredValue="#{view.filteredResults} >
    ...
    <p:columnGroup type="header">
    ...
        <p:row>
    ...
           <p:column>
               <f:facet name="header">
                    <p:inputText value="#{view.filterValue}" />
                </f:facet>
           </p:column>

    ...
</p:dataTable>

view という名前のビューでのfilteredResultsのJava SetterおよびGetter:

public void setFilteredResults(List<?> filteredResults) {
    this.filteredResults = applyPremiumFilters(filteredResults, filterValue);
}

public List<?> getFilteredResults() {
    return this.filteredResults;
}

残りは、フィルター コンポーネントの値が変更されたときに dataTable にフィルターを適用する Javascript コードです。

于 2014-07-09T14:12:15.373 に答える