Coder Social home page Coder Social logo

flowingcode / twincolgridaddon Goto Github PK

View Code? Open in Web Editor NEW
7.0 6.0 7.0 370 KB

TwinColGrid Vaadin Add-on

Home Page: https://www.flowingcode.com/en/open-source/

License: Apache License 2.0

Java 95.69% CSS 2.95% JavaScript 1.36%
vaadin vaadin-addon component grids field

twincolgridaddon's Introduction

Published on Vaadin Directory Stars on vaadin.com/directory Build Status

TwinColGrid Add-on for Vaadin

TwinColGrid Add-on is a UI component add-on for Vaadin Framework version 14+

Features

TwinColGrid is built upon the same idea of TwinColSelect component, but using grids instead of selects. It provides a multiple selection component that shows two grids side by side. Left grid contains unselected items and the right grid the selected items. The user can select items from the list on the left and click on the ">" button to move them to the list on the right. Items can be deselected by selecting them in the right list and clicking on the "<" button. Component also supports drag and drop between grids.

Online demo

Try the add-on demo at http://addonsv24.flowingcode.com/twincolgrid

Download release

Official releases are available at Vaadin Directory https://vaadin.com/directory/component/twincolgrid-add-on

Maven install

Add the following dependencies in your pom.xml file:

<dependency>
   <groupId>com.flowingcode.vaadin.addons</groupId>
   <artifactId>twincolgrid</artifactId>
   <version>X.Y.Z</version>
</dependency>
<repository>
   <id>vaadin-addons</id>
   <url>https://maven.vaadin.com/vaadin-addons</url>
</repository>

For SNAPSHOT versions see here.

Building and running demo

git clone https://github.com/FlowingCode/TwinColGrid
mvn clean install
mvn jetty:run

To see the demo, navigate to http://localhost:8080/

Release notes

  • Version 2.0.0 First release for Vaadin 14+ NPM mode. Several API improvements
  • Version 1.0.0 First release of the component. This version has dependencies that are not available in the public repositories.
  • Version 1.0.1 First stable release. Compatible with Vaadin 8.1/8.2.
  • Version 1.0.2 Compatible with Vaadin 8.3 and later. Support for Vaadin Designer. Read-only mode.

Roadmap

This component is developed as a hobby with no public roadmap or any guarantees of upcoming releases.

Issue tracking

The issues for this add-on are tracked on its github.com page. All bug reports and feature requests are appreciated.

Contributions

Contributions are welcome, but there are no guarantees that they are accepted as such.

As first step, please refer to our Development Conventions page to find information about Conventional Commits & Code Style requirements.

Then, follow these steps for creating a contribution:

  • Fork this project.
  • Create an issue to this project about the contribution (bug or feature) if there is no such issue about it already. Try to keep the scope minimal.
  • Develop and test the fix or functionality carefully. Only include minimum amount of code needed to fix the issue.
  • For commit message, use Conventional Commits to describe your change.
  • Send a pull request for the original project.
  • Comment on the original issue that you have implemented a fix for it.

License & Author

This add-on is distributed under Apache License 2.0. For license terms, see LICENSE.txt.

TwinColGrid Add-on is written by Flowing Code S.A.

twincolgridaddon's People

Contributors

dependabot[bot] avatar federicoquarin avatar flang avatar flowingcodeci avatar hy8246 avatar javier-godoy avatar jcgueriaud1 avatar mlopezfc avatar ngonzalezpazfc avatar paodb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

twincolgridaddon's Issues

Drag&Drop error

Vaadin 8.4.3
Java 1.8
Tomcat 8.5

Trying D&D I got error just moving mouse selection over left grid:

java.lang.NoSuchMethodError: com.vaadin.ui.components.grid.GridDragStartEvent.getDraggedItems()Ljava/util/Set;
	at com.flowingcode.vaadin.addons.twincolgrid.TwinColGrid.lambda$configDragAndDrop$7624f3f1$1(TwinColGrid.java:319)

get/set value of component handle Set, but method in trace handle List.

Allow re-ordering of the right side

