WysiwygEditor with Ajax

57 views
Skip to first unread message

Jan Dohrmann

unread,
Sep 9, 2014, 8:51:50 PM9/9/14
to wicket-j...@googlegroups.com
Hi Sebastien,

Which ajax behaviors can I add to the WysiwygEditor? I tried with OnChangeAjaxBehavior and AjaxFormComponentUpdatingBehavior.

I need to "auto save" all changes in the Editor.

Best Regards
Jan

Sebastien

unread,
Sep 10, 2014, 7:56:12 AM9/10/14
to wicket-j...@googlegroups.com
Hi Jan,

The bootstrap-wysiwyg (the jquery plugin) does not provide such feature. But you can attach an event to the underlying Container (not the underlying TextArea!). That's also means that you cannot attach a form input related event/behavior ('change' / OnChangeAjaxBehavior). So 'keyup' seems to be a good compromise:

        DefaultWysiwygToolbar toolbar = new DefaultWysiwygToolbar("toolbar");
        final WysiwygEditor editor = new WysiwygEditor("wysiwyg", Model.of(""), toolbar);
        form.add(editor, toolbar);
       
        editor.get("container").add(new AjaxEventBehavior("keyup") {
           
            private static final long serialVersionUID = 1L;

            @Override
            protected void onEvent(AjaxRequestTarget target)
            {
                MyPage.this.info("Saving...");
               
                target.add(feedback);
            }
        });

Hope this helps,
Sebastien.


--
You received this message because you are subscribed to the Google Groups "wicket-jquery-ui" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wicket-jquery-...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wicket-jquery-ui/4ea77c41-319a-453e-9bd5-1c628908c362%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jan Dohrmann

unread,
Sep 10, 2014, 12:53:03 PM9/10/14
to wicket-j...@googlegroups.com
It helps. Thank you for a quick response while you are busy.

Best Regards

Jan Dohrmann

unread,
Sep 10, 2014, 1:50:07 PM9/10/14
to wicket-j...@googlegroups.com
Hi Sebastien,

The wysiwyg do not update the model before a submit. Any hint about how to access the entered text before a submit inside the key-up AjaxEventBehavior code. Just a hint if you have an idea.

Best Regards
Jan

Sebastien

unread,
Sep 10, 2014, 1:54:51 PM9/10/14
to wicket-j...@googlegroups.com
Hi Jan

Hi Sebastien,

The wysiwyg do not update the model before a submit.
Yes, this is the normal behavior, the model is updated after submit, if no error
 
Any hint about how to access the entered text before a submit inside the key-up AjaxEventBehavior code. Just a hint if you have an idea.
#getValue() should return the text
 

Best Regards
Jan



Best regards,
Sebastien.

Jan Dohrmann

unread,
Sep 10, 2014, 1:59:25 PM9/10/14
to wicket-j...@googlegroups.com
Txs Sebastien,

Tried getValue on the editor. It is not "filled" before the submit.

Best Regards
Jan

Sebastien

unread,
Sep 10, 2014, 2:06:14 PM9/10/14
to wicket-j...@googlegroups.com
How, you get a point! Actually that's because we did not submit it (AjaxEventBehavior does not post)

Ok, try to bind AjaxFormComponentUpdatingBehavior("keyup") to the editor directly and let me know, thanks.

--
You received this message because you are subscribed to the Google Groups "wicket-jquery-ui" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wicket-jquery-...@googlegroups.com.

Jan Dohrmann

unread,
Sep 10, 2014, 2:17:20 PM9/10/14
to wicket-j...@googlegroups.com
The behavior works on the editor but the value is not updated.


Jan Dohrmann

unread,
Sep 10, 2014, 2:35:20 PM9/10/14
to wicket-j...@googlegroups.com
I will try to implement a self-submitting form. Not a pretty solution...

Best Regards
Jan

Sebastien

unread,
Sep 10, 2014, 2:46:32 PM9/10/14
to wicket-j...@googlegroups.com
I am sorry, I don't have a better solution. I tried something else (posting, #inputChanged and #convertInput) but it does not work either due to the nature of the component (the fact that the textarea is not updated while you are typing...)

--
You received this message because you are subscribed to the Google Groups "wicket-jquery-ui" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wicket-jquery-...@googlegroups.com.

