1

Does it makes sense to merge these several hidden forms on a single page into just one single big form?

To submit a particular set of parameters belonging to a particular form process attribute could be used to submit all elements required to be processed.

What are the pro/cons of this single form approach over using several forms?

   <span class="hiddenForms">
        <h:form>
            <h:inputHidden id="selctdChnlType_in" value="#{channelCntlr.type}"/>
            <h:inputHidden id="selctdChnlId_in" value="#{channelCntlr.channelId}"/>
            <p:remoteCommand name="updateChnlDataPanel" process="@form" actionListener="#{channelCntlr.init()}" update=":channelHeader, :channelDataPanel, :channelSideColumn"/>
        </h:form>

        <h:form>
            <h:inputHidden id="selctdLOBId_in" value="#{lobCntlr.targetLOBId}"/>
            <p:remoteCommand name="updateLOBPanel" process="selctdLOBId_in, @this" actionListener="#{lobCntlr.retrieveCurrentLOB()}" update=":lobFullContentPanel" />
        </h:form>

        <h:form id="lobAction_form" >
            <h:inputText id="targetLOBId_in" value="#{lobCntlr.targetLOBId}"/>
            <h:inputText id="targetResponseId_in" value="#{lobCntlr.targetResponseOrCommmentId}"/>
            <h:inputText id="targetAction_in" value="#{lobCntlr.targetAction}"/>
            <p:remoteCommand name="doLOBAction" process="targetLOBId_in, targetAction_in, targetResponseId_in,@this" actionListener="#{lobCntlr.doLOBAction()}"/>

            <h:inputText id="targetTopics" value="#{lobCntlr.list}" converter="listConverter"/>
            <p:remoteCommand name="suggestAsHotLOB" process="targetLOBId_in, targetTopics, @this" actionListener="#{lobCntlr.addForTryAsHotLOB()}"/>
        </h:form>

        <h:form id="comment_form" >
            <h:inputText id="targetLOBId_in" value="#{lobCntlr.targetLOBId}"/>
            <h:inputText id="targetCommentOrResponseId_in" value="#{lobCntlr.targetResponseOrCommmentId}"/>
            <h:inputText id="comment_in" value="#{lobCntlr.text_input}" required="true">
                <f:validateLength minimum="15" maximum="1000"/>
            </h:inputText>
            <h:inputText id="previousCommenters_in" value="#{lobCntlr.list}" converter="listConverter"/>

            <p:remoteCommand name="addComment" process="@form" actionListener="#{lobCntlr.addUserComment()}" oncomplete="addCommentToPage(args);" />
            <p:remoteCommand name="deleteComment" process="targetLOBId_in, targetCommentOrResponseId_in, @this" actionListener="#{lobCntlr.removeUserComment()}"  oncomplete="removeFromPage(args);" />
        </h:form>

        <h:form id="recosForm">
            <h:inputText id="startFromRecos_in" value="#{recmdnsCntlr.startFromIndex}"/>
            <p:remoteCommand name="fetchAllRecos" actionListener="#{recmdnsCntlr.retrieveAllRecmmndns()}" process="startFromRecos_in,howManyRecos_in,isLocalStorAvailble_in,@this" />
            <p:remoteCommand name="fetchFollowiesList" actionListener="#{recmdnsCntlr.fetchAllFollowiesList()}" process="@this" oncomplete="storeFollowiesList(args)"/>
        </h:form>

        <span id="editsForm" style="display:none">
            <form action="javascript:void(0);" class="edits_submitter" >
                <p:inputTextarea styleClass="editedText"/>
                <input type="submit" value="Save edits"/>
                <a class="cancel-edit" href="javascript:void(0)">Cancel</a>
            </form>
        </span>

    </span>
Rajat Gupta
  • 25,853
  • 63
  • 179
  • 294

2 Answers2

5

A major con to the single, monolithic JSF form control is the sheer volume of data that is (needlessly) sent to the server for processing. Using your existing code. Consider the following. If all the controls in <h:form id="lobAction_form" > and <h:form id="comment_form" > were in a single form, you'd have

     <h:inputText id="targetLOBId_in" value="#{lobCntlr.targetLOBId}"/>
        <h:inputText id="targetResponseId_in" value="#{lobCntlr.targetResponseOrCommmentId}"/>
        <h:inputText id="targetAction_in" value="#{lobCntlr.targetAction}"/>
        <p:remoteCommand name="doLOBAction" process="targetLOBId_in, targetAction_in, targetResponseId_in,@this" actionListener="#{lobCntlr.doLOBAction()}"/>

        <h:inputText id="targetTopics" value="#{lobCntlr.list}" converter="listConverter"/>
        <p:remoteCommand name="suggestAsHotLOB" process="targetLOBId_in, targetTopics, @this" actionListener="#{lobCntlr.addForTryAsHotLOB()}"/>
        <h:inputText id="targetLOBId_in" value="#{lobCntlr.targetLOBId}"/>
        <h:inputText id="targetCommentOrResponseId_in" value="#{lobCntlr.targetResponseOrCommmentId}"/>
        <h:inputText id="comment_in" value="#{lobCntlr.text_input}" required="true">
            <f:validateLength minimum="15" maximum="1000"/>
        </h:inputText>
        <h:inputText id="previousCommenters_in" value="#{lobCntlr.list}" converter="listConverter"/>

        <p:remoteCommand name="addComment" process="@form" actionListener="#{lobCntlr.addUserComment()}" oncomplete="addCommentToPage(args);" />
        <p:remoteCommand name="deleteComment" process="targetLOBId_in, targetCommentOrResponseId_in, @this" actionListener="#{lobCntlr.removeUserComment()}"  oncomplete="removeFromPage(args);" />
    </h:form>

For every command action that you initiate in that form, possibly to process 1 input text component, you'd always be sending all 13 components in there to the server anyway. Wasteful and unnecessary. You'll have high volume of client-server communications for small operations and sometimes slow response times. Depending on whatever JSF framework you're using, you might be able to get creative with this situation, selectively processing components and what not, but that is just needless and painful. Clean separation of concerns also comes into play in the presentation layer.

Then there is the problem of validation. More often than not, you will have selected components in a single form that are marked as required and have nothing to do with the rest of the components within that form. You'll most likely be unable to selectively process those components without affecting all the other components on that form.

kolossus
  • 20,559
  • 3
  • 52
  • 104
  • Could you also clarify whether all input fields are submitted even when I explicitly specify in `p:remoteCommand`'s `process` attribute what all fields to process ? – Rajat Gupta Nov 15 '12 at 12:45
  • @user01, that's what I meant by "selectively processing components". Specifying the component ids in `process` is deciding what should be processed on the server side, allowing you to reduce overall processing overhead – kolossus Nov 16 '12 at 06:43
0

I see you're using primefaces. You could consider the use of Wizard component. With this component there is a single form with more sections in different tabs. The validation is done in Ajax mode when you go from one tab to the next one. As the partial validation is done with Ajax, only the fields of the tab you are validating, are processed and sent to the server.

It is also useful to split long forms in more readable and user friendly sections.

Daniela Mogini
  • 299
  • 1
  • 5
  • 17