> Wicket 7.0.0 is about to be released so it's a bit late for ideas.
>

=) Is there a board for ideas for next one?


> But what you describe sounds like what  wicketstuff-stateless project
> already provides.
>

I looked at
https://github.com/mafulafunk/wicketstuff-core/tree/master/jdk-1.6-parent/stateless-parent/stateless/src/main/java/org/wicketstuff/stateless

It is not quite the same what I am discussing. I mean that if you call
page.removeAll() and execute the event, it would still work.

We have implemented things like:


/**
 *
 * Listener that collects fake events.
 *
 */
public class FakeEventListener implements IListener {

  private static final MetaDataKey<FakeEventListener> DATA_KEY = new
MetaDataKey<FakeEventListener>() {
    private static final long serialVersionUID = 1L;
  };

  private ArrayList<String> scripts = new ArrayList<String>();

  /**
   * Constructor
   *
   */
  private FakeEventListener() {
  }

  /**
   * @see
org.apache.wicket.ajax.AjaxRequestTarget.IListener#onBeforeRespond(java.util.Map,
   *      org.apache.wicket.ajax.AjaxRequestTarget)
   */
  @Override
  public void onBeforeRespond(Map<String, Component> map, AjaxRequestTarget
target) {
    // do nothing
  }

  /**
   * @see
org.apache.wicket.ajax.AjaxRequestTarget.IListener#onAfterRespond(java.util.Map,
   *      org.apache.wicket.ajax.AjaxRequestTarget.IJavascriptResponse)
   */
  @Override
  public void onAfterRespond(Map<String, Component> map,
IJavascriptResponse response) {
    StringBuilder builder = new StringBuilder();
    builder.append("var fakeev_inin = function(event) {");
    builder.append("if( typeof Tustor == 'undefined' || typeof
Tustor.Events == 'undefined') { setTimeout(fakeev_inin, 10); } else {");
    for (String parentMarkupId : scripts) {
      builder.append("Tustor.Events.addFakeEventsClassName('.FACB");
      builder.append(index(parentMarkupId));
      builder.append("', '");
      builder.append(parentMarkupId);
      builder.append("');");
    }
    builder.append("}};");
    builder.append("$(document).ready(function(){fakeev_inin();});");
    response.addJavascript(builder.toString());
    RequestCycle.get().setMetaData(DATA_KEY, null);
  }

  /**
   * Adds script;
   *
   * @param parentMarkupId
   *
   */
  public void addScript(String parentMarkupId) {
    if(!scripts.contains(parentMarkupId)) {
      scripts.add(parentMarkupId);
    }
  }

  /**
   *
   * @param parentMarkupId
   * @return index
   */
  public int index(String parentMarkupId) {
    if(!scripts.contains(parentMarkupId)) {
      scripts.add(parentMarkupId);
    }
    return scripts.indexOf(parentMarkupId);
  }

  /**
   * Gets and creates if does not exists.
   *
   * @return DatePickerListener
   */
  public static FakeEventListener getCreate() {
    FakeEventListener listener = RequestCycle.get().getMetaData(DATA_KEY);
    if (listener == null) {
      listener = new FakeEventListener();
      RequestCycle.get().setMetaData(DATA_KEY, listener);
    }
    return listener;
  }

  /**
   * Gets without create.
   *
   * @return {@link FakeEventListener}
   */
  public static FakeEventListener get() {
    return RequestCycle.get().getMetaData(DATA_KEY);
  }

}






/**
 *
 */
package com.tustor.tuntinetti.view.reusables.components;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.IAjaxCallDecorator;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.html.IHeaderContributor;
import org.apache.wicket.markup.html.IHeaderResponse;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.util.string.JavascriptUtils;

import com.tustor.common.wicket.constants.JavaScriptConstants;
import
com.tustor.tuntinetti.view.reusables.components.FakeEventButton.FakeAjaxEventBehavior;

/**
 * Fake event button which trigger fake event to parent. Parent need to have
 * {@link FakeAjaxEventBehavior} attached.
 *
 *
 */
public abstract class FakeAjaxFormComponentUpdatingBehavior extends
AjaxFormComponentUpdatingBehavior implements IHeaderContributor {
  private static final String FAKE_EVENT_NAME = "fake";
  private String parentMarkupId;
  private final boolean busySignal;

  private boolean isCollectString = false;

  /**
   * Construct.
   *
   * @param parentMarkupId
   * @param busySignal
   * @param isCollectString

   */
  public FakeAjaxFormComponentUpdatingBehavior(String parentMarkupId,
boolean busySignal, boolean isCollectString) {
    super("fake");

    this.busySignal = busySignal;
    this.parentMarkupId = parentMarkupId;
    this.isCollectString  = isCollectString;
  }

  /**
   * @see
org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior#onBind()
   */
  @Override
  protected void onBind() {
    super.onBind();
    if (AjaxRequestTarget.get() != null) {
      getComponent().add(new AttributeAppender("class",true, new
AbstractReadOnlyModel<String>() {
        /**
         * @see org.apache.wicket.model.AbstractReadOnlyModel#getObject()
         */
        @SuppressWarnings("synthetic-access")
        @Override
        public String getObject() {
          if (FakeEventListener.get() == null) {

AjaxRequestTarget.get().addListener(FakeEventListener.getCreate());
          }
          return "FACB"+
FakeEventListener.get().index(FakeAjaxFormComponentUpdatingBehavior.this.parentMarkupId);
        }
      }, " "));
      getComponent().add(new AttributeModifier("bs",true,
Model.of(busySignal)));
    }
  }


  /**
   *
   * @param target
   */
  public void fireOnEvent(AjaxRequestTarget target) {
    onEvent(target);
  }




  /**
   * @see
org.apache.wicket.behavior.AbstractAjaxBehavior#onComponentRendered()
   */
  @Override
  protected void onComponentRendered() {
    super.onComponentRendered();
    String event = getEvent();
    Component component = getComponent();
    if(!isCollectScripts()) {
      onComponentRendered(event, component);
    }
  }

  /**
   * @see
org.apache.wicket.ajax.AjaxEventBehavior#onComponentTag(org.apache.wicket.markup.ComponentTag)
   */
  @Override
  protected void onComponentTag(ComponentTag tag) {
    if(!isCollectScripts()) {
      super.onComponentTag(tag);
    }
  }

  /**
   * @param event
   * @param component
   */
  protected static void onComponentRendered(String event, Component
component) {
    JavascriptUtils.writeOpenTag(component.getResponse());
    component.getResponse().write("$('#" + component.getMarkupId() +
"').change(function() { eval($(this).attr('" + event + "')); });");
    JavascriptUtils.writeCloseTag(component.getResponse());
  }

  /**
   * @return Should scripts be collected.
   */
  protected final boolean isCollectScripts() {
    return isCollectString;
  }

  /**
   * @see
org.apache.wicket.ajax.AbstractDefaultAjaxBehavior#renderHead(org.apache.wicket.markup.html.IHeaderResponse)
   */
  @Override
  public void renderHead(IHeaderResponse response) {
    super.renderHead(response);
    response.renderJavascriptReference(JavaScriptConstants.JS_JQUERY);
    if(isCollectScripts() && AjaxRequestTarget.get() != null) {
      response.renderJavascriptReference(FakeAjaxCheckBox.JS);
      if (FakeEventListener.get() == null) {
        AjaxRequestTarget.get().addListener(FakeEventListener.getCreate());
      }
      FakeEventListener.get().addScript(parentMarkupId);
    }
  }

  /**
   *
   * @param target
   */
  protected abstract void onUpdate(AjaxRequestTarget target);

  /**
   *
   * @return Click script.
   */
  protected String getOnClickScript() {
    CharSequence onClickScript = "$('#" + parentMarkupId + "').trigger('" +
FAKE_EVENT_NAME + "', '" + getComponent().getMarkupId() + "'); return "
        + busySignal + ";";
    IAjaxCallDecorator decorator = getDecorator();
    if (decorator != null) {
      onClickScript = decorator.decorateScript(onClickScript);
    } else if (AjaxRequestTarget.get() != null) {
      return null;
    }
    return onClickScript.toString();
  }



  /**
   * Get decorator. Only {@link
IAjaxCallDecorator#decorateScript(CharSequence)}
   * is used here!
   *
   * @return {@link IAjaxCallDecorator}
   */
  protected IAjaxCallDecorator getDecorator() {
    return null;
  }

  /**
   * @return the parentMarkupId
   */
  public String getParentMarkupId() {
    return parentMarkupId;
  }

  /**
   * @param parentMarkupId the parentMarkupId to set
   */
  public void setParentMarkupId(String parentMarkupId) {
    this.parentMarkupId = parentMarkupId;
  }

  /**
   * @return the isCollectString
   */
  public boolean isCollectString() {
    return isCollectString;
  }

  /**
   * @param isCollectString the isCollectString to set
   */
  public void setCollectString(boolean isCollectString) {
    this.isCollectString = isCollectString;
  }

  /**
   * @return the busySignal
   */
  public boolean isBusySignal() {
    return busySignal;
  }

}




**
Martin


> On Jan 10, 2015 4:43 AM, "Martin Makundi" <
> [email protected]> wrote:
>
> > Hi!
> >
> > I tried to add and idea to
> > https://cwiki.apache.org/confluence/display/WICKET/Ideas+for+Wicket+7.0
> >
> > However I cannot find any edit buttons when Logged in to confluence. The
> > contribution page says anybody can contribute?
> >
> > My idea is related to "Better stateless support
> > <
> >
> https://cwiki.apache.org/confluence/display/WICKET/Ideas+for+Wicket+7.0#IdeasforWicket7.0-Betterstatelesssupport
> > >
> > ":
> >
> >
> >    - Wicket seems to have this inherent MVC design flaw that it's View is
> >    stateful when it would really be sufficient that the Model is stateful
> > and
> >    it does not (and neither does controller) need to be serialized.
> >    - It is possible to tweak to implement stateless View but it's quite a
> >    hack because most event listeners are attached to the hierarcy instead
> > of
> >    page root which would have avoided the need to keep/serialize state of
> > the
> >    view. We have prototypes of "FakeAjaxEventBehavior" which is bound to
> > page
> >    instead of a component; the component event thus invokes the
> page-level
> >    listener (on gui side) and thus in event processing (page level) we
> > don't
> >    need the component itself nor its state.
> >    - Form components, however, are difficult to implement because they
> >    inherently have state in view, but on the other hand it is rare (and
> >    impractical) to actually have 'huge' forms; any such large editing
> areas
> >    will need to be 'worked around' some another way.
> >
> >
> > **
> > Martin
> >
>

Reply via email to