Call function after loading google custom search results?
Asked Answered
L

3

7

I basically need to run some jQuery code after the search results get rendered on my page. I can use either the v1 code:

<div id="cse" style="width: 100%;">Loading</div>
<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script type="text/javascript"> 
 google.load('search', '1', {language : 'en', style : google.loader.themes.V2_DEFAULT});
 google.setOnLoadCallback(function() {
var customSearchOptions = {};
var orderByOptions = {};
orderByOptions['keys'] = [{label: 'Relevance', key: ''},{label: 'Date', key: 'date'}];
customSearchOptions['enableOrderBy'] = true;
customSearchOptions['orderByOptions'] = orderByOptions;  var customSearchControl = new google.search.CustomSearchControl(
  'zzzzzzzzzzzz', customSearchOptions);
customSearchControl.setResultSetSize(google.search.Search.FILTERED_CSE_RESULTSET);
var options = new google.search.DrawOptions();
options.setAutoComplete(true);
customSearchControl.setAutoCompletionId('zzzzzz:zzzzzzz+qptype:3');
options.enableSearchResultsOnly(); 
customSearchControl.draw('cse', options);
function parseParamsFromUrl() {
  var params = {};
  var parts = window.location.search.substr(1).split('\x26');
  for (var i = 0; i < parts.length; i++) {
    var keyValuePair = parts[i].split('=');
    var key = decodeURIComponent(keyValuePair[0]);
    params[key] = keyValuePair[1] ?
        decodeURIComponent(keyValuePair[1].replace(/\+/g, ' ')) :
        keyValuePair[1];
  }
  return params;
}

var urlParams = parseParamsFromUrl();
var queryParamName = "q";
if (urlParams[queryParamName]) {
  customSearchControl.execute(urlParams[queryParamName]);
}
  }, true);
</script>

Or the v2 code:

<!-- Put the following javascript before the closing </head> tag. -->

<script>
    (function() {
var cx = 'xxxxxxxxx';
var gcse = document.createElement('script'); gcse.type = 'text/javascript'; gcse.async = true;
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
    '//www.google.com/cse/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(gcse, s);
  })();
</script>

I've tried putting my function call in various places in the code but no avail.

I have a function that needs to dynamically set the height of the container the search results appear in, so once the results load I need to call it otherwise my page displays incorrectly.

Here is a link to their v2 API documentation: https://developers.google.com/custom-search/docs/element#cse-element and v1: https://developers.google.com/custom-search/docs/js/cselement-reference . I can't see anything where there is a callback upon search result rendering, only on initialization. Seems crazy though there isn't support for something like this.

Here is what I've tried with v2:

(function () {
        var cx = 'xxxxxxxxx';
        var gcse = document.createElement('script'); gcse.type = 'text/javascript'; gcse.async = true;

        gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
            '//www.google.com/cse/cse.js?cx=' + cx;
        gcse.onreadystatechange = gcse.onload = function () {
            console.log("executed");
            SetMainHeight(20);
        };
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(gcse, s);

    })();

The console never outputs "executed". Also I notice in my console I have the following error:

Unsafe JavaScript attempt to access frame with URL about:blank from frame with URL http://www.google.com/cse?q=test&client=google-coop&hl=en&r=s&cx=xxxxx…s1%2Csr1&rurl=http%3A%2F%2Flocalhost%3A58257%2FSearch%3Fq%3Dtest#slave-1-1. Domains, protocols and ports must match.

Not sure if that matters as the search function still works fine. I am testing this on localhost over http.

Labradorite answered 20/2, 2013 at 21:18 Comment(2)
Can you set a minimal height on the container so that if the search fails at least some structure will be in place to hold the layout together?Morelos
There already is a minimum height. I am doing some sticky footer and other dynamic sizing of various containers on my page, so basically anytime the height gets changed via jQuery, I need to recalculate certain heights.Labradorite
B
5

Unfortunately v2 doesn't have this ability, but in v1 you can use:

.setSearchCompleteCallback(object, method)

You can search for it on this page.

Bust answered 21/2, 2013 at 18:2 Comment(0)
R
14

Previous solutions did not work for me, but here's what worked for me:

<script>
  (function() {

    window.__gcse = {
      callback: myCallback
    };

    function myCallback() {
       $('input.gsc-input').keyup(function(e) { if(e.keyCode == 13 || e.which == 13) {  console.log('enter pressed'); }});
      $('input.gsc-search-button').on('click', function(e) { console.log('clicked');});
    }
    var cx = '002806224466286757728:XXXXXXX';
    var gcse = document.createElement('script');
    gcse.type = 'text/javascript';
    gcse.async = false;
    gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
        '//www.google.com/cse/cse.js?cx=' + cx;
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(gcse, s);
  })();
</script>
<gcse:search></gcse:search>

Hope this helps

Runstadler answered 12/5, 2014 at 23:37 Comment(1)
This is what the documentation says for the v2 custom search control and it's the only way to do this I believe. You've got to wait for the search script to load then execute before the DOM contains the things you might want to change. This is how we removed the text from the button so our overridden background image style showed an icon instead of the "search" text: window.__gcse = { callback: function() { $('input.gsc-search-button').val(''); } };Translate
B
5

Unfortunately v2 doesn't have this ability, but in v1 you can use:

.setSearchCompleteCallback(object, method)

You can search for it on this page.

Bust answered 21/2, 2013 at 18:2 Comment(0)
T
0

For v2, for example, try and set an onload handler to the gcse object (script) before inserting it in the DOM.

gcse.onreadystatechange = gcse.onload = function() {
  //execute my code
};

basically you end up with:

<!-- Put the following javascript before the closing </head> tag. -->

<script>
    (function() {
var cx = 'xxxxxxxxx';
var gcse = document.createElement('script'); gcse.type = 'text/javascript'; gcse.async = true;
gcse.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') +
    '//www.google.com/cse/cse.js?cx=' + cx;
gcse.onreadystatechange = gcse.onload = function() {
  //execute your code here
};
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(gcse, s);
  })();
</script>
Tabbitha answered 21/2, 2013 at 16:53 Comment(1)
Not being called. I do see one error message in console, but it may not be related, updated my question.Labradorite

© 2022 - 2024 — McMap. All rights reserved.