On Thu, Nov 19, 2009 at 1:10 AM, Thiago H. de Paula Figueiredo <
thiag...@gmail.com> wrote:

> Em Wed, 18 Nov 2009 20:00:22 -0200, Ilya Obshadko <ilya.obsha...@gmail.com>
> escreveu:
>
>
>  Finally, I've managed to create generic-purpose mixin that can trigger
>> form submit on any type of event and on any element within t:form component.
>> It works using standard Tapestry mechanisms (similarly to original Submit
>> component), supports multiple submit triggers within single form
>> (analogous to multiple submit buttons).
>>
>
> Please post it here. :)
>
>
Okay.

Mixin source:

@IncludeJavaScriptLibrary("submitonevent.js")

public class SubmitOnEvent {

    @Environmental

    private RenderSupport renderSupport;



    @Environmental

    private FormSupport formSupport;



    @InjectContainer

    private ClientElement container;



    @Inject

    private ComponentResources resources;



    @Inject

    private Request request;



    /**

     * Component event that triggers form submission; must be the name of
REAL JavaScript

     * event (click, change, blur etc.)

     */

    @Parameter(required=true,allowNull=false,defaultPrefix="literal")

    private String monitorEvent;



    /**

     * Tapestry submit event name that will be simulated during form
submission

     */

    @Parameter(required=true,allowNull=false,defaultPrefix="literal")

    private String submitEvent;



    /**

     * ID of the field that MUST have a value before form submission.

     * If field is empty, event is not triggered.

     */

    @Parameter(required=false,allowNull=false,defaultPrefix="literal")

    private String requiredField;



    /**

     * Form submit context

     */

    @Parameter(required=false,allowNull=false,defaultPrefix="prop")

    private Object[] submitContext;


    private static class ProcessFakeSubmission
implementsComponentAction<SubmitOnEvent> {

        private static final long serialVersionUID = -2205200857980521346L;

        private String fakeSubmitName;


        public ProcessFakeSubmission ( String fakeSubmitName ) {

            this.fakeSubmitName = fakeSubmitName;

        }


        public void execute ( SubmitOnEvent component ) {

            component.processFakeSubmission ( fakeSubmitName );

        }

    }



    public void afterRender () {

        final String formId = formSupport.getClientId ();

        formSupport.store ( this, new ProcessFakeSubmission ( "submit_" +
container.getClientId () ) );

        renderSupport.addInit ( "submitOnChange",

                new JSONArray ( monitorEvent, formId, container.getClientId
(), requiredField ) );

    }



    private void processFakeSubmission ( String elementName ) {

        String value = request.getParameter ( elementName );


        if ( value == null )

            return;


        Runnable sendNotification = new Runnable () {

            public void run () {

                resources.triggerEvent ( submitEvent, submitContext, null );

            }

        };


        formSupport.defer ( sendNotification );

    }


}

and JavaScript:

Tapestry.Initializer.submitOnChange = function(eventName, formId, elementId,
requiredField) {

    $(elementId).observe (eventName, function(event) {

        if ( ( requiredField && $(requiredField).value ) || ! requiredField
) {

            var hiddenSubmit = document.createElement("input");

            hiddenSubmit.type = "submit";

            hiddenSubmit.name = "submit_" + elementId;

            hiddenSubmit.style.visibility = "hidden";

            hiddenSubmit.style.display = "none";

            $(formId).appendChild(hiddenSubmit);

            hiddenSubmit.click();

        }

    });

};

The idea behind 'requiredField' parameter is simple: if parameter is
specified, this field must be filled in before triggering submit
event. Probably it's better to leave that up to Tapestry built-in
client-side validation, but I don't use it in my project (it's very
intrusive and its visual features doesn't fit the website design).

Enjoy!

-- 
Ilya Obshadko

Reply via email to