All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opensingular.lib.wicket.util.modal.OpenModalEvent Maven / Gradle / Ivy

There is a newer version: 1.9.7
Show newest version
package org.opensingular.lib.wicket.util.modal;

import java.io.Serializable;
import java.util.Optional;

import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.opensingular.lib.commons.lambda.IFunction;
import org.opensingular.lib.commons.lambda.IPredicate;
import org.opensingular.lib.commons.lambda.ITriConsumer;
import org.opensingular.lib.wicket.util.modal.BSModalBorder.ButtonStyle;
import org.opensingular.lib.wicket.util.util.WicketUtils;

public class OpenModalEvent implements IOpenModalEvent {

    public static interface ConfigureCallback extends Serializable {
        void configure(ModalDelegate delegate);
    }

    protected static interface ActionComponentFactory extends Serializable {
        C create(String id, ModalDelegate delegate, Optional> form, ActionCallback action);
    }

    @FunctionalInterface
    public static interface ActionCallback extends Serializable {

        void onAction(AjaxRequestTarget target, ModalDelegate delegate, IModel model);
        default void onError(AjaxRequestTarget target, ModalDelegate delegate, IModel model) {
            target.add(delegate.getModalBorder().getModalBody());
        }

        default ActionCallback withOnError(ITriConsumer, AjaxRequestTarget, IModel> onError) {
            ActionCallback self = this;
            return new ActionCallback() {
                @Override
                public void onAction(AjaxRequestTarget target, ModalDelegate delegate, IModel model) {
                    self.onAction(target, delegate, model);
                }
                @Override
                public void onError(AjaxRequestTarget target, ModalDelegate delegate, IModel model) {
                    onError.accept(delegate, target, model);
                }
            };
        }
    }

    private final AjaxRequestTarget                target;
    private final IFunction     bodyContentFactory;
    private final ConfigureCallback             configureCallback;
    @SuppressWarnings("unchecked")
    private IFunction>        modelExtractor = c -> (IModel) c.getDefaultModel();
    private ActionComponentFactory, T> linkFactory    = OpenModalEvent::defaultNewLink;
    private ActionComponentFactory  buttonFactory  = OpenModalEvent::defaultNewButton;

    public OpenModalEvent(AjaxRequestTarget target, IModel model, IFunction bodyContentFactory, ConfigureCallback configureCallback) {
        this(target, bodyContentFactory, configureCallback);
        this.setModelExtractor(c -> model);
    }
    protected OpenModalEvent(AjaxRequestTarget target, IFunction bodyContentFactory, ConfigureCallback configureCallback) {
        this.target = target;
        this.bodyContentFactory = bodyContentFactory;
        this.configureCallback = configureCallback;
    }

    protected final void setModelExtractor(IFunction> modelExtractor) {
        this.modelExtractor = modelExtractor;
    }
    protected final void setLinkFactory(ActionComponentFactory, T> linkFactory) {
        this.linkFactory = linkFactory;
    }
    protected final void setButtonFactory(ActionComponentFactory buttonFactory) {
        this.buttonFactory = buttonFactory;
    }

    protected static  AjaxLink defaultNewLink(String id, ModalDelegate delegate, Optional> form, ActionCallback action) {
        return new AjaxLink(id, delegate.getModel()) {
            @Override
            public void onClick(AjaxRequestTarget target) {
                action.onAction(target, delegate, delegate.getModel());
            }
        };
    }
    protected static  AjaxButton defaultNewButton(String id, ModalDelegate delegate, Optional> form, ActionCallback action) {
        return new AjaxButton(id, form.orElse(null)) {
            @Override
            protected void onSubmit(AjaxRequestTarget target, Form form) {
                action.onAction(target, delegate, delegate.getModel());
            }
            @Override
            protected void onError(AjaxRequestTarget target, Form form) {
                super.onError(target, form);
                action.onError(target, delegate, delegate.getModel());
            }
        };
    }