Often, we provide a list of columns to choose from for subset data display. Having chosen the appropriate columns, the client wants to then change the order with drag and drop in the 'selected' side.

Possible?

Component refactoring

In #6 we made the internal grids protected instead of private, so that they can be configured by extending the component (they were not made public in order to conceal the data provider from the public API, however increasing their visibility is still an option).

Since grids are not public, feature #9 required adding SIX methods to the public API (three for left-delegation and three for right-delegation):

  • setLeftGridClassName / setRightGridClassName that delegate on left/right setClassName
  • addLeftGridClassName / addRightGridClassName that delegate on left/right addClassName
  • removeLeftGridClassName / removeRightGridClassName that delegate on left/right removeClassName

This (anti)pattern was not noticeable when there was only a single pair of withLeftColumnCaption / withRightColumnCaption methods, but the evolution of the component seems to be guided by chirality. #25 attempts to address this ambidextrous code duplication on the component internals, but the public API still suffers from it.

On the other hand (pun intended) addColumn is cool-fluent, thus #8 had to introduce addSortableColumn(Book::getIsbn, comparing(Book::getIsbn), "ISBN") when addColumn(Book::getIsbn, "ISBN").setComparator(comparing(Book::getIsbn)) would have sufficed. There are still many other settings such as classNameGenerator. resizable, flexGrow and key, that cannot be configured through public API.

Latest PR #33 exposes this situation up to the point where a refactoring has to be considered.

Any thoughts?

Consider the possibility of using a TreeGrid instead of Grid

A user mentioned in the directory about the possibility of using a TreeGrid instead of a Grid.
I think that there are three different ways of using a TreeGrid:

  1. As a replacement for the left grid: In this case it would be like a better way of "classifying" the items that can be added to the collection. So instead of having a filtered grid, we could organize the available items in branches of the tree, so we could handle a lot of items in a better way. This is the simpler choice, given that we would still create a list of selected items.
  2. As a replacement for both grids, but "respecting" the hierarchy. That means that if we add a node from the left, it would create all of the parents in the right grid. This is a more difficult strategy, because instead of a List we would produce a Tree. But at least the handling of the items would be not so difficult because the produced tree would be a stripped down version of the left tree.
  3. As a replacement for both grid, but allowing to create a different tree in the right. This would be the more difficult strategy because it would allow to create a complete different tree.

Move items by doubleclick or similar

This comes from directory question by Michael Thome

"Is there a straightforward way to enable a doubleclick (or similar) event to immediately move an item to the other column?"

Assigning column key.

public TwinColGrid addSortableColumn(
final ItemLabelGenerator itemLabelGenerator,
Comparator comparator,
final String header,
final String key)

assign the a column key, however

public TwinColGrid addSortableColumn(
final ItemLabelGenerator itemLabelGenerator,
Comparator comparator,
final String header)

public TwinColGrid addFilterableColumn(
final ItemLabelGenerator itemLabelGenerator,
SerializableFunction<T, String> filterableValue,
final String header,
String filterPlaceholder,
boolean enableClearButton)

public TwinColGrid addFilterableColumn(
final ItemLabelGenerator itemLabelGenerator,
final String header,
String filterPlaceholder,
boolean enableClearButton)

does not.

Refactor the component layout

Over the years, we have been stacking assumptions on how the component should look, while adding new features and migrating from Vaadin 8. In consequence:

  • The component inherits from VerticalLayout
  • There are three nested horizontal/vertical layouts (not even divs, but actual Flow components)
  • It's not clear which part of the layout is public API (which reduces room for non-breaking refactoring)
  • There is no clear API for styling

This change should be addressed in a major release.

Problem with sorting

In a thread from Vaadin Directory, Mohan wrote:

I'm trying to add a sortableColumn. But the columns are not getting sorted at all.

Below is my code:

List<Student> studentList = getDataFromBackend();

TwinColGrid<Student> studentTwinColGrp = new TwinColGrid<Student>()
	.addSortableColumn(Student::getName, Comparator.comparing(Student::getName), "Student Name")
	.withoutAddAllButton();

studentTwinColGrp.setItems(studentList);

Student Class looks like below:

