V8 detect changed property name

yes, that is exactly how we used it before

String propertyName = (String) binder.getPropertyId((Field<?>) valueChangeEvent.getProperty());

For now I am going to construct the Field->PropertyName map from boundProperties

Yeah, the difference here would be that event.getSource() would return the source Component, but that doesn’t matter with your usage

Yes, I dont care what it is

Something you can already do is binder.getBinding(propertyName).get().getField().addValueChangeListener(listener)

First i need to get the property name

binder.getBoundProperties().forEach((propertyName, binding) → {
propertyNamesToFields.put(propertyName, binding.getField());
fieldsToPropertyNames.put(binding.getField(), propertyName);
});

Sry I need to leave now

String propertyName = fieldsToPropertyNames.get(valueChangeEvent.getComponent());

Not tested yet

:wave: We have a similar use case, we bind fields by definitions (in your case property names) https://git.magnolia-cms.com/projects/PLATFORM/repos/ui.pub/browse/magnolia-ui-framework/src/main/java/info/magnolia/ui/editor/FormPresenter.java#206, so we can get it later by definition https://git.magnolia-cms.com/projects/PLATFORM/repos/ui.pub/browse/magnolia-ui-framework/src/main/java/info/magnolia/ui/editor/FormPresenter.java#211 (it would be the other way around in your case, right?)

Hello @inclusive-camel , do you always call forField directly or it is called by all other Binder methods? Nice idea, going to have a look at it

I guess you call it directly

we rely on auto-binding by reflection

Hey, yes we call it directly but I think you can do something like:

 private static class PropertyAwareBinder<BEAN> extends Binder<BEAN> {

        private final Map<HasValue<?>, Binding<BEAN, ?>> boundProperties = new HashMap<>();

        private PropertyAwareBinder(Class<BEAN> beanClass) {
            super(beanClass);
        }

        @Override
        public <FIELDVALUE> BindingBuilder<BEAN, FIELDVALUE> forField(HasValue<FIELDVALUE> field) {
            return new BindingBuilderWrapper<>(super.forField(field)) {
                @Override
                public Binder.Binding<BEAN, FIELDVALUE> bind(String propertyName) {
                    var binding = wrapped.bind(propertyName);
                    boundProperties.put(getField(), binding);
                    return binding;
                }
            };
        }

        public Optional<Binding<BEAN, ?>> getBinding(HasValue<?> hasValue) {
            return Optional.ofNullable(boundProperties.get(hasValue));
        }
    }
    @AllArgsConstructor
    private static abstract class BindingBuilderWrapper<BEAN, TARGET> implements Binder.BindingBuilder<BEAN, TARGET> {
        @Delegate(excludes = BindMethodInterface.class)
        Binder.BindingBuilder<BEAN, TARGET> wrapped;

        private interface BindMethodInterface<BEAN, TARGET> {
            Binder.Binding<BEAN, TARGET> bind(String propertyName);
        }
    }

there is some lombok to simplify the wrapper object but at least you don’t need to use reflection to access a private object

Thank s for inputs, for now I guess we will be happy with exposing boundProperties