Jan Dohrmann

unread,
Sep 10, 2014, 3:18:20 PM9/10/14
to wicket-j...@googlegroups.com
Thank you for your the help. I will post a solution.

Best Regards
Jan

Maxim Solodovnik

unread,
Sep 11, 2014, 12:54:53 AM9/11/14
to wicket-j...@googlegroups.com
I believe component should be modified to implement this
I would add client side script updating model every X seconds (keyUp seems to be too annoying)

Martin Grigorov

unread,
Sep 11, 2014, 2:14:38 AM9/11/14
to wicket-j...@googlegroups.com
You can use AjaxRequestAttributes' throttleing for that.

Sebastien

unread,
Sep 11, 2014, 4:02:39 AM9/11/14
to wicket-j...@googlegroups.com
Hi Jan, Maxim, Martin,

Right, keyup isn't the best as it will send many requests, a timer would be better... I also think the component should be modified to integrate this.
@Jan, could you open an issue in GitHub so I take care of this?

Thanks & best regards,
Sebastien.

Jan Dohrmann

unread,
Sep 11, 2014, 10:30:11 AM9/11/14
to wicket-j...@googlegroups.com
Hi Sebastien,

I started on a solution but it just not work yet maybe you can see why. Here is the essential code(not all) - see below. Form is submitted by timer but models are not updated. I could open a issue but maybe I could provide you will a template for a solution first. Keyup is not to bad - it can be set on the form, the editor container or the editor. It only fires once per click.

Beside using a timer I tried to generate a form submit from the keyup code itself. I am trying to say that the structure could be optimized but right now I do not understand may my form submit do notuopdate the models but a ajaxbutton submit does.


