How to use the parameters of the EssentialsSearchComponent

EssentialsSearchComponent comes with 2 parts:

  1. the search form (which is available through the Standard-Catalogue)
  2. the search-result page (which is directed to, when the search-form is submitted)

The Component also comes with some parameters declared in EssentialsSearchComponentInfo

Beside a side-wide search, I also want to offer some “page specific search”.
I would like to place the search form on different pages and limit the documentTypes on some pages (e.g. news -page - > limit to )

How can I pass the documentTypes, configured on the Search Form Component to the Search-Component on the search-result page?

Hi Thomas,
You should be able to get the EssentialsSearchComponentInfo class from the “cparam” attribute (as set by #populateRequest from parent EssentialsListComponent), then use its #getDocumentTypes method.

HTH
Jeroen

Hi Jeroen,

do you mean something like
final EssentialsSearchComponentInfo cparam = (EssentialsSearchComponentInfo) requestContext.getAttribute("cparam");

in doBeforeRender-method of my custom component ?
The above code-snippet results in “null” :frowning:

I am currently doing a post-request an make a redirect to annother page. I guess that is the point.
Here is the code:

             @Override
            public void doAction(HstRequest request, HstResponse response) throws stComponentException {
                 super.doAction(request, response);
                 FormMap formMap = new FormMap(request, new String[]{"dt", "query"});

                 logger.info("Search called for docType {} and query-string= {}",
                    formMap.getField("dt").getValue(), formMap.getField("query").getValue());

                request.setAttribute("dt", formMap.getField("dt").getValue());         
                request.setAttribute("query", formMap.getField("query").getValue());

                try {
                    response.sendRedirect("/site/search");
                } catch (IOException e) {
                    logger.error(e.getMessage());
               }
        }

Normally I would return a RedirectView with some attributes, but that is not possible here :frowning: !?

OK I get it, the redirect will go to a page that doesn’t have the same component.

You could use response.setRenderParameter() to communicate parameter values. These will show as public request parameters that you can read.

Also I advise you to use BaseHstComponent#sendRedirect() when redirecting, using site map item, not a hardcoded context path “/site/search” that will probably fail in live environment.

Regards, Jeroen

Hie Jeroen,

unfortunately that still does not work.
I changed my code to the following:

 @Override
public void doAction(HstRequest request, HstResponse response) throws HstComponentException {
    super.doAction(request, response);
    FormMap formMap = new FormMap(request, new String[]{"dt", "query"});

    logger.info("Search called for docType {} and query-string= {}",
            formMap.getField("dt").getValue(), formMap.getField("query").getValue());

    response.setRenderParameter("dt", formMap.getField("dt").getValue());
    response.setRenderParameter("query", formMap.getField("query").getValue());

    HstLinkCreator linkCreator = request.getRequestContext()
            .getHstLinkCreator();
    // create HstLink
    HstLink link = linkCreator.createByRefId("search", this.getMount(request));
    // create the url String

    String Url = link.toUrlForm(request.getRequestContext(),false);

    this.sendRedirect(Url,request,response);

}

In doBeforeRender I have:

     @Override
    public void doBeforeRender(HstRequest request, HstResponse response) {
        super.doBeforeRender(request, response);

        logger.info("Received query-Attribute from request: {}",
                request.getAttribute("query"));

        this.cleanupSearchQuery(this.getAnyParameter(request, "query"));
        final EssentialsSearchComponentInfo componentParametersInfo = this.getComponentParametersInfo(request);
        request.setAttribute("docType", componentParametersInfo.getDocumentTypes());
    }

There are still 2 problems:

  1. request.getAttribute is still null, expected is “Portal” (tested with hardcoded redirect url!) from

response.setRenderParameter("query", formMap.getField("query").getValue());

and the created link resolves in
http://localhost/site/site/search
and not
http://localhost/site/search

Any further tips ??

So are you redirecting in code to your own page? If so, why, since that part is an out-of-the-box feature. by the Post Redirect Get pattern already used. Then just request.setAttribute("docType", componentParametersInfo.getDocumentTypes()); should be enough.

Otherwise to get a request parameter set by #setRenderParameter, use #getPublicRequestParameter.
If you do want to redirect, how about sendRedirect("search",request,response) where “search” is an existing site map item.

HTH
Jeroen

Hi Jeroen,

Yes- that is correct. But unfortunatelly
request.setAttribute("docType", componentParametersInfo.getDocumentTypes())
The reason is not to prevent double submission, but hiding query-parameters (see also explanation of use case at the end)

does not work with the redirect - It even does not work without redirect (from action-phase to render phase / at least in my case :frowning: ).

I made a couple of test.
I put a second searchBox on my page, both call the same component. The form is submittet by post:

In “doAction” I put the following lines:

response.setRenderParameter("test", "set test by response.setRenderParameter");
request.setAttribute("test2", "set test2 by request.setAttribute);

Then in doBeforeRender I try to get them with:

this.getAnyParameter(request, "test");
this.getPublicRequestParameter(request,"test");
request.getAttribute("test2); 

Only
this.getAnyParameter(request, "test");

works - but only for the one component, which did the post!

With redirecting, even that does not work!

I took a look at what BaseHstComponent#sendRedirect does!
It calls HSTResponseUtils#sendRedirect at at the end this class calls
response.sendRedirect(urlString);

I can not detect where attributes are passed with the redirect. I know 2 approaches with Spring .

  1. return a RedirectView Object alog with RedirectAttributes
  2. return a ModelAndView object along with a ModelMap

The only way I found was to add queryParams to the redirect- but that ends up in url-Parameters -what I would like to prevent.

Maybe to better understand I explain the use case:
Different to the “out the box” - implementation of the search-component, where a form with a query-string input, submits to a searchg-page by a get request. So the query-string is submitted as an url-parameter.

I would like to add additional query-parameters, from ComponentInfo and user-input!
I would like to hide these query-parameters. Thererfore I need to do a post-request.
With that approach I can put the search-box on different pages- with different configuration, so that the user can perform a scoped search, with a unique user-experience :slight_smile:

OK so it looks like response#setRenderParameter sets a namespaced (component specific) parameter so indeed use #getAnyParameter or request.getParameter(), rather than #getPublicRequestParameter.

So you want a POST, which triggers the #doAction. You will get a redirect to same page out-of-the-box, do please don’t redirect yourself. You’ll get a GET which is a new request. See https://documentation.bloomreach.com/14/library/concepts/component-development/hst-2-forms.html

Transferring parameter values from POST to GET can be done:

  • by #setRenderParameter, which will be a URL-parameter of the GET
  • by saving/retrieving FormMap object to and from the repository (as used by EForms module)
  • in HTTP session (but usually the site is session-free)
  • in a cookie (why not)

Hope this helps, Jeroen

Thank’s for your support and patience.

Of course, this helps!

Update:
After some more tests, I went back to start - At the end it is very simple- you were totally right with your statement:

I would like to share my success with the community :slight_smile:

I can keep the “out-of the box” configuration and only add Method = “Post” to action url to hide the url-parameters

<form class="navbar-form" role="search" action="<@hst.link siteMapItemRefId="search" />" method="Post">

Doing so I can get ComponentInfo Params in my component and put them in the request by:
request.setAttribute("cparam", getComponentParametersInfo(request));

In the form I add a hidden field:

 <#if cparam.documentTypes??>
        <input type="hidden" name="doctypes" value="${cparam.documentTypes}">
 </#if>

In the receiving component, this value is available via:

final String doctypes = getAnyParameter(request, "doctypes");