    @Override
    public Component getBodyContent(String id) {
        return bodyContentFactory.apply(id);
    }

    @Override
    public Optional getTarget() {
        return Optional.ofNullable(this.target);
    }

    @Override
    public void configureModal(BSModalBorder modal, Component bodyContent) {
        configureCallback.configure(
            new ModalDelegate<>(
                modal,
                modelExtractor.apply(bodyContent),
                new BodyContentPredicate(bodyContent),
                linkFactory,
                buttonFactory));
    }

    public static class ModalDelegate implements Serializable {

        private final BSModalBorder                          modalBorder;
        private final IModel                              model;
        private final IPredicate                  bodyContentPredicate;
        private final ActionComponentFactory, T> linkFactory;
        private final ActionComponentFactory  buttonFactory;

        public ModalDelegate(
                BSModalBorder modalBorder,
                IModel model,
                IPredicate bodyContentPredicate,
                ActionComponentFactory, T> linkFactory,
                ActionComponentFactory buttonFactory) {
            this.modalBorder = modalBorder;
            this.model = model;
            this.bodyContentPredicate = bodyContentPredicate;
            this.linkFactory = linkFactory;
            this.buttonFactory = buttonFactory;
        }

        public void setTitle(String title) {
            setTitle(Model.of(title));
        }
        public void setTitle(Model titleModel) {
            getModalBorder().setTitleText(titleModel);
        }
        public AjaxLink addLink(String label, ActionCallback action) {
            return addLink(getModalBorder().newButtonId(), Model.of(label), ButtonStyle.LINK, action);
        }
        public AjaxLink addLink(String id, IModel labelModel, ButtonStyle style, ActionCallback action) {
            Optional> form = WicketUtils.findFirstChild(getModalBorder().getModalBody(), Form.class).map(it -> (Form) it);
            AjaxLink link = newAjaxLink(id, form, action);
            getModalBorder().addLink(style, labelModel, link);
            return link;
        }
        public AjaxButton addButton(String label, ActionCallback action) {
            return addButton(getModalBorder().newButtonId(), Model.of(label), ButtonStyle.PRIMARY, action);
        }
        public AjaxButton addButton(String id, IModel labelModel, ButtonStyle style, ActionCallback action) {
            Optional> form = WicketUtils.findFirstChild(getModalBorder().getModalBody(), Form.class).map(it -> (Form) it);
            AjaxButton button = newAjaxButton(id, form, action);
            getModalBorder().addButton(style, labelModel, button);
            return button;
        }

        public AjaxLink addCloseLink(String label) {
            return addLink(getModalBorder().newButtonId(), Model.of(label), ButtonStyle.LINK, newCloseAction());
        }
        public AjaxLink addCloseButton(String label) {
            return addLink(getModalBorder().newButtonId(), Model.of(label), ButtonStyle.CANCEL, newCloseAction());
        }

        public BSModalBorder getModalBorder() {
            return modalBorder;
        }
        public IModel getModel() {
            return model;
        }
        public IPredicate getBodyContentPredicate() {
            return bodyContentPredicate;
        }
        public void close(AjaxRequestTarget target) {
            new CloseModalEvent(target, getBodyContentPredicate()).bubble(getModalBorder());
        }

        private ActionCallback newCloseAction() {
            return (t, d, i) -> d.close(t);
        }
        private AjaxLink newAjaxLink(String id, Optional> form, ActionCallback action) {
            return linkFactory.create(id, ModalDelegate.this, form, action);
        }
        private AjaxButton newAjaxButton(String id, Optional> form, ActionCallback action) {
            return buttonFactory.create(id, ModalDelegate.this, form, action);
        }
    }

    private static final class BodyContentPredicate implements IPredicate {
        private final Component bodyContent;
        public BodyContentPredicate(Component bodyContent) {
            this.bodyContent = bodyContent;
        }
        @Override
        public boolean test(Component t) {
            return t == bodyContent;
        }

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy