You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2022/09/20 07:57:53 UTC
[isis] branch master updated: ISIS-3215: update negotiation models on select2 events
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new fe7ed87171 ISIS-3215: update negotiation models on select2 events
fe7ed87171 is described below
commit fe7ed871714e80f0f9b6d85ceeed2f137c8d34c9
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Sep 20 09:57:47 2022 +0200
ISIS-3215: update negotiation models on select2 events
---
.../ui/components/widgets/select2/Select2.java | 60 +------
.../widgets/select2/Select2OnSelect.java | 191 +++++++++++++++++++++
2 files changed, 194 insertions(+), 57 deletions(-)
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2.java
index aab59cdf9e..c864260ecb 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2.java
@@ -20,20 +20,13 @@ package org.apache.isis.viewer.wicket.ui.components.widgets.select2;
import java.io.Serializable;
import java.util.List;
-import java.util.Optional;
-import org.apache.wicket.Component;
-import org.apache.wicket.behavior.AbstractAjaxBehavior;
import org.apache.wicket.behavior.Behavior;
-import org.apache.wicket.markup.head.IHeaderResponse;
-import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LambdaModel;
import org.apache.wicket.model.Model;
-import org.apache.wicket.request.mapper.parameter.INamedParameters.NamedPair;
import org.apache.wicket.validation.IValidator;
import org.wicketstuff.select2.AbstractSelect2Choice;
-import org.wicketstuff.select2.JQuery;
import org.wicketstuff.select2.Select2Choice;
import org.wicketstuff.select2.Select2MultiChoice;
@@ -45,7 +38,6 @@ import org.apache.isis.viewer.wicket.model.models.HasCommonContext;
import org.apache.isis.viewer.wicket.model.models.ScalarModel;
import org.apache.isis.viewer.wicket.model.models.ScalarModelWithMultiChoice;
import org.apache.isis.viewer.wicket.model.models.ScalarModelWithSingleChoice;
-import org.apache.isis.viewer.wicket.model.util.PageParameterUtils;
import org.apache.isis.viewer.wicket.model.util.WktContext;
import org.apache.isis.viewer.wicket.ui.components.widgets.select2.providers.ChoiceProviderAbstract;
import org.apache.isis.viewer.wicket.ui.components.widgets.select2.providers.ChoiceProviderAbstractForScalarModel;
@@ -85,8 +77,8 @@ implements
select2.setLabel(Model.of(scalarModel.getFriendlyName()));
select2.getSettings().setWidth("100%");
- // listen on select2:select events (client-side)
- select2.add(new Select2OnSelect());
+ // listen on select2:select/unselect events (client-side)
+ select2.add(new Select2OnSelect(scalarModel));
return select2;
}
@@ -191,53 +183,7 @@ implements
});
}
- /**
- * Listen on select2:select events so that we then can send an AJAX request with all selected object(.id)s,
- * while still doing parameter negotiation; that is, not submitting the form yet.
- * @see "https://select2.org/programmatic-control/events#listening-for-events"
- * @since 2.0
- */
- static class Select2OnSelect extends AbstractAjaxBehavior {
- private static final long serialVersionUID = 1L;
- private static enum Event {
- SELECT, UNSELECT, CLEAR;
- String key() { return name().toLowerCase(); }
- static Optional<Event> valueOf(final NamedPair pair) {
- for(val event : Event.values()) {
- if(event.name().equalsIgnoreCase(pair.getKey())) {
- return Optional.of(event);
- }
- }
- return Optional.empty();
- }
- };
- @Override public void renderHead(final Component component, final IHeaderResponse response) {
- for(val event : Event.values()) {
- response.render(OnDomReadyHeaderItem.forScript(JQuery.execute("$('#%s')"
- + ".on('select2:%s', function (e) {"
- + "var data = e.params.data;"
- //debug + "console.log(e);"
- + "Wicket.Ajax.get({'u': '%s&%s=' + data.id});"
- + "});",
- component.getMarkupId(),
- event.key(),
- getCallbackUrl(),
- event.key()
- )));
- }
- }
-
- @Override public void onRequest() {
- PageParameterUtils.streamCurrentRequestParameters()
- .forEach(pair->
- Event.valueOf(pair).ifPresent(event->{
- val itemId = ObjectMemento.destringFromUrlBase64(pair.getValue());
- //TODO update the param negotiation model
- //System.err.printf("onRequest %s->%s%n", event, itemId.getTitle());
- })
- );
- }
- }
+
// -- HELPER
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2OnSelect.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2OnSelect.java
new file mode 100644
index 0000000000..59f103ea62
--- /dev/null
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/select2/Select2OnSelect.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.isis.viewer.wicket.ui.components.widgets.select2;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.behavior.AbstractAjaxBehavior;
+import org.apache.wicket.markup.head.IHeaderResponse;
+import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
+import org.apache.wicket.request.mapper.parameter.INamedParameters.NamedPair;
+import org.wicketstuff.select2.JQuery;
+
+import org.apache.isis.commons.binding.Bindable;
+import org.apache.isis.commons.collections.Can;
+import org.apache.isis.core.metamodel.object.ManagedObject;
+import org.apache.isis.core.metamodel.object.PackedManagedObject;
+import org.apache.isis.core.metamodel.objectmanager.memento.ObjectMemento;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.viewer.wicket.model.models.ScalarModel;
+import org.apache.isis.viewer.wicket.model.util.PageParameterUtils;
+
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+import lombok.val;
+
+/**
+ * Listen on select2:select, select2:unselect and select2:clear events
+ * so that we then can send an AJAX request including the event type and
+ * the selected or un-selected object(.id),
+ * while still doing parameter negotiation; that is, not submitting the form yet.
+ * @see "https://select2.org/programmatic-control/events#listening-for-events"
+ * @since 2.0
+ */
+@RequiredArgsConstructor
+class Select2OnSelect extends AbstractAjaxBehavior {
+ private static final long serialVersionUID = 1L;
+ private final ScalarModel scalarModel;
+
+ private static enum Event {
+ SELECT, UNSELECT, CLEAR;
+ String key() { return name().toLowerCase(); }
+ static Optional<Select2OnSelect.Event> valueOf(final NamedPair pair) {
+ for(var event : Event.values()) {
+ if(event.name().equalsIgnoreCase(pair.getKey())) {
+ return Optional.of(event);
+ }
+ }
+ return Optional.empty();
+ }
+ };
+
+ @Override
+ public void renderHead(final Component component, final IHeaderResponse response) {
+ for(var event : Event.values()) {
+ response.render(OnDomReadyHeaderItem.forScript(JQuery.execute("$('#%s')"
+ + ".on('select2:%s', function (e) {"
+ + "var data = e.params.data;"
+ //debug + "console.log(e);"
+ + "Wicket.Ajax.get({'u': '%s&%s=' + data.id});"
+ + "});",
+ component.getMarkupId(),
+ event.key(),
+ getCallbackUrl(),
+ event.key()
+ )));
+ }
+ }
+
+ /**
+ * update the param negotiation model
+ */
+ @Override
+ public void onRequest() {
+ PageParameterUtils.streamCurrentRequestParameters()
+ .forEach(pair->
+ Event.valueOf(pair).ifPresent(event->{
+ val objectMementoFromEvent = ObjectMemento.destringFromUrlBase64(pair.getValue());
+ if(getComponent() instanceof Select2MultiChoiceExt) {
+ val component = (Select2MultiChoiceExt)getComponent();
+ switch(event) {
+ case SELECT:{
+ val selection = component.getModelObject();
+ val newSelection = selection!=null
+ ? new ArrayList<ObjectMemento>(selection)
+ : new ArrayList<ObjectMemento>();
+ newSelection.add(objectMementoFromEvent);
+ component.setModelObject(newSelection);
+ updateReceiver().setValue(demementify(newSelection));
+ break;
+ }
+ case UNSELECT:{
+ val selection = component.getModelObject();
+ val newSelection = selection!=null
+ ? new ArrayList<ObjectMemento>(selection)
+ : new ArrayList<ObjectMemento>();
+ newSelection.remove(objectMementoFromEvent);
+ component.setModelObject(newSelection);
+ updateReceiver().setValue(demementify(newSelection));
+ break;
+ }
+ case CLEAR:
+ component.setModelObject(null);
+ clearUpdateReceiver();
+ break;
+ }
+// System.err.printf("value updated %s%n",
+// scalarModel.getObjectManager().demementify(objectMementoFromEvent));
+ }
+ else
+ if(getComponent() instanceof Select2ChoiceExt) {
+ val component = (Select2ChoiceExt)getComponent();
+ switch(event) {
+ case SELECT:
+ component.setModelObject(objectMementoFromEvent);
+ updateReceiver().setValue(demementify(objectMementoFromEvent));
+ break;
+ case UNSELECT:
+ case CLEAR:
+ component.clearInput();
+ clearUpdateReceiver();
+ break;
+ }
+
+ } else return;
+
+ //TODO schedule form update (AJAX)
+
+ })
+ );
+ }
+
+ // -- HELPER
+
+ private ManagedObject demementify(final ObjectMemento memento) {
+ return scalarModel.getObjectManager().demementify(memento);
+ }
+
+ private PackedManagedObject demementify(
+ final @NonNull List<ObjectMemento> mementos) {
+ return ManagedObject.packed(
+ elementSpec(),
+ mementos.stream().map(this::demementify).collect(Can.toCan()));
+ }
+
+ private @NonNull Bindable<ManagedObject> updateReceiver() {
+ val updateReceiver = scalarModel.getSpecialization().fold(
+ param->
+ param.getParameterNegotiationModel().getBindableParamValue(param.getParameterIndex()),
+ prop->
+ prop.getPendingPropertyModel().getValue());
+ return updateReceiver;
+ }
+
+ private @NonNull ObjectSpecification elementSpec() {
+ val updateReceiver = scalarModel.getSpecialization().fold(
+ param->param.getScalarTypeSpec(),
+ prop->prop.getScalarTypeSpec());
+ return updateReceiver;
+ }
+
+ private void clearUpdateReceiver() {
+ scalarModel.getSpecialization().accept(
+ param->
+ param.getParameterNegotiationModel().getParamModels()
+ .getElseFail(param.getParameterIndex())
+ .clear(),
+ prop->
+ prop.getPendingPropertyModel().clear());
+ }
+
+
+}
\ No newline at end of file