public class Student implements Serializable {
	private static final long serialVersionUID = 1L;
	private String name;
	.............
	// getters-setters
	.............
}

I'm using 2.0.3 version of twincolgrid

<dependency>
			<groupId>com.flowingcode.vaadin.addons</groupId>
			<artifactId>twincolgrid</artifactId>
			<version>2.0.3</version>
</dependency>

Is there anyway I can make the columns sortable?

Screenshot attached for reference.

Further efforts: tried with Comparator.comparing(s -> s.getName()) - didn't work

At the same time I've tried to check if ArrayList is actually getting sorted, I've tried

Collections.sort(studentList, Comparator.comparing(Student::getName));

The above method actually sorts the list, so no problem in comparator or class definition,

Provide an option for selecting items on row clicking

In order to make it more similar to a regular list component, it would be nice to be able to select each item by clicking on a row. It would be great to enable / disable this feature, and by enabling it, disabling the checkboxes.

Add support for HasValue.clear() method

This comes from a directory comment by Paul Corbett:

"Nice effort, however, the component does not support the HasValue.clear() method. This causes a NullPointerException when the component is incorporated in an instance of type Binder and the setBean method is called with a parameter of null to clear out the fields. This makes this component unusable in our project, very disappointing."

Clear throws NPE

As discussed in #16

clear() DOES throw an exception (as of 2.0.4-SNAPSHOT) because it's implemented as setValue(getEmptyValue()) and getEmptyValue() returns null.

	at java.base/java.util.Objects.requireNonNull(Objects.java:221)
	at com.flowingcode.vaadin.addons.twincolgrid.TwinColGrid.setValue(TwinColGrid.java:343)
	at com.flowingcode.vaadin.addons.twincolgrid.TwinColGrid.setValue(TwinColGrid.java:1)
	at com.vaadin.flow.component.HasValue.clear(HasValue.java:179)

It should be documented that setValue does not allow null.
https://github.com/vaadin/flow/blob/907cbbd59612ac2e31daf5c1566fb48529d75200/flow-server/src/main/java/com/vaadin/flow/component/HasValue.java#L100-L102

Clear all values on the right grid and reset the left grid

is there a way to clear all filters of a TwinColGrid? After moving some of the items over to the right grid, there is no method to programmatically clear all the values of the right grid and reset the left grid with the original list.

Problem in readonly mode

Setting twinColGrid to isReadOnly(false) results in 2 Checkboxes inside Items Column and Selected Column.

Screenshot:

Screenshot

Caption is not configurable

Caption is not configurable. In order to set a caption, one have to use the constructors that receive a caption:

TwinColGrid(ListDataProvider<T>, String)
TwinColGrid(Collection<T>, String);

If a caption is not wanted, one can pass caption = null to those constructors, or call the other constructors that don't receive a caption.

TwinColGrid()
TwinColGrid(Collection<T>);

In any case, the caption cannot be added, removed, or modified afterwards.

In addition, if we have setCaption we could consider deprecating

TwinColGrid(ListDataProvider<T>, String) and TwinColGrid(Collection<T>, String) in favor of TwinColGrid() and TwinColGrid(Collection<T>) plus setCaption.

Add support for vertical orientation of grids

I need to replicate a view where I can use this addon, but I need the grids to be one on top of the other, with the button icons pointing towards them, up and down. For example:
image

Also, this layout could be applied if the width of the view is not greater than X pixels, making the addon responsive. Now the grids are shown squashed:
image

idea: extend selection semantics to support ordered value along with UI to adjust

One use case we have is to select data columns for export. Users would like to not only choose which data columns to export but the order in which they are exported.

TwinColGrid implements HasValue<ValueChangeEvent<Set<T>>, Set<T>> but perhaps it could either provide a secondary List<T> result option or have a base implementation like
<T, C extends Collection<T>> implements HasValue<ValueChangeEvent<C>, C> and then both a Set and List option.

Move all buttons ignore applied filters

This comes from directory:

I think the default semantics of ">>" and "<<" should be that only filtered items should be moved. My users find it surprising when >> ignores applied filters.

e.g. if I have a set {Apple, Banana, Celery} and filter by "n", not only should only Banana be visible on the left, but only Banana should be moved to the right on ">>".

