Pietro15
(Pietro Ferraboschi)
May 29, 2019, 11:15am
1
I need to use a CustomField to group info about a tracking event (code of delivery as Delivered, Not Delivered, etc… + delivery datetime).
In the route where I put my component (in a grid, a component for every row) I add a change listener but I have two issue:
the listener only listen for the ComboBox changes;
after listen correctly the first change, the listener seems to stop itself and I couldn’t see the System.out output more.
I think the issue is linked to override changeListener, but I could not figure out how to resolve it.
Code in route.
...
grid.addColumn(new ComponentRenderer<TrackingCodeDateTime, Shipment>(item -> {
TrackingCodeDateTime field = new TrackingCodeDateTime(item.getTracking());
field.setWidthFull();
field.addValueChangeListener(event -> {
System.out.println(event.getValue());
});
return field;
})).setHeader("Delivery time");
...
CustomField code.
public class TrackingCodeDateTime extends CustomField<Tracking> {
private final Tracking tracking;
private final ComboBox<EventCode> eventCode;
private final DatePicker datePicker;
private final TimePicker timePicker;
public TrackingCodeDateTime(Tracking tracking) {
this.tracking = tracking;
eventCode = new ComboBox<>();
eventCode.setPlaceholder("Code");
eventCode.setRequired(true);
eventCode.setRequiredIndicatorVisible(true);
// eventCode.setAllowCustomValue(false);
eventCode.setWidth("14em");
datePicker = new DatePicker();
datePicker.setPlaceholder("Date");
datePicker.setRequired(true);
datePicker.setMin(minDate);
datePicker.setWidth("9em");
timePicker = new TimePicker();
timePicker.setPlaceholder("Time");
timePicker.setWidth("5em");
if (tracking != null) {
setPresentationValue(tracking);
}
FormLayout layout = new FormLayout();
layout.add(eventCode, datePicker, timePicker);
layout.setResponsiveSteps(new ResponsiveStep("14em", 1), new ResponsiveStep("9em", 2), new ResponsiveStep("5em", 3));
add(layout);
}
@Override
protected Tracking generateModelValue() {
final LocalDate date = datePicker.getValue();
final LocalTime time = timePicker.getValue();
tracking.setEventCode(eventCode.getValue());
tracking.setEventDateTime(date != null && time != null ? LocalDateTime.of(date, time) : null);
return tracking;
}
@Override
protected void setPresentationValue(Tracking newPresentationValue) {
if (newPresentationValue == null) {
eventCode.setValue(null);
datePicker.setValue(null);
timePicker.setValue(null);
} else {
LocalDateTime ldt = newPresentationValue.getEventDateTime();
eventCode.setValue(newPresentationValue.getEventCode());
datePicker.setValue(ldt != null ? ldt.toLocalDate() : null);
timePicker.setValue(ldt != null ? ldt.toLocalTime() : null);
}
}
ado2000
(Giovanni Adobati)
February 25, 2020, 7:08pm
2
Pietro Ferraboschi:
Hi, did you solved the problem ? i have something similar.
Thanks
Jaufray
(Jaufray Sornette)
February 27, 2020, 1:33pm
3
I have the same problem: Basically I am adding textfields in a grid and I want to add a key listener on each one of them. But it is never called and I do not understand why…
Here is my code:
for (Week w : weekRepository.findAll()) {
Grid.Column<EmployeeProject> gridColumn = grid.addComponentColumn(employeeProject -> {
TextField amountTime = new TextField();
amountTime.setWidth("85px");
amountTime.setValue(String.valueOf(employeeProject.getAmountTimeEmployeeOnProject(w)));
amountTime.addKeyPressListener(Key.ENTER, keyPressEvent -> {
notificationMessage.openSuccess("Saving");
employeeProject.setAmountTimeEmployeeOnProject(employeeProject.getProject(), w, Integer.parseInt(amountTime.getValue()));
employeeProjectRepository.save(employeeProject);
});
return amountTime;
});
gridColumn.setHeader(w.getWeekNumber() + " / " + w.getYear());
}
Has anyone solved this?
Pietro15
(Pietro Ferraboschi)
February 27, 2020, 1:44pm
4
Hi Giovanni and hi Jaufray, here my last version. I’m pretty happy with it but not for component responsivness! I must open another ticket to solve it
public class TrackingEvent extends CustomField<Tracking> {
// private static final long serialVersionUID = 4075248600075394610L;
final private String ICON_SIZE = "16px";
private final ComboBox<EventCode> code = new ComboBox<>(null);
private final DatePicker date = new DatePicker();
private final TimePicker time = new TimePicker();
private final Button delete = new Button();
private boolean complete = false;
public TrackingEvent(EventCodeType eventCodeType, Set<EventCode> items) {
this(new Tracking(eventCodeType), items, null, null);
}
public TrackingEvent(Tracking tracking, Set<EventCode> items) {
this(tracking, items, null, null);
}
public TrackingEvent(Tracking tracking, Set<EventCode> items, LocalDate minDate, LocalTime minTime) {
code.setItems(items);
// code.setPlaceholder(getTranslation("placeholder.event_code"));
code.setAllowCustomValue(false);
code.setRequired(true);
code.setWidthFull();
// code.setWidth("13em");
date.setMin(minDate);
date.setMax(LocalDate.now());
// date.setPlaceholder(getTranslation("placeholder.event_date"));
date.setRequired(true);
date.setWidth("9em");
// time.setPlaceholder(getTranslation("placeholder.event_time"));
if (minTime != null)
time.setMin(minTime.format(DateTimeFormatter.ofPattern("HH:mm")));
time.setWidth("7em");
time.addValueChangeListener(event -> {
// if time complete, the tracking is completed
complete = event.getValue() != null;
// updates the model value
setModelValue(generateModelValue(), true);
});
// delete button, default is not visible
delete.setVisible(false);
delete.setEnabled(false);
delete.setWidth(ICON_SIZE);
delete.setIcon(VaadinIcon.TRASH.create());
delete.addThemeVariants(ButtonVariant.LUMO_PRIMARY, ButtonVariant.LUMO_ERROR);
// show button's purpose "on hover"
delete.getElement().setProperty("title", getTranslation("tooltip.delete_event"));
Binder<Tracking> binder = new Binder<>();
binder.bind(code, Tracking::getEventCode, Tracking::setEventCode);
binder.bind(date, Tracking::getEventDate, Tracking::setEventDate);
binder.bind(time, Tracking::getEventTime, Tracking::setEventTime);
binder.addValueChangeListener(event -> enableDateTime());
setPresentationValue(tracking);
enableDateTime();
HorizontalLayout layout = new HorizontalLayout();
layout.setAlignItems(Alignment.CENTER);
layout.setWidthFull();
layout.add(code, date, time, delete);
// layout.setJustifyContentMode(FlexComponent.JustifyContentMode.BETWEEN);
// layout.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.STRETCH);
layout.setMargin(false);
add(layout);
}
public void setTracking(Tracking tracking) {
setPresentationValue(tracking);
enableDateTime();
}
public void setMinDate(LocalDate minDate) {
this.date.setMin(minDate);
}
public void setMinTime(LocalTime minTime) {
this.time.setMin(minTime.format(DateTimeFormatter.ofPattern("HH:mm")));
}
@Override
public void clear() {
code.clear();
date.clear();
time.clear();
}
/*
* Se confermato, lo rendo immodificabile; altrimenti lascio tutto com'è.
* */
public void setConfirmed(boolean confirmed) {
if (confirmed) {
code.setReadOnly(confirmed);
date.setReadOnly(confirmed);
time.setReadOnly(confirmed);
}
}
private void enableDateTime() {
if (code.getValue() == null) {
date.clear();
time.clear();
date.setReadOnly(true);
time.setReadOnly(true);
delete.setEnabled(false);
} else {
date.setReadOnly(false);
if (date.getValue() == null) {
time.clear();
time.setReadOnly(true);
delete.setEnabled(false);
} else {
time.setReadOnly(false);
delete.setEnabled(true);
}
}
}
public boolean isComplete() {
return complete;
}
public void addDeleteButtonClickListener(ComponentEventListener<ClickEvent<Button>> listener) {
delete.setVisible(true);
delete.addClickListener(listener);
}
@Override
protected Tracking generateModelValue() {
Tracking tracking = new Tracking();
tracking.setEventCode(code.getValue());
tracking.setEventDate(date.getValue());
tracking.setEventTime(time.getValue());
return tracking;
}
@Override
protected void setPresentationValue(Tracking newPresentationValue) {
if (newPresentationValue == null) {
clear();
} else {
code.setValue(newPresentationValue.getEventCode());
date.setValue(newPresentationValue.getEventDate());
// issue here https://github.com/vaadin/vaadin-time-picker-flow/issues/22
time.setValue(newPresentationValue.getEventTime());
}
}
}
ado2000
(Giovanni Adobati)
February 27, 2020, 2:09pm
5
Pietro Ferraboschi:
Hi Giovanni and hi Jaufray, here my last version. I’m pretty happy with it but not for component responsivness! I must open another ticket to solve it
Hi, Pietro, thanks,
may be my problem was related to creation of new object instance in generateModelValue().
like you did.
@Override
protected Tracking generateModelValue() {
Tracking tracking = new Tracking();
tracking.setEventCode(code.getValue());
tracking.setEventDate(date.getValue());
tracking.setEventTime(time.getValue());
return tracking;
}
Thanks.
Jaufray
(Jaufray Sornette)
February 27, 2020, 2:19pm
6
Hi Pietro,
Thanks for your message. However, I don’t fully understand how you made it work inside your grid.addColumn…
I have tried to make a new TextFieldCustom extening TextField but I have the same problem: the keyEventListener is never called.
I works perfectly when it is outside my loop and grid.addComponentColumn but not inside.
And I don’t understand why
Pietro15
(Pietro Ferraboschi)
February 27, 2020, 2:51pm
7
Jaufray Sornette:
Hi Pietro,
Thanks for your message. However, I don’t fully understand how you made it work inside your grid.addColumn…
I have tried to make a new TextFieldCustom extening TextField but I have the same problem: the keyEventListener is never called.
I works perfectly when it is outside my loop and grid.addComponentColumn but not inside.
And I don’t understand why
I think you have to bang your head on the wall of Binding
binder.addValueChangeListener … is the way to manage an event into a custom component.
Look for bind, binding or binder to have further information.