alejandro-du / crudui Goto Github PK
View Code? Open in Web Editor NEWAutomatically generate CRUD-like Vaadin views for any Java Bean
Home Page: https://vaadin.com/directory#!addon/crud-ui-add-on
License: Apache License 2.0
Automatically generate CRUD-like Vaadin views for any Java Bean
Home Page: https://vaadin.com/directory#!addon/crud-ui-add-on
License: Apache License 2.0
When you have an JPA entity with a unique constraint and type in an already in use value, the whole form closes before an error pop up is shown. This way you lose all you typed in data.
Instead it is better when the form remains, so you do not need to reenter all of your data again.
Caused by: java.io.IOException: Unable to create directory /Users/alejandro/git/crudui/target/frontend
Did not change anything other than pom.xml when updating from 3.9.0, which works fine, to 4.0.0.
Hello.Your crudui is nice but I can't to use Collection in fields
grails=3.2.9
gorm=6.0.12.RELEASE
also ( vaadin-server 7.7.6 and 8.1.4, vaadin-compatibility,vaadin-client-compiled)
once I add the plugin to the dependency it gives me this error.
General error during conversion: java.lang.NoClassDefFoundError: com/vaadin/ui/Composite
The buttons caption need to support I18N, and also error messages.
I can help on this.
getGrid().addItemDoubleClickListener
(
item
->
{
// why should I have to test this ? double click should always contain
// doubled-clicked row in selection
if( item.getSource().getSelectedItems().iterator().hasNext() )
{
// do action on selected row
Below is a sample exception occuring when instaciating with constructor GridCrud(Class domainType, CrudLayout crudLayout)
Caused by: java.lang.NoSuchMethodError: com.vaadin.ui.Grid.asSingleSelect()Lcom/vaadin/ui/SingleSelect;
at org.vaadin.crudui.crud.impl.GridCrud.updateButtons(GridCrud.java:128)
at org.vaadin.crudui.crud.impl.GridCrud.initLayout(GridCrud.java:89)
at org.vaadin.crudui.crud.impl.GridCrud.<init>(GridCrud.java:60)
at org.vaadin.crudui.crud.impl.GridCrud.<init>(GridCrud.java:43)
I have a custom cross-field validator @StartEndDate
which checks if the end date is chronologically after the start date. The annotation has @Target
as ElementType.TYPE
.
I have setUseBeanValidation(true)
on my CrudFormFactory
but this validation doesn't even gets triggered.
I have tested different types of @Target
and found out that, somehow, in crud ui, annotation that have @Target({ElementType.FIELD})
only work. I need a cross-field validation functionality in my use case. Is there a way to do so?
Please help.
In version 3.7, there are extra scrollbars that appear when a toolbar is present because the grid is set to the full size of the parent, and so there is not enough room for the toolbar and the grid.
The fix is simple -- in WindowsBasedCrudLayout(), replace mainComponentLayoutsetSizeFull()
with setWidth("100%"). The setExpand() a few lines below will do the rest (using all the vertical space)
mainComponentLayout.setWidth("100%");
mainComponentLayout.setMargin(false);
mainComponentLayout.setPadding(false);
mainLayout.add(mainComponentLayout);
mainLayout.expand(mainComponentLayout);
The first Field in any form should get the focus so that users can start introducing data right away.
java.lang.IllegalArgumentException: Given item id (com.example.admin.Company@7a5d1808) does not exist in the container
at com.vaadin.ui.Grid$AbstractSelectionModel.checkItemIdExists(Grid.java:1371) ~[vaadin-server-7.7.3.jar:7.7.3]
at com.vaadin.ui.Grid$SingleSelectionModel.select(Grid.java:1460) ~[vaadin-server-7.7.3.jar:7.7.3]
at com.vaadin.ui.Grid$SingleSelectionModel.select(Grid.java:1452) ~[vaadin-server-7.7.3.jar:7.7.3]
at com.vaadin.ui.Grid.select(Grid.java:5714) ~[vaadin-server-7.7.3.jar:7.7.3]
at org.vaadin.crudui.crud.impl.GridBasedCrudComponent.lambda$addButtonClicked$1(GridBasedCrudComponent.java:137)
Could you add the following method to the GridCrud class?
public boolean isEmpty() {
return CollectionUtils.isEmpty(items);
}
It will be very usefull method to do some logic if grid is empty.
I have a similar problem to this one: [https://vaadin.com/forum/#!/thread/571301/571300]
the grid works as expected, the form is shown as expected, but when I do click on Update/Add Button I receive the "com.vaadin.data.util.MethodProperty$MethodException" doing invokeSetMethod
UserAccount->Person and doing getPerson() on the instance it returns null. What maybe I'm doing wrong here?
Hello.I have problem.I can't update GRID with composite key if I change part of this key or all parts.It don't change.I see that to DB sending old composite key.
What I must to do?DELETE,READ is working
`
crud.getGrid().setColumns("title", "weaponInfo", "effectInfo", "chance");
List<WeaponInfo> listItemsWeapon = weaponInfoRepo.readAll();
formFactory.setFieldProvider("weaponInfo", new ComboBoxProvider<>("WeaponInfo", listItemsWeapon));
List<EffectInfo> listItemsEffect = effectInfoRepo.readAll();
formFactory.setFieldProvider("effectInfo", new ComboBoxProvider<>("EffectInfo", listItemsEffect));
public class WeaponInfoEffectAppliance {
@EmbeddedId
private EffectWeaponKey id = new EffectWeaponKey();
@Column(name = "TITLE", unique = true)
@NotNull
private String title;
@ManyToOne
@NotNull
@MapsId("weaponInfoId")
private WeaponInfo weaponInfo;
@ManyToOne
@NotNull
@MapsId("effectInfoId")
private EffectInfo effectInfo;
@NotNull
@Column(name = "CHANCE")
@Min(value = 0, message = "The value must be positive")
private Double chance;
public WeaponInfoEffectAppliance() {
super();
}
public WeaponInfoEffectAppliance(@NotNull String title) {
super();
this.title = title;
}
public EffectWeaponKey getId() {
return id;
}
public void setId(EffectWeaponKey id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public WeaponInfo getWeaponInfo() {
return weaponInfo;
}
public void setWeaponInfo(WeaponInfo weaponInfo) {
this.weaponInfo = weaponInfo;
}
public EffectInfo getEffectInfo() {
return effectInfo;
}
public void setEffectInfo(EffectInfo effectInfo) {
this.effectInfo = effectInfo;
}
public Double getChance() {
return chance;
}
public void setChance(Double chance) {
this.chance = chance;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((chance == null) ? 0 : chance.hashCode());
result = prime * result + ((effectInfo == null) ? 0 : effectInfo.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((title == null) ? 0 : title.hashCode());
result = prime * result + ((weaponInfo == null) ? 0 : weaponInfo.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
WeaponInfoEffectAppliance other = (WeaponInfoEffectAppliance) obj;
if (chance == null) {
if (other.chance != null)
return false;
} else if (!chance.equals(other.chance))
return false;
if (effectInfo == null) {
if (other.effectInfo != null)
return false;
} else if (!effectInfo.equals(other.effectInfo))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
if (weaponInfo == null) {
if (other.weaponInfo != null)
return false;
} else if (!weaponInfo.equals(other.weaponInfo))
return false;
return true;
}
@Override
public String toString() {
return "(" + title + ")";
}
}
`
Will need this: vaadin/framework#10040
Hello!
I have following code, but with converter field showing error "Must be a number", not "Own custom error text"
// crud instance
GridCrud<ExchangeRate> crud = new GridCrud<>(ExchangeRate.class);
...
// form configuration
DefaultCrudFormFactory<ExchangeRate> formFactory = (DefaultCrudFormFactory<ExchangeRate>) crud
.getCrudFormFactory();
...
// this code is not working
formFactory.setConverter("buyRate", new PriceConverter());
PriceConverter
public class PriceConverter implements Converter<String, BigDecimal> {
private final DecimalFormat df = FormattingUtils.getUiPriceFormatter();
@Override
public Result<BigDecimal> convertToModel(String presentationValue, ValueContext valueContext) {
try {
return Result.ok(new BigDecimal(presentationValue));
} catch (NumberFormatException e) {
return Result.error("Own custom error text");
}
}
@Override
public String convertToPresentation(BigDecimal modelValue, ValueContext valueContext) {
return convertIfNotNull(modelValue, i -> df.format(modelValue), () -> "");
}
}
GridCrud
seems to mostly work in Vaadin 12, but FieldProvider
s break.
For example, when using ComboBoxProvider
, the following error occurs when you click on edit or add button:
java.lang.ClassCastException:
com.vaadin.flow.component.combobox.ComboBox
cannot be cast to com.vaadin.flow.data.binder.HasDataProvider
at org.vaadin.crudui.form.impl.field.provider.AbstractListingProvider
.buildField(AbstractListingProvider.java:42) ~[crudui-3.6.0.jar:3.6.0]
This is reproducible with TestUI
.
See #11 (comment)
Thanks for your work.
When i add a number property, only show 3 decimals in form factory.
Can u add support to new Fields?
https://vaadin.com/components/vaadin-text-field/java-examples/number-field
Thanks you very much!
There is no option to change the alert message on delete operation, "Are you sure you want to delete this item?" as in the case of the rest of messages.
Would it be possible to access this message to update it?
By either implementing a new Crud
or adding support to existing ones.
Thanks for GridCrud
, it is really useful and the API is elegant!
Version 2.3.0 worked very well in a library management app prototype that I created with Vaadin 8, but version 3.6.0 displays an empty grid with similar code in a Spring Boot project with Vaadin 10.
Here's the screenshot that shows that grid contains 5 items (I clicked on refresh to trigger the notification) but does not display them;
Here's the relevant snippet:
@Route
public class MainView extends VerticalLayout {
private Repository<Book> bookRepository;
@Autowired
public MainView(DataPopulator dataPopulator, Repository<Book> bookRepository) {
this.bookRepository = bookRepository;
dataPopulator.fillDatabase();
add(createBookGridCrud());
}
private GridCrud<Book> createBookGridCrud() {
final GridCrud<Book> crud = new GridCrud<>(Book.class);
crud.setFindAllOperation(bookRepository::findAll);
crud.setAddOperation(bookRepository::add);
crud.setUpdateOperation(bookRepository::update);
crud.setDeleteOperation(bookRepository::delete);
// I also tried with crud.setSizeFull(); to no avail
return crud;
}
}
The full project is here:
https://gitlab.com/library-manager/library-manager-admin-vaadin/
Any idea why the grid stays empty?
Hi Alejandro,
refreshGrid() will throw NullPointerException if the spring boot JPA nativeQuery result is null.
gridCrud.setFindAllOperation(() -> service.findAllByCreatedBetween(
fromDatePicker.getValue(),
toDatePicker.getValue()));
gridCrud.refreshGrid();
java.lang.NullPointerException: Cannot provide an id for a null item.
at java.util.Objects.requireNonNull(Objects.java:228)
at com.vaadin.flow.data.provider.DataProvider.getId(DataProvider.java:132)
at com.vaadin.flow.data.provider.KeyMapper.has(KeyMapper.java:105)
at com.vaadin.flow.data.provider.DataCommunicator.lambda$activate$5(DataCommunicator.java:639)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.util.stream.ReferencePipeline$11$1.accept(ReferencePipeline.java:373)
at java.util.stream.SliceOps$1$1.accept(SliceOps.java:204)
at java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1359)
at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
Hello,
This may be an improvement, the current crudui component throws an Exception if the getter is not set to getBoolean. So if you set a getter with isBoolean an Exception is thrown.
It would be better if both getter worked.
Thanks
Currently it is impossible to do
crud.setCrudListener(new LazyCrudListener<TeamTreeItem>() {
@Override
public DataProvider<TeamTreeItem, Void> getDataProvider() {
return new TreeDataProvider<TeamTreeItem>(tbd);
}
because of the Void generic.
Alternately, supporting the TreeGrid setItems method with the parent/child relationship would work.
Example:
crud.getCrudFormFactory().addProperty(String.class, User::getName, User::setName);
Make it possible to modify the strings shown in the UI and the styles used for the components in all CrudComponent implementations.
I think it'd be a good idea to add a method to set a Converter
for a specific field. This would allow converting price fields using a "currency converter", for example.
Make the UI adaptable to different screen sizes.
Here is a minimal setup to recreate a strange interaction that only happens with crudui (and not with a normal grid). Since app-layout is likely what many people will be using ...
Steps to reproduce
•Clone https://github.com/jflamy/bug_crud.git
•Run mvn exec:java (or start org.ledocte.owlcms.Main from IDE)
•Click on the "Test" button -- observe there is no error message
•Refresh the page (navigating directly to the URL)
•Observe that there is an error message (cannot read property 'map' of null)
Column should be re-sizable using mouse
Add keyboard shortcuts for CRUD actions and form buttons.
This needs to be in place before moving to stable
release.
Nowaday, JPA is usually used to manage entity, and a BeanBinder that support JPA annotation could be very useful.
It could set a maxLenth on textField, or required field.
I can help on this.
The interface LazyFindAllCrudOperationListene
r requires DataProvider<T, Void>
on its getDataProvider()
which prevents other implementations which does not use Void as a filter on the second generic. This could be resolved by making the interface be as:
public interface LazyFindAllCrudOperationListener<T> extends FindAllCrudOperationListener<T> {
DataProvider<T, ?> getDataProvider();
}
Vaadin grid method for setting DataProvider requires DataProvider<T, ?> which I assume with the implementation above it will still work.
Hi Alejandro, as an idea, it would be nice, to add a possibility to externelize notifications, or to overide them.
Steps to reproduce:
now both the old item and the newly clicked are selected in the grid. The old item can't be selected anymore to update its value.
The same problem occurs if at step 4 you click "update" but an Exception occurs (i.e. a duplicate key saving to database).
Tested with version 2.1.1
I found an issue with the following case. I use crud.setFindAllOperation to pass a collection of objects to the crud grid. Then I add a new item to the collection on the server side (not using Crud functionality). I expect that grid will be automatically refreshed and a new row will be added. Current Crud implementation breaks this case. Setting items to the grid in refreshGrid method (grid.setItems(items);) breaks automatic refresh of the grid by Vaadin NotificationListeners. I suggest to rewrite attach and refreshGrid methods in the following way:
@Override
public void attach() {
super.attach();
items = findAllOperation.findAll();
grid.setItems(items);
}
public void refreshGrid()
{
grid.getDataProvider().refreshAll();
}
I have a spring-boot program (version 1.5.2) and have added an UI
`
package com.example;
import com.vaadin.server.VaadinRequest;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.UI;
import org.vaadin.crudui.crud.impl.GridBasedCrudComponent;
import java.util.Arrays;
import java.util.List;
@SpringComponent
@springui(path = "/demo")
public class MyUI extends UI {
HorizontalLayout layout = new HorizontalLayout();
GridBasedCrudComponent<UserBean> crud = new GridBasedCrudComponent<>(UserBean.class);
@Override
protected void init(VaadinRequest request) {
crud.setFindAllOperation(() -> UserBean.getSome());
layout.addComponent(crud);
setContent(layout);
}
public static class UserBean {
private String givenName;
private String surName;
public UserBean(String givenName, String surName) {
this.givenName = givenName;
this.surName = surName;
}
public static List<UserBean> getSome() {
return Arrays.asList(
new UserBean("Tom","Hansen")
, new UserBean("Odd", "Jensen")
);
}
public String getGivenName() {
return givenName;
}
public void setGivenName(String givenName) {
this.givenName = givenName;
}
public String getSurName() {
return surName;
}
public void setSurName(String surName) {
this.surName = surName;
}
}
}
`
I think this is as minimalistic as can be. Values are not shown in the grid, though. On reload the notification shows that two rows are found. But the grid is just blank. Is this due to 2.1.0 not being released yet?
grid.setItems(items); in GridBasedCrudComponent do happen in the debugger, and items is of size 2 as expected, so it's a bit weird.
How I can use TextArea instead of TextFiled?
My Bean was using a "int" datatype but it seems like AbstractAutoGeneratedCrudFormFactory only supports "Integer"? Any reason?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.