All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.imunity.vaadin.elements.LocalizedTextFieldDetails Maven / Gradle / Ivy
/*
* Copyright (c) 2021 Bixbit - Krzysztof Benedyczak. All rights reserved.
* See LICENCE.txt file for licensing information.
*/
package io.imunity.vaadin.elements;
import static io.imunity.vaadin.elements.CSSVars.BASE_MARGIN;
import static io.imunity.vaadin.elements.CssClassNames.DETAILS_ICON;
import static io.imunity.vaadin.elements.CssClassNames.EMPTY_DETAILS_ICON;
import static io.imunity.vaadin.elements.CssClassNames.SMALL_GAP;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.function.BiConsumer;
import com.vaadin.flow.component.HasSize;
import com.vaadin.flow.component.HasValue;
import com.vaadin.flow.component.customfield.CustomField;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.orderedlayout.FlexComponent.Alignment;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.data.binder.Binder;
import com.vaadin.flow.data.binder.HasValidator;
import com.vaadin.flow.data.binder.ValidationResult;
import com.vaadin.flow.data.binder.Validator;
public class LocalizedTextFieldDetails extends CustomField> implements HasValidator>
{
private final Map fields = new LinkedHashMap<>();
private final Binder> binder = new Binder<>();
private final LocalizedTextField defaultField;
private HorizontalLayout summary;
private Validator validator = (val, context) -> ValidationResult.ok();
public LocalizedTextFieldDetails(Collection enabledLocales, Locale currentLocale)
{
this(enabledLocales, currentLocale, null);
}
public LocalizedTextFieldDetails(Collection enabledLocales, Locale currentLocale, String label)
{
VerticalLayout content = new VerticalLayout();
content.setVisible(false);
content.setPadding(false);
content.setSpacing(false);
Icon angleDown = crateIcon(VaadinIcon.ANGLE_DOWN, label);
angleDown.getStyle().set("margin-top", BASE_MARGIN.value());
Icon angleUp = crateIcon(VaadinIcon.ANGLE_UP, label);
angleUp.getStyle().set("margin-top", BASE_MARGIN.value());
angleUp.setVisible(false);
angleDown.addClickListener(event ->
{
angleDown.setVisible(false);
angleUp.setVisible(true);
content.setVisible(true);
});
angleUp.addClickListener(event ->
{
angleDown.setVisible(true);
angleUp.setVisible(false);
content.setVisible(false);
});
defaultField = new LocalizedTextField(currentLocale);
defaultField.setLabel(label);
fields.put(currentLocale, defaultField);
summary = new HorizontalLayout(defaultField, angleDown, angleUp);
summary.setWidthFull();
summary.setClassName(SMALL_GAP.getName());
enabledLocales.stream()
.filter(locale -> !currentLocale.equals(locale))
.forEach(locale ->
{
LocalizedTextField localizedTextField = new LocalizedTextField(locale);
content.add(localizedTextField);
fields.put(locale, localizedTextField);
});
fields.forEach((locale, field) ->
binder.forField(field)
.withValidator((val, context) -> validator.apply(val, context))
.bind(map -> map.get(locale), (map, val) -> map.put(locale, val))
);
setValue(new LinkedHashMap<>());
add(summary, content);
propagateValueChangeEventFromNestedTextFieldToThisComponent();
}
private void propagateValueChangeEventFromNestedTextFieldToThisComponent()
{
fields.values().forEach(localizedTextField -> localizedTextField.addValueChangeListener(event ->
fireEvent(new ComponentValueChangeEvent<>(this, event.getHasValue(), event.getOldValue(), event.isFromClient()))
));
}
public void addValuesChangeListener(BiConsumer, Integer> consumer)
{
fields.values().forEach(field -> field.getElement().addEventListener(
"keyup",
e -> field.getElement().executeJs("return this.inputElement.selectionStart")
.then(Integer.class, pos -> consumer.accept(field, pos)))
);
fields.values().forEach(field -> field.addFocusListener(
e -> field.getElement().executeJs("return this.inputElement.selectionStart")
.then(Integer.class, pos -> consumer.accept(field, pos)))
);
}
public void setValidator(Validator validator)
{
this.validator = validator;
}
public Collection getSlottedFields()
{
return fields.values();
}
private Icon crateIcon(VaadinIcon angleDown, String label)
{
Icon icon = angleDown.create();
icon.addClassName(DETAILS_ICON.getName());
if(label != null)
icon.setClassName(EMPTY_DETAILS_ICON.getName());
return icon;
}
@Override
public void setWidthFull()
{
getElement().getStyle().setWidth("100%");
fields.values().forEach(HasSize::setWidthFull);
}
@Override
public void setWidth(String width)
{
fields.values().forEach(f -> f.setWidth(width));
}
@Override
public void focus()
{
fields.values().iterator().next().focus();
}
@Override
public void setValue(Map value)
{
binder.setBean(new LinkedHashMap<>(value));
}
@Override
public Map getValue()
{
return binder.getBean();
}
@Override
public void setReadOnly(boolean readOnly)
{
VaadinElementReadOnlySetter.setReadOnly(getElement(), readOnly);
fields.values().forEach(field -> field.setReadOnly(readOnly));
}
@Override
protected Map generateModelValue()
{
return getValue();
}
@Override
protected void setPresentationValue(Map newPresentationValue)
{
setValue(newPresentationValue);
}
@Override
public Validator> getDefaultValidator()
{
return (value, context) ->
{
if (binder.isValid()) {
return ValidationResult.ok();
} else {
return ValidationResult.error("");
}
};
}
@Override
public void setLabel(String label)
{
defaultField.setLabel(label);
}
@Override
public String getLabel()
{
return defaultField.getLabel();
}
public void setPlaceholder(String message)
{
defaultField.setPlaceholder(message);
}
public void centerIcons()
{
summary.setAlignItems(Alignment.BASELINE);
}
}