Search code examples
jquerygoogle-api-javascript-client

How to combine jQuery file with Google Drive API?


I found 2 JavaScript libraries.

One is "JavaScript Quickstart", the other is "jQuery Typeahead Search".

I choose the "Conutry v2" function which demonstrated in the "jQuery Typeahead Search" page. And I want the data source(url) comes from the "listFiles()" function in the "JavaScript Quickstart".

JavaScript Quickstart:

<head>
<title>Drive API Quickstart</title>
<meta charset='utf-8' />
</head>
<link type="text/css" rel="stylesheet" href="jquery.autocomplete.css" />
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js">   </script>
<script src="jquery.autocomplete.js"></script>

<body>
<input id="authorize-button" value="Authorize" type="button" />

<p>Drive API Quickstart</p>

<button id="authorize-button" style="display: none;">Authorize</button>
<button id="signout-button" style="display: none;">Sign Out</button>

<pre id="content"></pre>

<script type="text/javascript">
    var CLIENT_ID = '603464653206-shrjn8lfsu1uahjd1v7f1rcpgcdlhc03.apps.googleusercontent.com';

    var DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"];

    var SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly';

    var authorizeButton = document.getElementById('authorize-button');
    var signoutButton = document.getElementById('signout-button');

    function handleClientLoad() {
        gapi.load('client:auth2', initClient);
    }

    function initClient() {
        gapi.client.init({
            discoveryDocs: ["https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"],
            clientId: '603464653206-shrjn8lfsu1uahjd1v7f1rcpgcdlhc03.apps.googleusercontent.com',
            scope: 'https://www.googleapis.com/auth/drive.metadata.readonly'
        }).then(function() {
            gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);

            updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
            authorizeButton.onclick = handleAuthClick;
            signoutButton.onclick = handleSignoutClick;
        });
    }


    function updateSigninStatus(isSignedIn) {
        if (isSignedIn) {
            authorizeButton.style.display = 'none';
            signoutButton.style.display = 'block';
            listFiles();
        } else {
            authorizeButton.style.display = 'block';
            signoutButton.style.display = 'none';
        }
    }


    function handleAuthClick(event) {
        gapi.auth2.getAuthInstance().signIn();
    }


    function handleSignoutClick(event) {
        gapi.auth2.getAuthInstance().signOut();
    }


    function appendPre(message) {
        var pre = document.getElementById('content');
        var textContent = document.createTextNode(message + '\n');
        pre.appendChild(textContent);
    }


    function listFiles() {
        gapi.client.drive.files.list({
            'pageSize': 10,
            'fields': "nextPageToken, files(id, name, webContentLink)"
        }).then(function(response) {
            appendPre('Files:');
            var returnedFiles = response.result.files;
            if (returnedFiles && returnedFiles.length > 0) {
                for (var i = 0; i < returnedFiles.length; i++) {
                    var file = returnedFiles[i];
                    appendPre(file.name + ' (' + file.id + ')' + file.webContentLink);
                }
            } else {
                appendPre('No files found.');
            }
        });
    }

</script>
<script async defer src="https://apis.google.com/js/api.js" onload="this.onload=function(){};handleClientLoad()" onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>
</body>
</html>

The jQueryTypeahead Search:

<head>
<!-- Optional CSS -->
<link rel="stylesheet" href="jquery.typeahead.min.css">
<link rel="stylesheet" href="deco.css">
<!-- Required JavaScript -->
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script src="jquery.typeahead.min.js"></script>
</head>
<body>
<var id="result-container" class="result-container"></var>

<form id="form-country_v2" name="form-country_v2">
    <div class="typeahead__container">
        <div class="typeahead__field">

            <span class="typeahead__query">
            <input class="js-typeahead-country_v2" name="country_v2[query]" placeholder="Search" autocomplete="off" type="search">
        </span>
            <span class="typeahead__button">
            <button type="submit">
                <i class="typeahead__search-icon"></i>
            </button>
        </span>

        </div>
    </div>