Left Grid Data Does Not Update

I just noticed this today that when I remove items from the right grid dataprovider, the left grid dataprovider does not update (refresh issue?). Right to left works fine, left to right does not.

Thanks.

Doesn't support readonly

Vaadin 8.4.3
Java 1.8
Tomcat 8.5

I tryed to bind your component with Binder that can be setted to readOnly. I got this exception:

java.lang.IllegalStateException: This component does not support the read-only mode, since state is of type CustomComponentState and does not inherit AbstractFieldState
	at com.vaadin.ui.AbstractComponent.setReadOnly(AbstractComponent.java:1083)
	at com.flowingcode.vaadin.addons.twincolgrid.TwinColGrid.setReadOnly(TwinColGrid.java:287)
	at com.vaadin.data.Binder$BindingImpl.setReadOnly(Binder.java:1219)

Expose more Grid configuration

This component is especially helpful when selecting from a large list of items with discrete attributes. It would be even better if the left grid was exposed in such a way that we could easily add a header row for filter controls, to allow users to filter items by relevant values. I'd be happy with a standard text filter per column, but allowing customizing would be nice.

Since the grids are final and private, I would have to modify the source or modify the class at runtime to get at the grid to call addHeaderRow().

Avoid code duplication

Several features require applying similar configuration to both the left grid and the right grid. However, in some cases it's hard to reuse the code in its current form, since all the relevant private attributes come in left/right pairs.

Deprecate the constructor that receives a ListDataProvider and caption

The constructor is TwinColGrid(ListDataProvider<T>, String caption) is redundant and can be replaced with a call to TwinColGrid(String caption) followed by setDataProvider(ListDataProvider<T>).

In addition, my proposal for #96 requires two new constructors

TwinColGrid(Grid<T> availableGrid, Grid<T> selectionGrid) 
TwinColGrid(Supplier<Grid<T>>) 

