2017-10-13 7 views
1

Je sais que je dois utiliser grid.getDataProvider() pour obtenir le ListDataProvider (en supposant que j'ai envoyé un List à grid.setItems()). Dans d'autres pour calculer le total de bas de page que je fais:Comment calculer le total dans un pied de grille Vaadin 8 avec le filtrage

Collection myItems = ((ListDataProvider)grid.getDataProvider()).getItems(); 
for(MyItem myItem : myItems) 
    total += myItem.getValue(); 
footer.getCell(footerCell).setText(format(total)); 

Mais cela ne fonctionne pas si j'ajoute un pied de page, car il calcule sur tous les éléments de ma grille. Ainsi, par exemple si j'ajoute:

((ListDataProvider)grid.getDataProvider()).addFilter(myFilter); 

Le code en haut échoue depuis le pied de page n'est pas le total filtré, mais le total complet de la grille.

Cela dit someone suggested I use:

grid.getDataCommunicator().fetchItemsWithRange(...); 

Cependant ceci est une méthode protégée. En supposant que je crée ma propre sous-classe, je ne comprends même pas comment cette méthode fonctionne.

Mais même alors, cela semble trop complexe et quelque chose qui devrait être simple, surtout s'il y a une possibilité d'ajouter un filtrage dans les grilles.

Par conséquent, ma grande question est comment puis-je calculer le total du pied de page dans une grille Vaadin 8 si je filtre la grille?

Répondre

2

Pour recalculer le total, vous pouvez utiliser un DataProviderListener qui est déclenché lorsque le filtre change. Dans sa mise en œuvre, vous pouvez les éléments de DataProvider avec un Query, car la méthode de récupération prend également en compte le filtre que vous avez défini.

L'exemple ci-dessous est principalement basé sur le Vaadin grid sampler et l'idée est d'afficher une liste de citations mensuelles et leur total. Le filtre vous permettra de voir les données à partir d'un certain mois (il est idiot, mais il vous permet de démarrer):

import com.vaadin.data.provider.ListDataProvider; 
import com.vaadin.data.provider.Query; 
import com.vaadin.ui.ComboBox; 
import com.vaadin.ui.Grid; 
import com.vaadin.ui.VerticalLayout; 
import com.vaadin.ui.components.grid.FooterRow; 
import com.vaadin.ui.components.grid.HeaderRow; 
import com.vaadin.ui.themes.ValoTheme; 

import java.util.List; 
import java.util.Random; 
import java.util.stream.Collectors; 
import java.util.stream.IntStream; 

public class FilteredGrid extends VerticalLayout { 
    public FilteredGrid() { 
     // list data provider with some random data 
     Random random = new Random(); 
     List<Quote> quotes = IntStream.range(1, 11).mapToObj(month -> new Quote(month, random.nextInt(10))).collect(Collectors.toList()); 
     ListDataProvider<Quote> provider = new ListDataProvider<>(quotes); 

     // month number filter combo 
     ComboBox<Integer> monthFilterCombo = new ComboBox<>("Starting with", IntStream.range(1, 10).boxed().collect(Collectors.toList())); 
     monthFilterCombo.setEmptySelectionCaption("All"); 
     monthFilterCombo.addStyleName(ValoTheme.COMBOBOX_SMALL); 
     monthFilterCombo.addValueChangeListener(event -> { 
      if (event.getValue() == null) { 
       provider.clearFilters(); 
      } else { 
       provider.setFilter(quote -> quote.getMonth() > event.getValue()); 
      } 
     }); 

     // grid setup 
     Grid<Quote> grid = new Grid<>(Quote.class); 
     grid.setDataProvider(provider); 

     // header and footer 
     HeaderRow header = grid.appendHeaderRow(); 
     header.getCell("month").setComponent(monthFilterCombo); 
     FooterRow footer = grid.prependFooterRow(); 
     footer.getCell("month").setHtml("<b>Total:</b>"); 
     provider.addDataProviderListener(event -> footer.getCell("value").setHtml(calculateTotal(provider))); 

     // add grid to UI 
     setSizeFull(); 
     grid.setSizeFull(); 
     addComponent(grid); 

     // trigger initial calculation 
     provider.refreshAll(); 
    } 

    // calculate the total of the filtered data 
    private String calculateTotal(ListDataProvider<Quote> provider) { 
     return "<b>" + String.valueOf(provider.fetch(new Query<>()).mapToInt(Quote::getValue).sum()) + "</b>"; 
    } 

    // basic bean for easy binding 
    public class Quote { 
     private int month; 
     private int value; 

     public Quote(int month, int value) { 
      this.month = month; 
      this.value = value; 
     } 

     public int getMonth() { 
      return month; 
     } 

     public void setMonth(int month) { 
      this.month = month; 
     } 

     public int getValue() { 
      return value; 
     } 

     public void setValue(int value) { 
      this.value = value; 
     } 
    } 
} 

Résultat:

Vaadin filtered Grid

+0

Merci. La partie clé qui me manquait était la possibilité de faire une nouvelle requête <>(). Je n'avais aucune idée que tu pouvais faire ça. J'ai supposé que si ce n'était pas nécessaire, ce ne serait pas un paramètre et quelque chose comme une requête vide serait créé pour vous par défaut dans l'API. En tout cas merci, ça a fonctionné parfaitement !! –