</form>
<script>
    $.typeahead({
        input: '.js-typeahead-country_v2',
        minLength: 2,
        maxItem: !1,
        order: "asc",
        href: "https://en.wikipedia.org/?title={{display}}",
        template: "{{display}} <small style='color:green;'>{{group}}</small>",
        source: {
            country: {
                ajax: {
                    url: "country_v2.json",
                    path: "data.country"
                }
            },
            capital: {
                ajax: {
                    type: "POST",
                    url: "country_v2.json",
                    path: "data.capital",
                    data: {
                        myKey: "myValue"
                    }
                }
            }
        },
        callback: {
            onNavigateAfter: function(node, lis, a, item, query, event) {
                if (~[38, 40].indexOf(event.keyCode)) {
                    var resultList = node.closest("form").find("ul.typeahead__list"),
                        activeLi = lis.filter("li.active"),
                        offsetTop = activeLi[0] && activeLi[0].offsetTop - (resultList.height() / 2) || 0;

                    resultList.scrollTop(offsetTop);
                }

            },
            onClickAfter: function(node, a, item, event) {

                event.preventDefault();

                var r = confirm("You will be redirected to:\n" + item.href + "\n\nContinue?");
                if (r == true) {
                    window.open(item.href);
                }

                $('#result-container').text('');

            },
            onResult: function(node, query, result, resultCount) {
                if (query === "") return;

                var text = "";
                if (result.length > 0 && result.length < resultCount) {
                    text = "Showing <strong>" + result.length + "</strong> of <strong>" + resultCount + '</strong> elements matching "' + query + '"';
                } else if (result.length > 0) {
                    text = 'Showing <strong>' + result.length + '</strong> elements matching "' + query + '"';
                } else {
                    text = 'No results matching "' + query + '"';
                }
                $('#result-container').html(text);

            },
            onMouseEnter: function(node, a, item, event) {

                if (item.group === "country") {
                    $(a).append('<span class="flag-chart flag-' + item.display.replace(' ', '-').toLowerCase() + '"></span>')
                }

            },
            onMouseLeave: function(node, a, item, event) {

                $(a).find('.flag-chart').remove();

            }
        }
    });

</script>
</body>
</html>

How to make the data from Google Drive API become the source of the jQueryTypeAhead library?


Solution

  • You can try this. Wrap typehead declaration in a function.

    <script>
    function initTypeHead(fileName){
    $.typeahead({
        input: '.js-typeahead-country_v2',
        minLength: 2,
        maxItem: !1,
        order: "asc",
        href: "https://en.wikipedia.org/?title={{display}}",
        template: "{{display}} <small style='color:green;'>{{group}}</small>",
        source: {
            country: {
                ajax: {
                    url: fileName,
                    path: "data.country"
                }
            },
            capital: {
                ajax: {
                    type: "POST",
                    url: fileName,
                    path: "data.capital",
                    data: {
                        myKey: "myValue"
                    }
                }
            }
        },
        callback: {
            onNavigateAfter: function(node, lis, a, item, query, event) {
                if (~[38, 40].indexOf(event.keyCode)) {
                    var resultList = node.closest("form").find("ul.typeahead__list"),
                        activeLi = lis.filter("li.active"),
                        offsetTop = activeLi[0] && activeLi[0].offsetTop - (resultList.height() / 2) || 0;
    
                    resultList.scrollTop(offsetTop);
                }
    
            },
            onClickAfter: function(node, a, item, event) {
    
                event.preventDefault();
    
                var r = confirm("You will be redirected to:\n" + item.href + "\n\nContinue?");
                if (r == true) {
                    window.open(item.href);
                }
    
                $('#result-container').text('');
    
            },
            onResult: function(node, query, result, resultCount) {
                if (query === "") return;
    
                var text = "";
                if (result.length > 0 && result.length < resultCount) {
                    text = "Showing <strong>" + result.length + "</strong> of <strong>" + resultCount + '</strong> elements matching "' + query + '"';
                } else if (result.length > 0) {
                    text = 'Showing <strong>' + result.length + '</strong> elements matching "' + query + '"';
                } else {
                    text = 'No results matching "' + query + '"';
                }
                $('#result-container').html(text);
    
            },
            onMouseEnter: function(node, a, item, event) {
    
                if (item.group === "country") {
                    $(a).append('<span class="flag-chart flag-' + item.display.replace(' ', '-').toLowerCase() + '"></span>')
                }
    
            },
            onMouseLeave: function(node, a, item, event) {
    
                $(a).find('.flag-chart').remove();
    
            }
        }
    });
    }
    

    Then in the list function call it after the response is received. I have passed the whole files array which you need to correct as typehead only requires one file.

    function listFiles() {
        gapi.client.drive.files.list({
            'pageSize': 10,
            'fields': "nextPageToken, files(id, name, webContentLink)"
        }).then(function(response) {
            appendPre('Files:');
            var returnedFiles = response.result.files;
            if (returnedFiles && returnedFiles.length > 0) {
                for (var i = 0; i < returnedFiles.length; i++) {
                    var file = returnedFiles[i];
                    appendPre(file.name + ' (' + file.id + ')' + file.webContentLink);
                }
                initTypeHead(returnedFiles);
            } else {
                appendPre('No files found.');
            }
        });
    }