My Attempt At Generating Row/Index Column to CrudUI

Hello Community!

keep in mind…THIS IS NON-PRODUCTION CODING
…just want to share how i finally added index to the grid

here’s what i’m doing: (specifically starting w/in the configureGrid method )

  1. Mapping crud-operations to functions provided by service
  2. Setting the grid-columns to match the fields of the member-table
  3. adding a new component ( type Span) to the grid - this will become the data that displays the grid’s row-number
  4. reordering the components ( doing it this way - currently is easiest for me … a long way for improvement )

but it’s w/in the addComponentColumn ( the SPAN ) where I stumbled on generating row numbers for the grid. the number displayed reflects the entries returned ( either from JPA’s findALL or from a custom filtered function ), not so much as the position the entry places w/in the member-table

in terms of how this would work for scaling/massive-data set…the jury is out. but hopefully this could get a start

import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.grid.ColumnTextAlign;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.PasswordField;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.data.selection.SelectionListener;
import com.vaadin.flow.data.value.ValueChangeMode;
import com.vaadin.flow.router.PreserveOnRefresh;
import net.esystems.apps.example.model.member.Member;
import net.esystems.apps.example.services.MemberService;
import org.vaadin.crudui.crud.CrudOperation;
import org.vaadin.crudui.crud.impl.GridCrud;

@PreserveOnRefresh
public class MembersTabView extends VerticalLayout {

    private final MemberService memberService;
    private final GridCrud<Member> memberGrid = new GridCrud<>(Member.class);


    private TextField getGridFilter() {
        TextField gridFilter = new TextField();
        gridFilter.setPlaceholder("Search....");
        gridFilter.setClearButtonVisible(true);
        gridFilter.setValueChangeMode(ValueChangeMode.LAZY);
        gridFilter.addValueChangeListener( event -> {
            memberGrid.getGrid().setItems( memberService.getFilteredResults( gridFilter.getValue().toLowerCase() ) );
            Notification.show(
              memberGrid.getGrid().getListDataView().getItemCount() + " items(s) found",
              5000,
              Notification.Position.BOTTOM_START
            );
                }
        );
        return gridFilter;
    }



     private void configureGrid() {
        memberGrid.setSizeFull();
        memberGrid.setHeightFull();
        memberGrid.setFindAllOperation(memberService::findAll);
        memberGrid.setAddOperation(memberService::save);
        memberGrid.setUpdateOperation(memberService::update);
        memberGrid.setDeleteOperation(memberService::delete);

        memberGrid.getGrid().setColumns( "name", "username", "email", "role" );

        memberGrid.getGrid().addComponentColumn(
                member -> {
                    return new Span(
                            String.valueOf(
                                    memberGrid.getGrid().getListDataView().getItemIndex(member).orElse(0) + 1
                            )
                    );
                }
        ).setHeader("#").setKey("Row Index").setAutoWidth(true);

        memberGrid.getGrid().setColumnOrder(
                memberGrid.getGrid().getColumnByKey("Row Index"),
                memberGrid.getGrid().getColumnByKey("name"),
                memberGrid.getGrid().getColumnByKey("username"),
                memberGrid.getGrid().getColumnByKey("email"),
                memberGrid.getGrid().getColumnByKey("role")
        );
     memberGrid.getGrid().getColumnByKey("Row Index").setFrozen(true);
        memberGrid.getGrid().getColumnByKey("Row Index").setSortable(false);
        memberGrid.getGrid().getColumnByKey("name").setFrozen(true);

here’s a screenshot of the grid listing all members ( all that fit w/in screen lenght )
note Catherine Black is #19 from the table ( JPA findALL ), but she’s #1 when I filtered for instances of black

Hi!

That sure isn’t the most efficien way to do it with large datasets. Better option would be to make your query/entity/dto contain that index.

I wonder if that kind of row index is a common need? There is a ticket about it, but not too much attention given to it. Workaround there suggests using something like this:

grid.addColumn(LitRenderer.of("${index +1}")).setHeader("#");

That uses the index (available on the client side column renderer) and render is there without additional logic on the server side.

Hi Matti,

Thanks for the feedback! I’m honestly not sure about the “common need” portion. In my case…I’m practicing/learning vaadin/coding as a hobbyist - I simply wanted to add the index functionality for personal visual aesthetics ( again…this isn’t production or anything )

I’ll try refactoring w/ your suggestion - wish me luck!

1 Like