And two redundant overloads with caption (because of #97)

TwinColGrid(String caption, Grid<T> availableGrid, Grid<T> selectionGrid) 
TwinColGrid(String caption, Supplier<Grid<T>>) 

If instantiating TwinColGrid with a data provider is a feature we want to mantain, then #96 would require eight constructors instead of "only" four.

TwinColGrid(ListDataProvider<T>, Grid<T> availableGrid, Grid<T> selectionGrid) 
TwinColGrid(ListDataProvider<T>, Supplier<Grid<T>>) 
TwinColGrid(ListDataProvider<T>, String caption, Grid<T> availableGrid, Grid<T> selectionGrid) 
TwinColGrid(ListDataProvider<T>, String caption, Supplier<Grid<T>>) 

Therefore: deprecate TwinColGrid(ListDataProvider<T>, String caption)

Idea: option to supply a stable item sorter

I have a use case for keeping the items in both columns in a specified sorted order, but moving items from left to right appears to drop moved items at the end unless (manual) column sorting is on.

Dragged out items disappear

In a thread from Vaadin Directory, Rajeev wrote:

Incorporating in my application. Works great. Noticing an issue with the drag and drop feature. If the row selected from the source grid is dropped anywhere else other than on the target grid, the row disappears from the source grid. Expected behavior or a bug?

setValue does not clear the previous value but only add items

When I call setValue the old value is kept and concatenated, instead of being set like it should.
Is it intended?

For example if you have an entity bound and run setBean it will keep the old values.

Here is an example to reproduce the issue:


@PageTitle("Twin Col Grid")
@Route(value = "twincol", layout = MainLayout.class)
public class TwinColGridView extends VerticalLayout {

    private Button button;
    private TwinColGrid<String> twinColGrid = new TwinColGrid<>("TwinCol");

    private List<String> items = new ArrayList<>();

    public TwinColGridView() {
        for (int i = 0; i < 10; i++) {
            items.add("Item "+ i);
        }
        twinColGrid.addColumn(item -> item, "item");
        twinColGrid.setItems(items.stream());
        twinColGrid.setSizeFull();
        button = new Button("set Value");
        button.addClickListener(e -> {
            twinColGrid.setValue(Collections.singleton(items.stream().findFirst().get()));
        });

        add(twinColGrid, button);
        setSizeFull();
    }

}

Cannot set fixed height

In thread from Vaadin Directory, Veronica Orgaz wrote:

It works very well, but I'm getting a quick fix bug.
I'm trying to set the height of the component to 220px and isn't working.

Remove deprecated methods

After five years we managed to collect 19 deprecated methods (and 4 deprecated protected fields). Let's release a new major version without them.

Allow usage of custom grid

Currently the model uses an instance of GridEx, which seems not to add any additional functionality. We would like to use a SelectionGrid instead (or some other custom grid, which provides additional functionality).

To allow that, the simples solution would be to use the normal Grid instead of GridEx and add a "createGrid" method to the base class, which can be overridden by any subclass.

Something like this:

  public TwinColGrid(final ListDataProvider<T> dataProvider, String caption) {
    available = new TwinColModel<>(createGrid(true), "twincol-grid-available");
    selection = new TwinColModel<>(createGrid(false),"twincol-grid-selection");
    ...
  }

  protected Grid<T> createGrid(boolean available) {
     return new GridEx<>();
  }

    private static final class TwinColModel<T> implements Serializable {
      final Grid<T> grid;
      ...

      TwinColModel(String className, Grid<T> grid) {
         this.grid = grid;
      }

Add filtering feature

In a thread from Vaadin Directory, Mohan wrote:

I have more than 1k entries in twinColGrid, now searching a specific value inside is a tedious process. Is there any plan of including (eager) search as we find in MultiselectComboBox. Or is there anyway we can achieve this by which the search should show entry (either in unselected list / selected list)?

We should investigate if there is a way of making it easy to add filters for each grid so it's easier to search for items

Not visible on firefox

When I place twinColGrid inside FormLayout, it is not showing in firefox. Microsoft Edge, Chrome works fine.

image

Infinite Loop on set required indicator visible true

at com.flowingcode.vaadin.addons.twincolgrid.TwinColGrid.setRequiredIndicatorVisible(TwinColGrid.java:614) ~[twincolgrid-2.4.0.jar:2.4.0]

I think you are missing to call super.setRequiredIndicatorVisible(value) inside your override method setRequiredIndicatorVisible.

Problem when clearing selected items programatically

According to a comment in the discussions in the addon's Vaadin directory page:

Is there a way to clear the selected items programmatically. I tried with twinColGrid.setValue(null) which throws exception. Tried with twinColGrid.clear() which doesn't throw any exception, but doesn't clear the elements. I've also tried with twinColGrid.setValue(new HashSet<>()) which again, throws no exception, but doesn't clear

addFilterableColumn with resize

How to use an addFilterableColumn with resize?
The user needs to be able to increase the column, because sometimes the entire text does not fit.

Is there any way to put rezise as you have in the grids in all columns, whether with filter or not?

This addon is very good!

How to with designer?

Hello

your API provide available items set only by constructor.
How can I set them to component inserted by Vaadin Designer which control the object instantiation?

Implement responsive behavior

Once the feature described in #82 is implemented, the component should have a responsive behavior, by switching between horizontal and vertical layout, as needed.

Add public getters for left/right grids

As discussed in #34, the lack of public getters for the left and right grids requires the addon to provide a pair of setLeftGridFoo / setRightGridFoo that delegate on leftGrid.setFoo and rightGrid.setFoo, for every foo provided by Grid. Several feature requests are just about adding a new pair of such methods.

Why is the component final? It doesn't need to be.

It would be much nicer from an OO coding perspective to be able to subclass the component rather than create some sort of configurator visitor, for cases where we want similarly configured instances in multiple views.

From the code, I can't see any purpose for making it final.

Possibility to swap grids/sides

Can you please tell me if it is possible to forcibly swap the grids? While maintaining the logic of the migration buttons.
For example, to force a grid with selected items to the left instead of the right.

Support for selection based on row clicks

It would be great to support multi selection by clicking on rows instead of checkboxes as an alternative way of selecting items. Selecting by using keyboard and presing space would be also desirable.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.