Skip to content

Commit

Permalink
#105 fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
vaadin-miki authored May 7, 2020
1 parent d50a607 commit 85009d5
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.vaadin.miki.superfields.dates;

import com.vaadin.flow.component.AttachEvent;
import com.vaadin.flow.component.Component;

/**
Expand All @@ -9,7 +10,7 @@
* @author miki
* @since 2020-05-02
*/
final class DatePatternHelper {
final class DatePatternHelper<C extends Component & HasDatePattern> {

/**
* Returns the pattern descriptor string expected by the client-side code.
Expand Down Expand Up @@ -52,20 +53,48 @@ private static String convertDatePatternToClientPattern(DatePattern pattern) {
}
}

private final C source;

/**
* Does magic and sets the display pattern on the client side.
* Requires the client-side connector to have a {@code setDisplayPattern} method.
* @param source Source component.
* @param pattern Pattern to set.
* Creates a helper for a given source object.
* The client-side representation should have mixed in methods from {@code date-pattern-mixin.js}.
* @param source Source to use.
*/
DatePatternHelper(C source) {
this.source = source;
this.source.addAttachListener(this::onAttached);
}

/**
* Class client-side method {@code initPatternSetting()} that, well, inits pattern setting.
* In general, client-side code overrides a few methods to make sure pattern displaying and parsing works properly with custom patterns.
*/
static void setClientSidePattern(Component source, DatePattern pattern) {
source.getElement().getNode().runWhenAttached(ui -> ui.beforeClientResponse(source, context ->
source.getElement().callJsFunction("setDisplayPattern", source.getElement(), convertDatePatternToClientPattern(pattern))
protected void initPatternSetting() {
this.source.getElement().getNode().runWhenAttached(ui -> ui.beforeClientResponse(this.source, context ->
this.source.getElement().callJsFunction("initPatternSetting", this.source)
));
}

private DatePatternHelper() {
// instances not allowed
/**
* Callback when onAttach() is called.
* @param event An {@link AttachEvent}.
*/
protected void onAttached(AttachEvent event) {
this.initPatternSetting();
this.updateClientSidePattern();
}

/**
* Does magic and sets the display pattern on the client side.
* Requires the client-side connector to have a {@code setDisplayPattern} method.
*/
protected void updateClientSidePattern() {
this.source.getElement().getNode().runWhenAttached(ui -> ui.beforeClientResponse(this.source, context ->
this.source.getElement().callJsFunction(
"setDisplayPattern",
this.source.getElement(), convertDatePatternToClientPattern(this.source.getDatePattern())
)
));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public class SuperDatePicker extends DatePicker
WithValueMixin<AbstractField.ComponentValueChangeEvent<DatePicker, LocalDate>, LocalDate, SuperDatePicker>,
WithIdMixin<SuperDatePicker> {

private final DatePatternHelper<SuperDatePicker> delegate = new DatePatternHelper<>(this);

private DatePattern datePattern;

public SuperDatePicker() {
Expand Down Expand Up @@ -77,22 +79,25 @@ public SuperDatePicker(String label, LocalDate initialDate, ValueChangeListener<
}

public SuperDatePicker(LocalDate initialDate, Locale locale) {
super(initialDate, locale);
super(initialDate);
this.setLocale(locale);
}

@Override
public final void setLocale(Locale locale) {
this.getElement().getNode().runWhenAttached(ui -> ui.beforeClientResponse(this, context ->
this.getElement().callJsFunction("initPatternSetting", this.getElement())
));
SuperDatePickerI18nHelper.updateI18N(locale, this::getI18n, this::setI18n);
// there is a call for setting locale from the superclass' constructor
// and when that happens, the field is not yet initialised
if(this.delegate != null) {
this.delegate.initPatternSetting();
SuperDatePickerI18nHelper.updateI18N(locale, this::getI18n, this::setI18n);
}
super.setLocale(locale);
}

@Override
public void setDatePattern(DatePattern datePattern) {
this.datePattern = datePattern;
DatePatternHelper.setClientSidePattern(this, datePattern);
this.delegate.updateClientSidePattern();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public class SuperDateTimePicker extends DateTimePicker
private static final String INTERNAL_DATE_PICKER_FIELD_NAME = "datePicker";
private static final String INTERNAL_TIME_PICKER_FIELD_NAME = "timePicker";

private final DatePatternHelper<SuperDateTimePicker> delegate = new DatePatternHelper<>(this);

private DatePattern datePattern;

public SuperDateTimePicker() {
Expand Down Expand Up @@ -89,19 +91,20 @@ public SuperDateTimePicker(LocalDateTime initialDateTime, Locale locale) {

@Override
public void setLocale(Locale locale) {
this.getElement().getNode().runWhenAttached(ui -> ui.beforeClientResponse(this, context ->
this.getElement().callJsFunction("initPatternSetting", this)
))
;
SuperDatePickerI18nHelper.updateI18N(locale, this::getDatePickerI18n, this::setDatePickerI18n);
// this method is called from the constructor of the superclass
// which means that first time it gets called, the delegate is not yet initialised
if(this.delegate != null) {
this.delegate.initPatternSetting();
SuperDatePickerI18nHelper.updateI18N(locale, this::getDatePickerI18n, this::setDatePickerI18n);
}
super.setLocale(locale);
}

/**
* Exposes an internal {@link DatePicker}, if it was successfully obtained through reflection.
* @return A {@link DatePicker} used by this component, if possible.
*/
public Optional<DatePicker> getDatePicker() {
public Optional<DatePicker> getInternalDatePicker() {
return ReflectTools.getValueOfField(this, DatePicker.class, INTERNAL_DATE_PICKER_FIELD_NAME);
}

Expand All @@ -116,7 +119,7 @@ public Optional<TimePicker> getInternalTimePicker() {
@Override
public void setDatePattern(DatePattern pattern) {
this.datePattern = pattern;
DatePatternHelper.setClientSidePattern(this, pattern);
this.delegate.updateClientSidePattern();
}

@Override
Expand Down

0 comments on commit 85009d5

Please sign in to comment.