7 Replies Latest reply on Jan 24, 2013 4:29 AM by vikramca06

    form and post as a method to send request parameter?

    kasq Level 3

      Hi all,

       

      I have question about best practice in the CQ to send between 2 pages a parameter using a post method in the form.

       

      I have simple form on page.html like:

       

      <form action="page_2.html" method="POST">

           <input type="hidden" name="flag" value="false" />

      </form>

       

      and using this form the flag parameter must be send to page_2.html.

       

      I'm quite new with this stuff in the CQ, so in advance thanks a lot for any advice.

       

      Regards,

      kasq

        • 1. Re: form and post as a method to send request parameter?
          Willy jojo

          Hey Kasq,

               I would like the answer to this as well. I have a form that is not authorable, that posts to itself. It is basically a calculator to return values based on form values.

           

               Anyone have ideas?

          • 2. Re: form and post as a method to send request parameter?
            Sham HC Level 7

            Hi Kasq/Willy jojo,

             

            Both of you are looking to process the form without storing any information in the JCR. In order to accomplish it you need to implement a post servlet that will handle posts to a custom action.

             

            More details look at /libs/foundation/components/form/actions there are nice examples.

             

            • Configure an overlaid custom form action. /apps/foundation/components/form/actions/<cusotmName> and its properties are mentioned at [0].
            • Have a dialog node defined with fields redirect (this will be used under "Action Configuration" when you add a CQ "Form" component) [1].
            • To handle the request data create a post servlet [2]
            • Configure a Form component and select your custom form action from the dropdown on page A

             

            [0]  {"hint":"Sends all submitted values to the post gateway.","sling:resourceType":"foundation/components/form/action","jcr:createdBy":"admin ","jcr:title":"Custom","jcr:created":"Mon Jan 23 2012 23:58:14 GMT-0500","jcr:primaryType":"sling:Folder"}

             

            [1] 

            <dialog jcr:primaryType="cq:WidgetCollection">

                <redirect jcr:primaryType="cq:Widget" fieldLabel="Redirect URL" name="./redirect" xtype="browsefield"/>

            </dialog>

             

            [2]  

             

            import java.io.IOException;

            import java.util.*;

             

            import javax.servlet.ServletException;

             

            import org.apache.commons.lang.StringUtils;

            import org.apache.sling.api.SlingHttpServletRequest;

            import org.apache.sling.api.SlingHttpServletResponse;

            import org.apache.sling.api.request.RequestParameter;

            import org.apache.sling.api.servlets.OptingServlet;

            import org.apache.sling.api.servlets.SlingAllMethodsServlet;

            import org.slf4j.Logger;

            import org.slf4j.LoggerFactory;

             

             

            import org.apache.sling.api.resource.Resource;

            import org.apache.sling.api.resource.ResourceResolver;

            import org.apache.sling.api.resource.ResourceUtil;

            import org.apache.sling.api.resource.ValueMap;

             

            /**

            * This  servlet accepts POSTs to a form begin paragraph but only if the

            * selector "test" and the extension "html" is used.

            *

            * @scr.component metatype="false"

            * @scr.service interface="javax.servlet.Servlet"

            *

            * @scr.property name="sling.servlet.resourceTypes"

            *               value="foundation/components/form/start"

            * @scr.property name="sling.servlet.methods" value="POST"

            *

            * @scr.property name="service.description" value="Test Form Servlet"

            */

            public class TestFormServlet extends SlingAllMethodsServlet implements

                    OptingServlet {

                private static final long serialVersionUID = -1346698467552285051L;

             

                protected final Logger log = LoggerFactory.getLogger(getClass());

             

                protected static final String EXTENSION = "html";

             

                /** @scr.property name="sling.servlet.selectors" */

                protected static final String SELECTOR = "test";

             

                /**

                 * @see org.apache.sling.api.servlets.OptingServlet#accepts(org.apache.sling.api.SlingHttpServlet Request)

                 */

                public boolean accepts(SlingHttpServletRequest request) {

                    return EXTENSION.equals(request.getRequestPathInfo().getExtension());

                }

             

                /**

                 * @see org.apache.sling.api.servlets.SlingSafeMethodsServlet#doGet(org.apache.sling.api.SlingHtt pServletRequest,

                 *      org.apache.sling.api.SlingHttpServletResponse)

                 */

                @Override

                protected void doGet(SlingHttpServletRequest request,

                        SlingHttpServletResponse response) throws ServletException,

                        IOException {

                    //this.doPost(request, response);

                }

             

                /**

                 * @see org.apache.sling.api.servlets.SlingAllMethodsServlet#doPost(org.apache.sling.api.SlingHtt pServletRequest,

                 *      org.apache.sling.api.SlingHttpServletResponse)

                 */

                @Override

                protected void doPost(SlingHttpServletRequest request,

                        SlingHttpServletResponse response) throws ServletException,

                        IOException {

                       

                    final ValueMap values = ResourceUtil.getValueMap(request.getResource());

                   

                    String flag = values.get("flag", String.class);

                   

                    log.error("Sample  test form servlet executed, properties: " + flag);

                   

                    //Do a redirect.  This is just an example, you can do a forward if you like or something else.

                    //It is up to you how you decide to handle what happens after the post.

                    String redirectTo = request.getParameter(":redirect");

                    if (redirectTo != null) {

                        response.sendRedirect(redirectTo);

                        return;

                    }

                }

             

            }

            • 3. Re: form and post as a method to send request parameter?
              4593029388218911 Level 1

              I'd first ask the question why are you passing the flag to the second page? Does the page display differently if flag is passed -for example without the flag it displays with a right column and if the flag isn't present there is no right column on the second page? Or is the flag eventually going to get persisted somewhere (either in the JCR or in the database.

               

              If the purpose of the flag is to cause the second page to display in a different mode then best practice would not be to use a post with a parameter but rather to use a GET with selector in the URL. So for example you rather then having the form action be page_2.html you have the form action be javascript that just sends the user to page_2.flagtrue.html.

               

              Then in your component code you call slingRequest.getRequestPathInfo().getSelectors() which returns an array and you can iterate over the array and look for your flag. If the flag is present in the array you display one way and if the flag is missing you display the other way. Or if your layout is totally different you can create a JSP in your template named flagtrue.html and you can create a totally differnet appearance of your page. One advantage of this over user a POST or a GET with parameters is that it's fully cachable.

               

              This only works well when you have a fairly well defined set of options, so if you have lots of possible values you are passing in the form then a parameter will work better then a selector. Also if you go down this path you need to pay attention to your dispatcher configuration to ensure you are white listing the selectors that permitted through to the app servers (to prevent DDOS attacks).

               

              If you truely are trying to pass form information that is going to be next page - perhaps because you have a multi-step form - a sort of wizard type of thing - then I would suggest that you might find using GETs rather than POSTs to be easier to work with. The combination of how cq:Page primary type is structured (with the sling resource type being on the jcr:content child node) means that POST parameters are not a good way to pass information from one page to the next. You want to think through why you are passing the information from one page to the next and then consider if there may be a more appropriate design - which may include:

              • Using selectors instead of paramters (again only useful when passing a short known list of options - and really only appropraite when trying to control the display of the next page).
              • If you have a multi-page form moving the user interaction down to the client and creating the effect of a multi-page form using JavaScript to hide/show the appropriate form elements and then posting the complete set of data to a servlet for persistence
              • For something like calculator mentioned a best practice would be a AJAX focused solution where the form posts to a servlet which returns the results - but not actually refreshing the page
              • Passing values from page to page in a cookie (may not be appropriate depending on the type of data). This approach requires that you set the cookie and take actions based on the cookie value all on the client side - if you are taking actions based on the cookie server side your pages can't be cached.
              • 4. Re: form and post as a method to send request parameter?
                kasq Level 3

                Hi,

                 

                First of all thanks a lot for answer. In my case we needed this form to a send a post parameter to avoid first of all sending parameters directly in the url.

                Second thing that in our case recognizing this flag we know if we should shown Disclaimer for a page or not depending on from where the page has been opened.

                 

                We have something like 2 pages - pageA and pageB. On a pageB we have assigned disclaimer. There are two possible scenario:

                 

                First scenario is that on pageA is the link to pageB, if user click on this link the disclaimer is open and in case if it is accepted by user webrowser redirect a user to pageB.

                Second scenario is that if a user found pageB in Google for example, the page is open and disclaimer is show after loading a page.

                 

                The issue is that in the first scenario we would like to use on a pageA a from with flag parameter send in post that tells a pageB do not open a disclaimer. In case if this parameter in the request is null, it means open a disclaimer on pageB (scenario 2) .

                 

                We found some workaround which works at this moment. We are using short life cookies which are set when on pageA when the user accept a disclaimer and is redirected to pageB.

                 

                I hope that now the situation is more clear.

                 

                Reagrds,

                kasq

                • 5. Re: form and post as a method to send request parameter?
                  Willy jojo Level 1

                  So in this example what might the form action="" be?

                  • 6. Re: form and post as a method to send request parameter?
                    aklimets Adobe Employee

                    Some quick clarifications:

                     

                    - if you don't modify anything on the server-side (such as the "calculator" mentioned), use GET instead of POST

                    - use selectors instead of request parameters if you want to benefit from caching (the cq dispatcher won't cache any request including request parameters (?....), but urls with selectors will be cached); so if your calculator is deterministic based on the parameters, use selectors, so the next requests will be served from the dispatcher; if it is e.g. a search and depends on repository or other external data, you don't want caching and use request parameters again

                    - you'd handle request parameters or selectors (as mentioned) inside the relevant component by simply using request.getParameter() or reqeust.getRequestPathInfo().getSelectors()

                    - if you don't use the CQ form components, there is no magic involved, but plain HTML forms; the action would be the target page (e.g. "target.html" or "/fixed/patch/target.html"); if you leave the action empty, the browser will get/post to the current page itself

                    - I agree that an AJAX solution is probably nicer for pure "calculator" style use cases

                     

                    Cheers,

                    Alex

                    • 7. Re: form and post as a method to send request parameter?
                      vikramca06 Level 1

                      Hi,

                       

                      I would like to know how to submit a form with some input fields to another page using sling POST method.

                       

                      example:

                      I have two pages.

                      * one is form page

                      * second page gets the form data and sends email using jsp and java

                      Please help me to do this using POST method

                       

                      Few questions:

                      What should i give in form action?

                      do i need to use sling redirect method or resource?

                      how to get form values from first page to second page?

                       

                      giving example code will really helpful.

                       

                      example form:

                      <form   id="commentForm" method="post" name="checkout" enctype="text/plain" action="/en/cart/checkout/order-confirmation.html">

                          <fieldset>

                             

                              <p>

                                  <label for="cname">Name (required, at least 5 characters)</label>

                                  <input id="cname" name="name" minlength="5" type="text" required />

                              <p>

                                  <label for="cemail">E-Mail (required)</label>

                                  <input id="cemail" type="email" name="email" required />

                              </p>

                       

                              <p>

                                  <label for="ccomment">Address (required)</label>

                                  <textarea id="ccomment" name="comment" required></textarea>

                              </p>

                             

                              <p>

                              <label for="creditcard">Credit Card No</label>

                        <input  type="text" name="creditcard" size="4" maxlength="4" required class="numeric" /><input type="text" maxlength="4" size="4" name="creditcard" required style="width: 40px !important;" class="numeric" /><input maxlength="4" type="text" size="4" name="creditcard" required style="width: 40px !important;" class="numeric"  /> <input  maxlength="4" type="text" size="4" name="creditcard" required style="width: 40px !important;" class="numeric" />

                              </p>

                              <p>

                              <label for="cardccv">CCV No</label>

                              <input type="text" class="numeric" name="cardccv" size="4" maxlength="3" required  />

                              </p>

                              <p>

                                  <input class="btn btn-success" type="submit" value="Place Order"/>

                              </p>

                          </fieldset>

                      </form>

                       

                      Please reply me ASAP.

                      Anyone can reply for this post.

                      Thank you.