Skip to main content

Using YUI3 Panel to send server transaction request from client-side

This article presents a nice way how to save some user-defined input on server and make browser wait for it before proceeding with navigation. This will be shown in a context of my use case that consists in a Cocoon Java application that allows exporting page in PDF format. Exported page is being generated by a specific Java Servlet as soon as the client browser redirects to the corresponding URL. Now assume that the end user wants to set a custom title for the exported page. Thus, we need some kind of interruption when the user clicks on the 'Export' link. It'll be implemented using nice YUI3-based Transaction utility and YUI3 Panel shown below:

Initialize YUI3
To get started with YUI3, you should perform two steps:
  1. Load the YUI javascript file on your web page.
  2. Create and configure a new YUI instance.
Please refer to this manual for code snippets. The only difference is that we'll use two modules: io and panel. Module io is required for transaction utility that will be used later.
YUI().use('io', 'panel', 
function(yui3) {
// Panel code will be here
}

Initialize Panel
First let's add html stub for YUI3 panel:
<div id="input-params-container">
    <div class="yui3-widget-bd">
        <table><tbody><tr>
            <td><label for="export_title">Title</label></td>
            <td><input type="text" name="export_title" id="export_title"/></td>
        </tr></tbody></table>
    </div>
</div>
Second let's initialize YUI3 Panel instance (check official documentation example for panel constructor parameters and this article about transaction utility). See inline comments for details.
panel = new yui3.Panel({
    srcNode: '#input-params-container',
    headerContent: 'Input export title',
    width: 250,
    zIndex: 5,
    centered: true,
    modal: true,
    render: true,
    visible: false
});

panel.addButton({
    value: 'OK',
    section: yui3.WidgetStdMod.FOOTER,
    action: function (e) {
        // Loading user input of export title
        var title = yui3.one("#export_title").get("value");
        // Sending a transaction using YUI3 io
        var uri = "setExportParameters.xml?title=" + title;
        new Transaction({"uri": uri, "sync": true}).execute();
        // Closing modal panel
        this.hide();
        // Redirecting browser to export servlet URL
        // (that is saved in event handler - see below)
        window.location.href = this.get("exportLinkHrefValue");
    }
});

Register event handler functions
Here is the html code snippet of linking image that redirects browser to the export servlet. I added exportLinks id attribute to locate this node from within javascript later as we would like to block redirection until our server transaction is completed.
<span id="exportLinks" style="float: right;">
    <a title="Export to PDF" href="{$contextPath}/export?type=pdf">
        <img style="border: none;" src="resource/external/icons/mimetypes/pdf_16.png" />
    </a>
</span>
This is a click event handler that substitutes default link navigation and show our panel instead. Check official documentation about preventDefault function. See inline comments for details.
yui3.on("click", function (e) {
    // Disabling redirection
    e.preventDefault();
    // Saving export servlet URL in panel instance for later usage
    // (we'll do manual redirection instead - see above)
    panel.set("exportLinkHrefValue", e.target.get('parentNode').get('href'));
    // Showing the panel to user
    panel.show();
}, "#exportLinks img");

Implement Cocoon pipeline and flowscript for transaction
Finally we need to add server-side code. The following Cocoon pipeline will process a transaction call when the end used presses 'OK' button in the modal panel.
<map:match pattern="setExportParameters.xml">
    <map:call function="setExportParameters"/>
</map:match>
Actually the pipeline simply redirects call to a flowscript function. See the official Cocoon documentation about sitemap and flowscript for more details.
// Saves export parameters in ExportDataSource Spring bean
function setExportParameters() {
    var exportDataSource = cocoon.getComponent("exportDataSource");
    exportDataSource.setTitle(cocoon.request.getParameter("title"));
    cocoon.sendStatus(200);
}
That's it! YUI version used is 3.4.1. You may also want to review this article about DynamicReports and Cocoon integration as it's closely related and based on the same Cocoon application.

Comments