DateField autofill within rangeStart and rangeEnd

Hello,

I want to use a DateField with enabled autofill function and within a defined Range (business period), for example 01.07.2022 - 30.06.2023. For the value 01.08. the field should autofill to 01.08.2022 and for the value 01.02. to 01.02.2023. I tested all possible resolution values, but none worked correctly for my described problem. Is there a way to get the correct year in the range depending on the day-month combination?

Best regards,
André

Jmix 1.4.3-222
IntelliJ 2022.2.1

Hi,

The current behaviour is not a but, the algorithm as follows:

  1. If only a day is defined, then add current month and current year
  2. If date and month are defined, then add current year
  3. If value is without the range, then set max possible value

Regards,
Gleb

Hello,

is it then possible to write an own autofill function?

After entering, for example 15.02 and then leaving the field, the value is automatically deleted. I disabled the autofill property and tested the valueChangeEvent and the Validator, but both didn’t fire. Is there another way for writing an own autofill function?

André

Hi,

The actual logic located in the client-side implementation of the component:

  • io.jmix.ui.widget.client.datefield.JmixDateFieldWidget#fillValue
  • io.jmix.ui.widget.client.datefield.JmixDateFieldWidget#adjustStringValue
  • io.jmix.ui.widget.client.datefield.JmixDateFieldWidget#adjustDateByRange

In order to provide our own implementation you need to extend JmixDateFieldWidget. To do this, you need to:

  1. Add custom widgetset settings to your app:
    1.1. Replace implementation 'io.jmix.ui:jmix-ui-widgets-compiled' with implementation 'io.jmix.ui:jmix-ui-widgets'
    1.2. add widgets 'io.jmix.ui:jmix-ui-widgets' in dependency list
    1.3. Define the following in build.gradle:
compileWidgets {
    generate "com.company.demo.widgets.CustomWidgetSet"
    includePaths("**/io/jmix/**/widget/**", "**/com/company/demo/widgets/**")
}

// for debug
task debugWidgets(type: WidgetsDebug, dependsOn: classes) {
    widgetSetClass 'com.company.demo.widgets.CustomWidgetSet'
    xmx '-Xmx1600m'
}
  1. Create <root_package>.widgets.client package and place the following classes:
    2.1. JmixDateFieldWidgetExt that extends JmixDateFieldWidget
import io.jmix.ui.widget.client.datefield.JmixDateFieldWidget;

import java.util.Date;

public class JmixDateFieldWidgetExt extends JmixDateFieldWidget {

    @Override
    protected String fillValue(String value) {
        return super.fillValue(value);
    }

    @Override
    protected String adjustStringValue(String value) {
        return super.adjustStringValue(value);
    }

    @Override
    protected Date adjustDateByRange(Date date, Date rangeStart, Date rangeEnd) {
        return super.adjustDateByRange(date, rangeStart, rangeEnd);
    }
}

2.2. JmixDateFieldConnectorExt that extends JmixDateFieldConnector

import com.company.demo.widgets.JmixDateFieldExt;
import com.vaadin.shared.ui.Connect;
import io.jmix.ui.widget.client.datefield.JmixDateFieldConnector;

@Connect(JmixDateFieldExt.class)
public class JmixDateFieldConnectorExt extends JmixDateFieldConnector {

    public JmixDateFieldWidgetExt getWidget() {
        return (JmixDateFieldWidgetExt) super.getWidget();
    }
}

2.3. (For debug) Create CustomWidgetSet.gwt.xml in <root_package>.widgets package:

<?xml version="1.0" encoding="UTF-8"?>
<module>
    <inherits name="io.jmix.ui.widget.WidgetSet"/>
</module>
  1. Extend Server side implementation of DateField in <root_package>.widgets package:
import io.jmix.ui.widget.JmixDateField;

public class JmixDateFieldExt extends JmixDateField {
}
  1. Extend Jmix Implementation in <root_package>.component package:
import com.company.demo.widgets.JmixDateFieldExt;
import io.jmix.ui.component.impl.DateFieldImpl;
import io.jmix.ui.widget.JmixDateField;

public class DateFieldExtImpl<V extends Comparable<V>> extends DateFieldImpl<V> {

    @Override
    protected JmixDateField createDateField() {
        return new JmixDateFieldExt();
    }
}
  1. Register new Date Field component so it’ll be used instead of default one:

FooApplication.java

@Bean
    public ComponentRegistration dateFieldExt() {
        return ComponentRegistrationBuilder.create(DateField.NAME)
                .withComponentClass(DateFieldExtImpl.class)
                .build();
    }

In JmixDateFieldWidgetExt you can provide your own implementation for the autofill logic. The only problem is that it is a GWT component which means that it’ll be compioled into JavaScript and you can’t debug it using your IDE. In order to debug client-side you need to execute debugWidgets gradle task after application has started and navigate to http://localhost:8080/?superdevmode. After that you’ll be able to open JmixDateFieldWidgetExt in browser’s dev tool and debug Java in browser:

Screenshot 2023-12-08 at 16.58.35

Demo project with extended DateField: classic-sandbox.zip (93.5 KB)

Regards,
Gleb

1 Like