Search code examples
richfaces

rich:fileupload in rich:popupPanel fails first time, in a large page


I have rich:datatable and bunch of buttons at the bottom of a XHTML. I use one of the buttons to show rich:popupPanel to upload a file. I separated rich:popupPanel with rich:fileUpload into different forms based on earlier suggestions.

1st form:

<h:form id="form" enctype="multipart/form-data">
    <h:panelGrid columns="1" columnClasses="valign">

        <rich:messages/>

        <rich:panel style="width:1100px;">                  
            <f:facet name="header">
                <h:outputText value="MRM Segments" />
            </f:facet>

            <rich:dataTable value="#{couponController.campaignSegmentDtoList}"
                var="campaignSegment" id="sas" rowClasses="odd-row, even-row"
                styleClass="stable" sortMode="single" rowKeyVar="myrow" onrowclick="myFunction()">

                <rich:column>
                    <f:facet name="header">No</f:facet>
                    <h:outputText value="#{myrow + 1}" />
                </rich:column>

                <!-- snipped -->

            </rich:dataTable>

            <script>
                //<![CDATA[
                function updateNumbers() {
                    var a = document.getElementById('form:sas:tb');
                    for (var i=0; i < a.children.length; i++) {
                        a.children[i].children[0].innerHTML = i + 1;
                    }
                }   
                //]]>
            </script>

            <a4j:outputPanel ajaxRendered="true">
                <rich:popupPanel id="confirmPaneStatus" autosized="true" header="Confirm">
                    <table border="0" cellspacing="0" cellpadding="0">
                        <tr><td colspan="3">Are you sure you want to set all
                            segments with numeric names as Inactive ?</td></tr>
                        <tr><td colspan="3"><br/></td></tr>
                        <tr><td align="right">
                            <a4j:commandButton value="Cancel"
onclick="#{rich:component('confirmPaneStatus')}.hide(); return false;" />
                        </td><td align="left">
                            <a4j:commandButton value="Update"
onclick="#{rich:component('confirmPaneStatus')}.hide(); updateStatus(); return false;" style="margin-left:15px"/>
                        </td></tr>  
                    </table>
                </rich:popupPanel>
            </a4j:outputPanel>

            <a4j:outputPanel ajaxRendered="true">
                <rich:popupPanel id="errorPane" autosized="true" header="Error" >
                    <table border="0" cellspacing="0" cellpadding="0">
                        <tr><td colspan="3">Only .xlsx files are accepted</td></tr>
                        <tr><td colspan="3"><br/></td></tr>
                        <tr><td align="right">
                            <a4j:commandButton value="Close" onclick="#{rich:component('errorPane')}.hide();" />
                        </td></tr>  
                    </table>
                </rich:popupPanel>
            </a4j:outputPanel>                                                              

            <a4j:jsFunction name="updateStatus"
                action="#{couponController.updateCampaignSegmentDtoListWithSegmentStatus()}"
                render="sas" immediate="true"/>
            <a4j:jsFunction name="sort" oncomplete="updateNumbers()" />

        </rich:panel>
    </h:panelGrid>

    <h:panelGrid columns="7">
        <a4j:commandButton value="Apply Segment Type"  render="sas"
            action="#{couponController.updateCampaignSegmentDtoListWithSegmentType()}"
            execute="@form" style="width:140px;height:30px;"/>
        <a4j:commandButton value="Apply Segment Status" render="sas"
            execute="@form" style="width:150px;height:30px;">
            <rich:componentControl target="confirmPaneStatus" operation="show"/>
        </a4j:commandButton>
        <a4j:commandButton value="Upload Segment Names" execute="@none" 
            style="width:160px;height:30px;">
            <rich:componentControl target="uploadSegmentNames"
                operation="show" />
        </a4j:commandButton>
        <a4j:commandButton value="Save"  render="sas"
            action="#{couponController.saveCampaignSegmentsReadyToPublish()}" 
            execute="@form" style="width:78px;height:30px;"/>
        <a4j:commandButton value="Publish"  render="sas"
            action="#{couponController.publishCampaignSegmentsReadyToPublish()}"
            execute="@this" style="width:78px;height:30px;"/>
        <a4j:commandButton value="Re-Publish"  render="sas"
            action="#{couponController.rePublishCampaignSegmentsReadyToPublish()}"
            execute="@this" style="width:78px;height:30px;"/>
        <h:commandButton onclick="location.href='CampaignsVersions.jsf';return false;"
            value="Cancel" style="width:78px;height:30px;"></h:commandButton>
    </h:panelGrid>

    <rich:popupPanel id="statPane" autosized="true">
        <h:graphicImage value="/images/please_wait.gif" alt="pw" />
        Please wait...
    </rich:popupPanel>

    <script type="text/javasript">
        $(window).load(function() {
            // Animate loader off screen
            $(".statPane").fadeOut("slow");;
        });
    </script>
</h:form>

2nd form:

<h:form id="uploadForm" enctype="multipart/form-data">
    <a4j:outputPanel ajaxRendered="true">
        <rich:popupPanel id="uploadSegmentNames" modal="true" autosized="true" 
            header="Upload Names File" domElementAttachment="parent">

            <rich:messages/>
            <rich:panel style="width:400px;height:300px;">
                <table border="0" cellspacing="0" cellpadding="0">
                    <tr>
                        <td colspan="3">
                            <rich:fileUpload id="upload" acceptedTypes="xlsx"
                                fileUploadListener="#{couponController.fileUploadListener}" 
                                immediateUpload="true" maxFilesQuantity="1"
                                ontyperejected="#{rich:component('errorPane')}.show();"
                                style="width:370px" addLabel="Choose File" 
                                doneLabel="Upload Complete" execute="@none"
                                serverErrorLabel="Error, please close the upload window and try again"> 
                            </rich:fileUpload>
                        </td>
                    </tr>
                    <tr><td colspan="3"><br/></td></tr> 
                </table>
            </rich:panel>
            <h:panelGrid columns="2" style="width:400px;height:20px;" align="right">
                <h:panelGrid columns="1" border="0" style="width:260px;height:20px"/>

                <h:panelGrid columns="2" border="0">
                    <a4j:commandButton value="Process" id="process"
                        action="#{couponController.processFile}" render="sas"
                        onclick="#{rich:component('uploadSegmentNames')}.hide();"
                        execute="@form" />
                    <a4j:commandButton value="Cancel" execute="@none"
                        onclick="#{rich:component('uploadSegmentNames')}.hide();" />
                </h:panelGrid>
            </h:panelGrid>

        </rich:popupPanel>
    </a4j:outputPanel>
</h:form>

Table could be having 10 row or 350 rows or in between. Problem is when table is big, upload fails for the first time. If I close the upload popup and try again. It works. This is happening only with big table. I greatly appreciate your help.

I'm using Tomcat 7 and Richfaces 4.5.1.


Solution

  • Solved. Bigger the table, bigger the ViewState calculated. I noticed it by debugging the upload XMLHttpRequest url and comparing both cases (with small table and large table). Increasing maxHttpHeaderSize to 65536 solved the issue. My state saving method is 'client'.