Gravatar for shirazi@rdacorp.com

Question by aga, Oct 29, 2015 5:32 PM

Adding Search Box hides the Coveo Search Sublayout

Hi

I'm using the default search page created from sitecore and I added a Header sublayout that contains a placeholder for a SearchBox. The idea is to have the search box in the global header. After I add a Search Box sublayout to the header's placeholder the Coveo Seach sublayout doesnt render. There are no JS errors and the the markup is just not generated.

Any thoughts?

1 Reply
Gravatar for jflheureux@coveo.com

Answer by Jean-François L'Heureux, Oct 29, 2015 6:07 PM

Normally, you don't add a Coveo Search Box and a Coveo Search component on the same item because the Coveo search item already have a search box in it. To have both controls on the same item, modifications to the JavaScript code needs to be done. You can download the Coveo for Launch Sitecore demo package to see an example of the modifications needed (see Launch Sitecore Demo Integration Guide).

This can be caused by many things:

  • The "unique id" you set on the Search box is the same as the id attribute of the "Coveo Search" component ("search"). This causes the init call to initialize the wrong component.
  • You included both the "Coveo Search Box Resources" and the "Coveo Search Resources" components in your item.
  • You included only the "Coveo Search Box Resources" component in your item. The "Coveo Search" component needs the "Coveo Search Resources" component.
  • You included the "Resources" component after your "Coveo search Box" or "Coveo Search" component.
Gravatar for shirazi@rdacorp.com

Comment by aga, Oct 30, 2015 4:48 PM

jeff: in order to debug this, i've made things even simpler. I'm using the default Search Layout and I'm trying to add the search box along with the search sublayout. i made sure the search box is using a unique id. The order of my sublayouts are: Coveo Search Resources, Coveo Search Box, and Coveo Search. In this case only the Search Box is displayed. If the Search Box is after the Coveo Search, then only Coveo Search is displayed.

Gravatar for jflheureux@coveo.com

Comment by Jean-François L'Heureux, Nov 3, 2015 4:56 PM

Hi Aga,

I reproduced the problem on my machine and I found the origin of it.

It is because the CoveoForSitecore.js jQuery extension only allows one search interface to be initialized. The Coveo Search Box is also considered as a search interface as it can display results with an OmniBox Result List. So calling init or initSearchBox after one is already initialized have no effect.

This is considered as a bug. In normal conditions, someone should be able to have a Coveo Search Box component in the header of the website and a Coveo Search component in the main placeholder to display the search results. I logged the bug in our tracking system. It may take some time until the fix is released as we are now releasing Coveo for Sitecore every 2 months.

There are workaounds for this problem but they all need modifying the JavaScript code of your components. As I said, an example of a working solution is in the Coveo for Launch Sitecore demo package. You can install it on a new Sitecore instance and have a look at the source files and rendered HTML and JavaScript to understand the customization needed to make it work.

Note: Do not modify the code of the out-of-the-box Coveo for Sitecore files as they will be overwritten at your next upgrade of the product. Always duplicate the sublayouts and their associated ascx files before modifying them.

Gravatar for shirazi@rdacorp.com

Comment by aga, Nov 6, 2015 1:41 PM

Jeff, for some reason I am having major issues installing the Coveo for Launch package. Can you point me to the js that I'll need to change on my side?

Gravatar for jflheureux@coveo.com

Comment by Jean-François L'Heureux, Nov 6, 2015 4:18 PM

Hi Aga,

There are many changes to do to the JavaScript code to make it work. I'll try to summarize it. You'll need to duplicate a Coveo Search Box component and a Coveo Search component to make those modifications.

First, you need to have a JavaScript method that indicates whether you are on a search page or not.

function isOnSearchPage() {
    return Coveo.$('#search').length > 0;
}

Basically, for the search box, when you are not on a search page, you want to call the "initSearchbox" method to initialize the Coveo Search Box component with the model initialization options as it is already done by the Coveo Search Box component.

if (typeof(CoveoForSitecore) !== 'undefined') {
    var searchOptionsForSearchbox = <%= Model.GetJavaScriptInitializationOptions() %>;
    CoveoForSitecore.componentsOptions = Coveo.$.extend({}, CoveoForSitecore.componentsOptions, searchOptionsForSearchbox);
    Coveo.$('#<%= Model.SearchBoxUniqueId %>').coveoForSitecore('initSearchbox', CoveoForSitecore.componentsOptions);
} else {
    Coveo.$('#<%= Model.SearchBoxUniqueId %>').coveo('initSearchbox', '<%= Model.GetSearchPageUrl() %>');
}

When you are on a search page however, you want to initialize the Coveo Search component with the "init" method and specify an array of external components for initialization. You will insert the Coveo search Box component in that external components array.