editor.get("container").add(new AjaxEventBehavior("keyup")
{
   @Override
   protected void onEvent(AjaxRequestTarget target)
   {
      // Copy input from <div> to <text-area> on keyup - this works - can see it in the dom
      target.appendJavaScript("$('#" + editor.getMarkupId() + "> textarea').html($('#" + editor.get("container").getMarkupId() +"').html())");               
   }
}

// Adding a timer to the form - see AjaxTimerFormSubmitBehavior implementation below
form.add(new AjaxTimerFormSubmitBehavior(form, Duration.seconds(1))
{
    @Override
    protected void onSubmit(AjaxRequestTarget target)
    {
       // This method is called but the models are not set?
       logger.debug(recordModel.getObject().getValue());
       logger.debug(editor.getValue());
    }
    @Override
     protected void onError(AjaxRequestTarget target)
     {
     }
});

// The timer behaviour
public abstract class AjaxTimerFormSubmitBehavior extends AbstractAjaxTimerBehavior
{
    private Form<?> __form;

    private boolean defaultProcessing = true;

    public AjaxTimerFormSubmitBehavior(Duration updateInterval)
    {
        this(null, updateInterval);
    }

    public AjaxTimerFormSubmitBehavior(Form<?> form, Duration updateInterval)
    {
        super(updateInterval);
        __form = form;

        if (form != null)
        {
            form.setOutputMarkupId(true);
        }
    }

    @Override
    protected void onTimer(final AjaxRequestTarget target)
    {
        getForm().getRootForm().onFormSubmitted(new IFormSubmitter()
        {
            public Form<?> getForm()
            {
                return AjaxTimerFormSubmitBehavior.this.getForm();
            }

            public boolean getDefaultFormProcessing()
            {
                return AjaxTimerFormSubmitBehavior.this.getDefaultProcessing();
            }

            public void onSubmit()
            {
                AjaxTimerFormSubmitBehavior.this.onSubmit(target);
            }

            public void onError()
            {
                AjaxTimerFormSubmitBehavior.this.onError(target);
            }

            public void onAfterSubmit()
            {
            }
        });
    }

    public final Form<?> getForm()
    {
        if (__form == null)
        {
            __form = findForm();

            if (__form == null)
            {
                throw new IllegalStateException("form was not specified in the constructor and cannot " + "be found in the hierarchy of the component this behavior " + "is attached to: Component=" +                        getComponent().toString(false));
            }
        }
        return __form;
    }

    public boolean getDefaultProcessing()
    {
        return defaultProcessing;
    }

    protected Form<?> findForm()
    {
        // try to find form in the hierarchy of owning component
        Component component = getComponent();
        if (component instanceof Form<?>)
        {
            return (Form<?>) component;
        } else
        {
            return component.findParent(Form.class);
        }
    }

    protected abstract void onSubmit(AjaxRequestTarget target);

    protected abstract void onError(AjaxRequestTarget target);
}

Best Regards
Jan

Jan Dohrmann

unread,
Sep 11, 2014, 10:51:39 AM9/11/14
to wicket-j...@googlegroups.com
Hi Maxin and Martin,

I first see you comments know. So a timer would be the right solution. Is the auto form submit I suggested a bad idea? Should the client just send an ajaxcall? I have not worked with AjaxRequestAttributes.

Best Regards
Jan

Sebastien

unread,
Sep 11, 2014, 10:51:53 AM9/11/14
to wicket-j...@googlegroups.com
Hi Jan,

> Copy input from <div> to <text-area> on keyup - this works - can see it in the dom

I do not totally agree with the approach consisting of copying div text to textarea. I think you somehow shortcut the editor's behavior...

It's hard to me to answer this specific question without looking at / remembering the editor's code in detail. I think the best is to try to find an embedded solution, so feel free to open the issue and I will manage this as soon as... I've got 5 free minutes :) (hard to find, but probably this WE...)

Best regards,
Sebastien

Jan Dohrmann

unread,
Sep 11, 2014, 11:14:48 AM9/11/14
to wicket-j...@googlegroups.com
Hi Sebastien,

I opened a issue.

Agree with your comment about copying from div to text-area - it is a dual implementation of what happens in javascript code of the native editor - just needed for testing.

Mean issue for me was why form auto submit does not work. But if you can do it in 5 min (when you have time) I am going to wait due to the fact that it is the first time I went down to the javascript level from Wicket. I know javascript and jQuery but do not have the full view of how Wicket use it (archicture). I am going to learn from the masters...

Best Regards
Jan

Sebastien

unread,
Sep 11, 2014, 3:18:51 PM9/11/14
to wicket-j...@googlegroups.com
Hi Jan,

So actually you can do it without I have to update the code:


        DefaultWysiwygToolbar toolbar = new DefaultWysiwygToolbar("toolbar");
        final WysiwygEditor editor = new WysiwygEditor("wysiwyg", Model.of(""), toolbar);

        form.add(editor, toolbar);

        editor.add(new AbstractAjaxTimerBehavior(Duration.ONE_SECOND) {


            private static final long serialVersionUID = 1L;

            @Override
            protected void updateAjaxAttributes(AjaxRequestAttributes attributes)
            {
                super.updateAjaxAttributes(attributes);

                attributes.getDynamicExtraParameters().add(String.format("return { 'text': jQuery('#%s').text() }", editor.getEditorMarkupId()));
            }

            @Override
            protected void onTimer(AjaxRequestTarget target)
            {
                String value = RequestCycleUtils.getQueryParameterValue("text").toString();

                // TODO: do here want you want to do with the value
                info(String.format("%s - %s", new Date().toString(), value));
                target.add(feedback);
            }
        });


Please do *not* close the issue, I will use it to remember writing a wiki.

Thanks and best regards,
Yoda - no I'm kidding :)

Jan Dohrmann

unread,
Sep 11, 2014, 3:47:14 PM9/11/14
to wicket-j...@googlegroups.com
Thank you Sebastien,

I stress tested and it went direct into production. This is fantastic!

I will not close the issue. Did not know the AjaxRequestAttributes possibility so I also learned something new today.

Best Regards
Jan
Message has been deleted

Sebastien

unread,
Sep 11, 2014, 6:17:34 PM9/11/14
to wicket-j...@googlegroups.com
Right, use jQuery('#%s').html() instead

On Thu, Sep 11, 2014 at 11:57 PM, Jan Dohrmann <dohrm...@gmail.com> wrote:
Small comment the code do not pickup any formatting from the text field like <b></b>. It gives the pure text

Best Regards
Jan

--
You received this message because you are subscribed to the Google Groups "wicket-jquery-ui" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wicket-jquery-...@googlegroups.com.
Reply all
Reply to author
Forward
Message has been deleted
0 new messages