var searchboxElement = Coveo.$('#<%= Model.SearchBoxUniqueId %>');
var searchOptionsForSearchbox = {
    externalComponents: [searchboxElement]
};
CoveoForSitecore.componentsOptions = Coveo.$.extend({}, CoveoForSitecore.componentsOptions, searchOptionsForSearchbox);

The Coveo Search Box is included before the Coveo Search component in the page. Since this code predefines the CoveoForSitecore.componentsOptions variable, you'll need to extend it in the Coveo Search component instead of redefining it like the original code of the component.

var searchOptions = <%= Model.GetJavaScriptInitializationOptions() %>;
CoveoForSitecore.componentsOptions = Coveo.$.extend({}, CoveoForSitecore.componentsOptions, searchOptions);

In the end, it will be similar to the code of the Coveo for Launch Sitecore solution:

CoveoLaunchSearchBox.ascx

<script type="text/javascript">
    function isOnSearchPage() {
        return Coveo.$('#search').length > 0;
    }

    function setSearchboxPlaceholderText() {
        Coveo.$('#<%= Model.SearchBoxUniqueId %>').find("input.CoveoQueryBox").attr("placeholder", '<%= Model.SearchboxPlaceholderText %>');
    }

    Coveo.$(function () {
        if (!isOnSearchPage()) {
            if (typeof(CoveoForSitecore) !== 'undefined') {
                var searchOptionsForSearchbox = <%= Model.GetJavaScriptInitializationOptions() %>;
                CoveoForSitecore.componentsOptions = Coveo.$.extend({}, CoveoForSitecore.componentsOptions, searchOptionsForSearchbox);
                Coveo.$('#<%= Model.SearchBoxUniqueId %>').coveoForSitecore('initSearchbox', CoveoForSitecore.componentsOptions);
            } else {
                Coveo.$('#<%= Model.SearchBoxUniqueId %>').coveo('initSearchbox', '<%= Model.GetSearchPageUrl() %>');
            }
            setSearchboxPlaceholderText();
        } else {
            var searchboxElement = Coveo.$('#<%= Model.SearchBoxUniqueId %>');
            var searchOptionsForSearchbox = {
                externalComponents: [searchboxElement]
            };
            CoveoForSitecore.componentsOptions = Coveo.$.extend({}, CoveoForSitecore.componentsOptions, searchOptionsForSearchbox);

            Coveo.$('#search').on('afterInitialization', function () {
                setSearchboxPlaceholderText();
            });
        }
    });
</script>

CoveoLaunchSearch.ascx

<script type="text/javascript">
    Coveo.$(function() {
        var searchOptions = <%= Model.GetJavaScriptInitializationOptions() %>;
        CoveoForSitecore.componentsOptions = Coveo.$.extend({}, CoveoForSitecore.componentsOptions, searchOptions);
    });
</script>

// Search component HTML code

<script type="text/javascript">
    Coveo.$(function() {
        Coveo.$('#search').coveoForSitecore('init', CoveoForSitecore.componentsOptions);
    });
</script>
Gravatar for shirazi@rdacorp.com

Comment by aga, Nov 9, 2015 11:24 AM

thanks Jeff

Gravatar for shirazi@rdacorp.com

Comment by aga, Nov 12, 2015 12:29 PM

Hi Jeff,

I've run into another issue. This breaks when I add the omni search results to the search box in the header. When I add the omni search result list and land on a search page i get the following JS error: CoveoForSitecore.plugin is undefined

Gravatar for jflheureux@coveo.com

Comment by Jean-François L'Heureux, Nov 12, 2015 4:50 PM

Are you using the "Coveo Search Resources" component or the "Coveo Search Box Resources" component when adding an OmniBox Result List? You need to use a "Coveo Search Resources" component.

Gravatar for shirazi@rdacorp.com

Comment by aga, Nov 13, 2015 9:33 AM

I'm using Coveo Search Resources

Gravatar for jflheureux@coveo.com

Comment by Jean-François L'Heureux, Nov 15, 2015 1:44 AM

Are you sure you are using the "Coveo Search Resources"? I had the same error when I changed my" Coveo Search Box Resources" component for a "Coveo Search Resources" one in Sitecore 8. It was only changed in the final version of my template instead of the shared version.

Can you look at the source of your page in your browser and look for "CoveoForSitecore.js". If it's not there, you are still using the "Coveo Search Box Resources" component.

Gravatar for shirazi@rdacorp.com

Comment by aga, Nov 16, 2015 3:52 PM

Jeff: CoverForSitecore.js is being loaded but js variable CoverForSitecore is null when you are on the search page but it works when you are on any other page. As of now I've got to work by changing the omnibox control to register the control only when its not on the search page. When it's on the search page the registration is ignored from the control's js but it is registered from the SearchSublayout. Thanks for your help

Ask a question