Google Drive Integration

Jira Code : AKS-1

Create Google Drive DashBoard in NetSuite and imitate its features such as Google Login Authorisation, Create Folder, Browse through Folders, Upload File, Drag-and-Drop to Upload Multiple Files, Rename File, Delete File, Download Multiple Files, File Preview and cycle through File Previews, Icons for each File Type.

An UserEvent will be deployed to record and this will add the Google Drive DashBoard under ‘Google Drive’ Subtab.

JJ UE Google Create Folderr_v2.js

/**
 * @ScriptName JJ Google Drive Create Folder
 * @ScriptId customscript_jj_google_drive_folder
 * @AppliedTo Cases,Invoices,Purchase Orders,Sales Orders,Work Orders
 * @NApiVersion 2.x
 * @NScriptType UserEventScript
 * @NModuleScope SameAccount
 */
define(
    ['N/file', 'N/url', 'N/record', 'N/runtime', 'N/search',
        'N/ui/serverWidget'
    ],
    /**
     * @param {record}
     *            record
     * @param {runtime}
     *            runtime
     * @param {search}
     *            search
     * @param {serverWidget}
     *            serverWidget
     */
    function(file, url, record, runtime, search, serverWidget) {

        /**
         * Function definition to be triggered before record is loaded.
         * 
         * @param {Object}
         *            scriptContext
         * @param {Record}
         *            scriptContext.newRecord - New record
         * @param {string}
         *            scriptContext.type - Trigger type
         * @param {Form}
         *            scriptContext.form - Current form
         * @Since 2015.2
         */
        function beforeLoad(scriptContext) {
            try {
                var userContext = runtime.executionContext;
                var type = scriptContext.type;
                if (runtime.executionContext == 'USERINTERFACE' &&
                    (type == 'view' || type == 'edit')) {

                    var recordType = '';
                    recordType = scriptContext.newRecord.type;
                    var stringrecordType = JSON.stringify(recordType);
                    var folderName = '';
                    // to find whether the recordType is custom record
                    var cusString = 'customrecord';

                    try {
                        /* To get the Document number of current record */
                        // If it is case record get the case number
                        if (recordType == 'supportcase') {
                            folderName = scriptContext.newRecord.getValue({
                                fieldId: 'casenumber'
                            });
                        } else if (recordType == 'vendorbill') {
                            // If it is transaction record to get tranid as
                            // document number
                            folderName = scriptContext.newRecord.getValue({
                                fieldId: 'transactionnumber'
                            });
                        } else if (recordType == 'check') {
                            // If it is check record to get internalid as
                            // document number
                            folderName = scriptContext.newRecord.getValue({
                                fieldId: 'transactionnumber'
                            });
                            //To add internal id as foldername for checks JJ 25 Oct 2017
                            //Mrudul - Reversed back to original way.
                            //folderName = scriptContext.newRecord.id;
                        } else if (recordType == 'calendarevent') {

                            folderName = scriptContext.newRecord.id;
                        } else {
                            // If it is transaction record to get tranid as
                            // document number
                            folderName = scriptContext.newRecord.getValue({
                                fieldId: 'tranid'
                            });
                        }
                        // if it is custom records
                        if (folderName == undefined || folderName == null) {
                            folderName = scriptContext.newRecord.getValue({
                                fieldId: 'recordId'
                            });
                        }
                        // it it is customer record
                        if (folderName == undefined || folderName == null) {
                            folderName = scriptContext.newRecord.getValue({
                                fieldId: 'entityid'
                            });
                        }

                    } catch (e) {
                        log.debug({
                            title: 'Get the correct Document number',
                            details: e.message
                        });
                    }
                    /* End of get the Document number of current record */
                    try {
                        /*
                         * To find the folder name and folder id from custom
                         * record 'Google Drive Record Types'
                         */

                        var GoogleDriveRecordTypeSearch = search
                            .create({
                                type: 'customrecord_aks_googledrive_recordtype',
                                title: 'Google Drive RecordType',

                                columns: [{
                                        name: 'id'
                                    },
                                    {
                                        name: 'custrecord_aks_googledr_rec_type'
                                    },
                                    {
                                        name: 'custrecord_aks_googledr_folder_type'
                                    },
                                    {
                                        name: 'custrecord_aks_drive_folder_id'
                                    }
                                ],
                                filters: [{
                                    name: 'custrecord_aks_googledr_rec_type',
                                    operator: 'IS',
                                    values: recordType
                                }]
                            });

                        var GoogleDriveRecordTypeResult = GoogleDriveRecordTypeSearch
                            .run().getRange({
                                start: 0,
                                end: 1
                            });
                        if ((GoogleDriveRecordTypeResult != null) &&
                            (GoogleDriveRecordTypeResult != undefined) &&
                            (GoogleDriveRecordTypeResult != '')) {

                            var folderType = GoogleDriveRecordTypeResult[0]
                                .getValue({
                                    name: 'custrecord_aks_googledr_folder_type'
                                });
                            var folderId = GoogleDriveRecordTypeResult[0]
                                .getValue({
                                    name: 'custrecord_aks_drive_folder_id'
                                });

                        }
                        // To form the folder name
                        var entireFoldername = folderType + ' ' +
                            folderName;
                        /* End of find the folder name from custom record */

                    } catch (e) {
                        log
                            .debug({
                                title: 'Get the folder(search) details from custom record',
                                details: e.message
                            });
                    }

                    // Add Tab dynamically
                    var googleTab = scriptContext.form.addTab({
                        id: 'custpage_google_folders',
                        label: 'Google Drive'
                    });
                    // Add field
                    var field = scriptContext.form.addField({
                        id: 'custpage_google_frame',
                        type: 'inlinehtml',
                        label: 'Google Field',
                        container: 'custpage_google_folders'
                    });
                    // URL of HTML file
                    var output = 'https://system.na2.netsuite.com/c.3815252/suitebundle203232/AKS - Netsuite Google Drive Integration/google-drive.html';
                    // Attaching the parameters folder name and record type
                    // to name the folder
                    var content = '<iframe id="google_frame_folder" src="' +
                        output +
                        '?foldertype=' +
                        folderType +
                        '?foldername=' +
                        entireFoldername +
                        '?folderid=' +
                        folderId +
                        '" align="center" style="width: 100%; height:600px;margin:0; border:0; padding:0"frameborder="0"></iframe>';
                    // Set the URL in the INLINE HTML field
                    scriptContext.newRecord.setValue({
                        fieldId: 'custpage_google_frame',
                        value: content
                    });

                }
            } catch (e) {
                log.debug({
                    title: 'googgledrive',
                    details: e.message
                });
            }

        }

        return {
            beforeLoad: beforeLoad

        };

    });

google-drive.css

body{
	font-family:arial;
	font-size:11px;
}


/*************** Google Login Box ***************/
#login-box{
	width: 41%;
	height: 20%;
	margin: 7% 10% 10% 29%;
	border-radius: 5px;
	border: solid 1px #ccc;
	padding: 10px;
	background: #EFEFF6;
	font-size: 202%;
	text-align: center;
}
#btnLogin{
	font-size: 95%;
}

/*************** END Google Login Box ***************/

/*************** Google Drive Breadcrumb ***************/
#drive-breadcrumb{
	font-size:11px;
	float: left;
	display: inline-block;
}

#drive-breadcrumb a{
	cursor:pointer;
}
#redirect-google{
	display: inline-block;
	margin-left: 25%;
}

.breadcrumb-arrow{
	background:url(images/arrow_right.png) no-repeat 0 3px;
	display:inline-block;
	height:16px;
	width:11px;
}
/*************** END Google Drive Breadcrumb ***************/

/*************** Google Drive Box ***************/
#transparent-wrapper
{
	display: none; 
	position: fixed;
	top: 0%; 
	left: 0%; 
	width: 100%; 
	height: 100%; 
	background-color: #000; 
	z-index: 1001;
	-moz-opacity: 0.35; 
	background-color: rgba(0, 0, 0, 0.8);
}
#overlay {
	background-color: rgba(0, 0, 0, 0.8);
	z-index: 999;
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	display: none;
	font-size: 155% !important;
	color: red !important;
}

#drive-box{
	padding:10px;
	margin:10px;   
	border:solid 1px #ccc;
	width:99%;
	min-height: 88%;
	height:auto;
	box-sizing: border-box;
	display:none;
	position:relative;
	margin-top:60px;
}
.no-items{
	text-align: center;
	margin: 13% 0 0 0%;
	font-size: 32px;
	color: #00BAD0;
}
#drag-and-drop-area{
	min-height: 82%;
	width:100%;
}

#drive-content{
	clear:both;
}
#drive-folder-view{
	clear:both;
}
#drive-list-view{
	clear:both;
}
.folder-box, .file-box {
	float:left;
	font-family:Arial;
	width:150px;
	height:150px;
	text-align:center;
	padding:10px;
	margin:10px;
	border:solid 1px #edeae9;
	-webkit-box-shadow: 7px 9px 5px -6px rgba(0,0,0,0.75);
	-moz-box-shadow: 7px 9px 5px -6px rgba(0,0,0,0.75);
	box-shadow: 7px 9px 5px -6px rgba(0,0,0,0.75);
	border-radius:5px;
}
.download-checkbox{
	float: left;
	display: inline-block;
}
.download-checkbox-list{
	float: right;
	display: inline-block;
}
.file-icon,.folder-icon{
	margin-left: 24%;
	width: 50%;
}
.image-preview{
    width: 100%;
    text-align: center;
    height: 49%;
    cursor: pointer;
}

.image-preview img{
    max-width: 100%;
    height: 91%;
    cursor: pointer;
}

.item-title,.item-title-folder,.item-title-file {
	margin-top: -8px;
	height: 28%;
	padding-top: 10px;
	word-wrap: break-word;
	width: 150px;
	text-align: center;
	font-size: 12px;
	cursor: pointer;
}
.item-title-folder{
	cursor: pointer;
}


.folder-boxlist, .file-boxlist {
	float:left;
	font-family:Arial;
	width:96%;
	height:50px;
	padding:10px;
	margin:10px;
	border:solid 1px #edeae9;
	-webkit-box-shadow: 7px 9px 5px -6px rgba(0,0,0,0.75);
	-moz-box-shadow: 7px 9px 5px -6px rgba(0,0,0,0.75);
	box-shadow: 7px 9px 5px -6px rgba(0,0,0,0.75);
	border-radius:5px;
	border-radius:5px;
}


.folder-icon-list,.image-icon-list,.file-icon-list{
	float:left;
	display:inline-block;
	width: 50px;
	height: 50px;
	cursor: pointer;
}


.image-preview-list{
	text-align: left;
	height: 100%;
	width: 100%;
	cursor: pointer;
}

.image-preview-list img{
	max-width: 100%;
	height: 100%;
	cursor: pointer;
}


.item-title-list,.item-title-folder-list,.item-title-file-list {
	float: left;
	display: inline-block;
	padding-top: 10px;
	word-wrap: break-word;
	width: 150px;
	text-align: center;
	font-size: 14px;
	width: 32%;
	padding: 1% 1% 0% 1%;
	cursor: pointer;
}
.item-title-folder-list
{
	cursor: pointer;

}


#drive-menu{
	float:right;
	display:inline-block;
}

#drive-menu div:hover{
	background-color:#fafccc;
	border:solid 1px #000;
}

#button-reload, #button-share, #button-addfolder, #button-upload ,#button-view{
	width:24px;
	height:24px;
	display:block;
	cursor:pointer;
	margin-right:5px;
	float:left;
	border:Solid 1px #fae8e4;
	border-radius:5px;
}
#button-view{
	background:url(images/button_view.png) no-repeat;
}
#button-reload {
	background:url(images/button_reload.png) no-repeat;
}

#button-share {
	background:url(images/button_share.png) no-repeat;
}

#button-share.flash{
	background-color:#dbeb2d;
}

#button-addfolder {
	background:url(images/button_addfolder.png) no-repeat;
}

#button-upload {
	background:url(images/button_upload.png) no-repeat;
}

.button-box{
	padding-top: 10px;
	max-height: 15%;
}

/*
.button-delete, .button-info, .button-download, .button-text{
width:20px;
height:20px;
display:inline-block;
cursor:pointer;
margin-right:5px;
}

.button-delete {
background:url(images/button_delete.png) no-repeat;
}

.button-info {
background:url(images/button_info.png) no-repeat;
}

.button-download {
background:url(images/button_download.png) no-repeat;
}
*/

.button-text {
	background:url(images/button_text.png) no-repeat;
}

/*************** END Google Drive Box ***************/

/************* User Drive Information **************/
#user-info
{
	position:absolute;
	height:100px;
	right:0;
	width:200px;
	margin-top:-110px;
	background:#338daf;
	z-index:99999999;
	color:#fff;
	padding:5px;
	box-sizing: border-box;
	text-align:right;
	font-size:11px;
	border-top-left-radius: 5px;
	border-top-right-radius: 5px;
}

.user-item
{
	padding-bottom:4px;
}

#drive-info{
	position:absolute;
	height:60px;
	right:0;
	width:250px;
	margin-top:0px;
	z-index:99999999;
	color:#fff;
	padding:5px;
	box-sizing: border-box;
	text-align:right;
	font-size:11px;
	border-top-left-radius: 5px;
	border-top-right-radius: 5px;
}
#btnCreateFolder {
	font-size: 33px;
	font-weight: lighter;
	margin: 16% 0% 0% 36%;
}
#link-logout {
	font-size: 12px;
	float: right;
}
#drive-location {
	position: absolute;
	padding: 10px;
	margin: 10px;
	border: solid 1px #ccc;
	width: 98%;
	min-height: 82%;
	height: auto;
	box-sizing: border-box;
	display: none;
	margin-top: 60px;
}
#drive-google {
	position: absolute;
	height: 60px;
	left: 0;
	width: 326px;
	margin-top: 0px;
	z-index: 99999999;
	color: #111;
	font-size: 12px;
	padding: 5px;
	box-sizing: border-box;
	text-align: right;
	font-size: 11px;
	border-top-left-radius: 5px;
	border-top-right-radius: 5px:;
}
#google-logo {
	display: inline-block;
	width: 218px;
	height: 51px;
	float: left;
}
#aks-logo {
	display: inline-block;
	width: 97px;
	height: 36px;
	float: right;
}
#recordDetails{
	float: right;
	font-weight: bold;
	color: #607799;
}
#currentRecordType,#currentRecordNumber{
	font-size: 12px;
	color: #3395d7;
	font-weight: bold;
	/*	color: #607799;*/
}
#link-logo{
	height: 25px;
	width: 70px;
}
/************* END User Drive Information **************/

/************* FLOATING BOX *********************/
.float-box{
	border-radius:0px;
	-webkit-box-shadow: 7px 7px 5px rgba(50, 50, 50, 0.75);
	-moz-box-shadow:7px 7px 5px rgba(50, 50, 50, 0.75);
	box-shadow:7px 7px 5px rgba(50, 50, 50, 0.75);
	width:400px;
	padding:7px 15px;
	border:solid 1px #ccc;
	position:fixed;
	left:50%;
	margin-left:-200px;
	top:35%;
	z-index:1000000;
	background-color:#fff;
	display:none;
}
#float-box-preview-button-left{
	display: inline-block;
    position: fixed;
    z-index: 1000000;
    top: 49%;
    bottom: 43%;
    left: 1%;
    float: left;
    font-size: 280%;
    font-weight: bold;
    background: black;
}
#float-box-preview-button-right{
	display: inline-block;
    position: fixed;
    z-index: 1000000;
    top: 49%;
    bottom: 43%;
    right: 1%;
    float: right;
    font-size: 280%;
    font-weight: bold;
    background: black;
}
.float-box-preview{

    display: inline-block;
	display: none;
}
.float-box-preview-box{

    border-radius: 0px;
    -webkit-box-shadow: 7px 7px 5px rgba(50, 50, 50, 0.75);
    -moz-box-shadow: 7px 7px 5px rgba(50, 50, 50, 0.75);
    box-shadow: 7px 7px 5px rgba(50, 50, 50, 0.75);
    width: 85%;
    height: 82%;
    padding: 7px 15px;
    border: solid 1px #ccc;
    position: fixed;
    margin-left: 6%;
    top: 12%;
    z-index: 1000000;
    background-color: #fff;
}
.info-form{
	margin-top: -12px;
}
#google-file-preview{
	height: 92%;
	width: 100%;
}

.close-x{
	float:right;
	display:inline-block;
	cursor:pointer;
}

.tbl-info{
	border-left:solid 1px #ccc;
	border-top:solid 1px #ccc;
	margin-bottom:10px;
	width:100%;
}

.tbl-info td{
	border-right:solid 1px #ccc;
	border-bottom:solid 1px #ccc;
	padding:5px 10px;
	font-size:11px;
}

.tbl-info td.label{
	background:#5f5d5c;
	color:#fff;
	text-align:right;
	width:50%;
}

#text-content
{
	margin-bottom:10px;
	overflow-y:auto;
	overflow-x:hidden;
	height:180px;
	border:solid 1px #ccc;
}

.text-input{
	width:90%;
	padding:5px;
	border-radius:5px;
	margin-bottom:10px;
}
/************* END FLOATING BOX *********************/

/*************** NOTIFICATION ******************/
#loading-wrapper{
	width:100%;
	height:100%;
	background:#000;
	-moz-opacity: 0.25; 
	opacity: .25; 
	filter: alpha(opacity=25);
	top:0;
	left:0;
	position:absolute;
}

#loading{
	position:absolute;
	left:50%;
	top:50%;
	margin-left:-60px;
	margin-top:-60px;
	width:120px;
}

#status-message{
	border:solid 1px #fbfbd4;
	background:#fbfbd4;
	border-radius:5px;
	padding:5px;
	position:absolute;
	right:10px;
	bottom:10px;
	z-index:9999999999;
}

#error-message{
	border:solid 1px #f2fcb9;
	background:#d83813;
	border-radius:5px;
	color:#fff;
	padding:10px;
	position:absolute;
	left:10px;
	bottom:10px;
	z-index:9999999999;
	max-width:400px;
	border-radius:5px;
	display:none;
}

#upload-percentage{
	position:absolute;
	left:50%;
	top:50%;
	margin-left:-25px;
	margin-top:-100px;
	width:50px;
	height:50px;
	border-radius: 50%;
	background:#297ab8;
	color:#fff;
	text-align:center;
	line-height:50px;
	font-weight:bold;
	font-size:15px;
	display:none;
}
/*************** END NOTIFICATION ******************/

/***************** MISC ************************/
.disabled{
	pointer-events: none;
	cursor: default;
}
/*.drive-viewer-toolstrip,.drive-viewer-toolstrip-inner,.drive-viewer-toolstrip-mid-panel,.drive-viewer-toolstrip-rgt-panel,.drive-viewer-popout-button,.drive-viewer-dark-button,.goog-inline-block,.drive-viewer-button,.drive-viewer-icon,.drive-viewer-nav-icon{
display: none;
pointer-events: none;
cursor: default;
}*/
.button,.button-delete, .button-info, .button-download, .button-text {
	background: #00BAD0;
	background-image: -webkit-linear-gradient(top, #00BAD0, #2980b9);
	background-image: -moz-linear-gradient(top, #00BAD0, #2980b9);
	background-image: -ms-linear-gradient(top, #00BAD0, #2980b9);
	background-image: -o-linear-gradient(top, #00BAD0, #2980b9);
	background-image: linear-gradient(to bottom, #00BAD0, #2980b9);
	border:none;
	-webkit-border-radius: 8;
	-moz-border-radius: 8;
	border-radius: 3px;
	font-family: Arial;
	color: #ffffff;
	font-size: 11px;
	padding: 5px 10px;
	text-decoration: none;
	cursor:pointer;
}

.button:hover {
	background: #3cb0fd;
	background-image: -webkit-linear-gradient(top, #3cb0fd, #00BAD0);
	background-image: -moz-linear-gradient(top, #3cb0fd, #00BAD0);
	background-image: -ms-linear-gradient(top, #3cb0fd, #00BAD0);
	background-image: -o-linear-gradient(top, #3cb0fd, #00BAD0);
	background-image: linear-gradient(to bottom, #3cb0fd, #00BAD0);
	text-decoration: none;
	border:none;
}

.hide{
	display:none;
}

.flash {
	-webkit-animation-name: flash;
	-webkit-animation-duration: 1s;
	-webkit-animation-timing-function: linear;
	-webkit-animation-iteration-count: infinite;

	-moz-animation-name: flash;
	-moz-animation-duration: 1s;
	-moz-animation-timing-function: linear;
	-moz-animation-iteration-count: infinite;

	animation-name: flash;
	animation-duration: 1s;
	animation-timing-function: linear;
	animation-iteration-count: infinite;
}

@-moz-keyframes flash {  
	0% { opacity: 1.0; }
	50% { opacity: 0.5; }
	100% { opacity: 1.0; }
}

@-webkit-keyframes flash {  
	0% { opacity: 1.0; }
	50% { opacity: 0.5; }
	100% { opacity: 1.0; }
}

@keyframes flash {  
	0% { opacity: 1.0; }
	50% { opacity: 0.5; }
	100% { opacity: 1.0; }
}
/***************** END MISC ************************/

google-drive.html

<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
        <script src="upload.js"></script>
        <script src="google-drive.js"></script>
        <link href="google-drive.css" rel="stylesheet" type="text/css" />
    </head>

    <body>

        <div id="transparent-wrapper"></div>

        <div id="login-box" class="hide">
            <p>Please login on your google account.</p>
            <button id="btnLogin"  class="button">Login</button>
        </div>
        <div id="drive-google" class="hide">
            <img id="google-logo" src="images/google-drive-logo.png">
            <img id="aks-logo" src="images/aks-logo.jpg">

        </div>
        <div id="drive-location" class="hide">
            <div class="user-item"><button id= "btnCreateFolder" title="Create Document Folder" class="button">Add Content in this Folder</button></div>
        </div>

        <div id="drive-info" class="hide">
            <div class="user-item"><button id="link-logout" href="javascript:void(0);" class="button" > Logout</button></div>

        </div>
        <div id="drive-box" class="hide">


            <!--            DRAG AND DROP DIV START         -->


            <div id="drag-and-drop-area" ondrop="javascript:drop_handler(event);" ondragover="javascript:dragover_handler(event);" ondragend="javascript:dragend_handler(event);">
                <div id="drive-breadcrumb">
                    <span class='breadcrumb-arrow'></span> <a class="disabled" data-id='0B-E0q-jV3NwcQlFyZUsxOHVReGM' data-level='0'>Netsuite</a>
                    <span id="span-navigation"></span>
                </div>
                <div id="redirect-google">
                    <button class="button" id="google-drive-link">View in Google Drive </button>
                </div>

                <div id="drive-menu">
                    <div id="button-reload" title="Refresh"></div>
                    <div id="button-upload" title="Upload to Google Drive" class="button-opt"></div>
                    <div id="button-addfolder" title="Add Folder" class="button-opt"></div>
                    <div id="button-view" title="Toggle Views"></div>
                    <button class="button" id="multiple-download">Download Selected(0)</button>
                    <!--                    <div id="button-share" title="Show shared files only"></div> -->
                </div>
                <!--<div><img id="link-logo" src="images/aks-logo.jpg" ></div>-->
                <div id="drive-content">
                    <div id="drive-folder-view" class="hide">
                    </div>
                    <div id="drive-list-view" class="hide">
                    </div>

                </div>





                <div id="error-message" class="flash hidden"></div>
                <div id="status-message" class="flash hidden"></div>
            </div>
            <!--            DRAG AND DROP DIV END         -->    
        </div>

        <input type="file" id="fUpload" class="hide" />
        <div class="float-box" id="float-box">
            <div class="folder-form">
                <div class="close-x"><img id="imgClose" class="imgClose" src="images/button_close.png" alt="close" /></div>
                <h3 class="clear">Add New Folder</h3>
                <div><input type="text" id="txtFolder" class="text-input" /></div>
                <button id="btnAddFolder" value="Save" class="button">Add</button>
                <button id="btnClose" value="Close" class="button btnClose">Close</button>
            </div>
        </div>

        <div id="float-box-preview" class="float-box-preview">
            <button id="float-box-preview-button-left" onclick="previewSlider(this,event,'left')" onkeydown="previewSlider(this,event,null)" button-index="" data-file-counter="" class="button"><</button>

            <div id="float-box-preview-box" class="float-box-preview-box">
                <div class="info-form">
                    <div class="close-x">
                        <button id="btnCloseInfo" value="Close" class="button btnClose">Close</button>
                    </div>
                    <h3 class="clear" id="google-file-preview-name">File Preview</h3>
                    <iframe id="google-file-preview" src="" data-file-counter="" ></iframe>
                </div>
               </div>

              <button id="float-box-preview-button-right" onclick="previewSlider(this,event,'right')" onkeydown="previewSlider(this,event,null)" button-index=""  data-file-counter="" class="button">></button>
        </div>

        <div id="float-box-text" class="float-box">
            <div class="info-form">
                <div class="close-x"><img id="imgCloseText" class="imgClose" src="images/button_close.png" alt="close" /></div>
                <h3 class="clear">Text Content</h3>
                <div id="text-content"></div>
                <button id="btnCloseText" value="Close" class="button btnClose">Close</button>
            </div>
        </div>
        <iframe id="frameLogout" class="hide"></iframe>
        <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>

google-drive.js

/*****
	Author: Manu Antony Vadassery , Jobin & Jismi IT Services LLP
    
    Revision 1 $ 24/11/2017  Manu Antony Vadassery : Bug Fix ( Loads the first folder when there are multiple folder of the same record name)
    
****/



/******************** GLOBAL VARIABLES ********************/
// Client ID and API key from the Developer Console
var CLIENT_ID =
    "971268855396-t1m379ldlsdroug8c6negnml68jc90vm.apps.googleusercontent.com";

// Array of API discovery doc URLs for APIs used by the quickstart
var DISCOVERY_DOCS = [
    "https://www.googleapis.com/discovery/v1/apis/drive/v3/rest"
];

// Authorization scopes required by the API; multiple scopes can be
// included, separated by spaces.
var SCOPES = [
    "https://www.googleapis.com/auth/drive",
    "profile",
    "email",
    "openid"
];


var FOLDER_NAME = "Netsuite";
var FOLDER_ID = "0B-E0q-jV3NwcQlFyZUsxOHVReGM";
var FOLDER_PERMISSION = true;
var FOLDER_LEVEL = 0;
var NO_OF_FILES = 1000;
var DRIVE_FILES = [];
var FILE_COUNTER = 0;
var FOLDER_ARRAY = [];
//var FOLDER_NAME = "";
var recordType, folderName, folderId;
var folderSubParentName, folderSubName, folderSubParent;
var FOLDER_ID_SubParent,
    FOLDER_NAME_SubParent,
    FOLDER_LEVEL_SubParent,
    FOLDER_PERMISSION_SubParent;
var FOLDER_ID_SubSubparent,
    FOLDER_NAME_SubSubparent,
    FOLDER_LEVEL_SubSubparent,
    FOLDER_PERMISSION_SubSubparent;
//To toggle between normal and list view, view=0-->normal,view=1-->list
var view = 0;
//To know current preview id so that we can cycle through previews
var buttonPreviewId;
// To show the current folder in Google Drive
var currentFolder;

/******************** AUTHENTICATION ********************/
var accessToken;
var idToken;
var authResult;

var authorizeButton = document.getElementById("btnLogin");
var signoutButton = document.getElementById("link-logout");

/**
 *  On load, called to load the auth2 library and API client library.
 */
function handleClientLoad() {
    gapi.load("client:auth2", initClient);
}

/**
 *  Initializes the API client library and sets up sign-in state
 *  listeners.
 */
function initClient() {
    gapi.client
        .init({
        discoveryDocs: DISCOVERY_DOCS,
        clientId: CLIENT_ID,
        scope: SCOPES.join(" ")
    })
        .then(function () {
        // Listen for sign-in state changes.
        gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);

        // Handle the initial sign-in state.
        updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
        $("#btnLogin").click(handleAuthClick);
        $("#link-logout").click(handleSignoutClick);
    });
}

/**
 *  Called when the signed in status changes, to update the UI
 *  appropriately. After a sign-in, the API is called.
 */
//check the return authentication of the login is successful, we display the drive box and hide the login box.
function updateSigninStatus(isSignedIn) {
    if (isSignedIn) {
        showUserInfo();
        showLoading();
        getDriveFiles();
        checkForDocumentFolder();
    } else {
        hideUserInfo();
    }
}

/**
 *  Sign in the user upon button click.
 */
function handleAuthClick(event) {
    gapi.auth2.getAuthInstance().signIn();
}

/**
 *  Sign out the user upon button click.
 */
function handleSignoutClick(event) {
    var c = confirm(
        "Are you sure you want to logout from your Google Drive account?"
    );
    if (c) {
        //$("#frameLogout").attr("src", "#");
        showLoading();
        $("#frameLogout").attr("src", "https://accounts.google.com/Logout");
        gapi.auth2.getAuthInstance().signOut();
        //gapi.auth2.getAuthInstance().disconnect();
        hideUserInfo();
    }
}


/******************** END AUTHENTICATION ********************/


/******************** PAGE LOAD ********************/

//To show user details after successfull signin
function showUserInfo() {
    $("#login-box").hide();
    $("#drive-info").show();
    $("#drive-google").show();
    $("#drive-location").show();
}

//To hide user details after signout
function hideUserInfo() {
    $("#transparent-wrapper").hide();
    $(".float-box").hide();
    $(".float-box-preview").hide();
    $("#login-box").show();
    $("#drive-box").hide();
    $("#drive-info").hide();
    $("#drive-location").hide();
    $("#drive-google").hide();
}

//To search for exiting document folder and loads it if found
function checkForDocumentFolder() {

    if (folderSubName) {
        var query = "";
        var mimeType = "application/vnd.google-apps.folder";
        query =
            "trashed=false and '" +
            folderId +
            "' in parents and name = '" +
            folderName +
            "'";
        var request = gapi.client.drive.files.list({
            q: query
        });
        request.execute(function (resp) {
            var searchLength = resp.files;
            //If there is already existing folder corresponding to the record name,get that folder id
            if (searchLength.length >= 1) {
                resp = resp.files[0];
                showStatus("Loading Google Drive files...");
                var levelNo = 2;
                var myObjParent = new Object();
                var myObjSubparent = new Object();
                var myObjSubSubparent = new Object();
                myObjParent = {
                    "data-id": "0B-E0q-jV3NwcQlFyZUsxOHVReGM",
                    "data-name": "Netsuite",
                    "data-level": "0",
                    "data-has-permission": " "
                };
                myObjSubparent = {
                    "data-id": folderSubParent,
                    "data-name": folderSubParentName,
                    "data-level": "1",
                    "data-has-permission": " "
                };
                myObjSubSubparent = {
                    "data-id": resp.id,
                    "data-name": resp.name,
                    "data-level": "2",
                    "data-has-permission": " "
                };
                currentFolder = resp.id;
                browseFolderDirect(
                    levelNo,
                    myObjParent,
                    myObjSubparent,
                    myObjSubSubparent
                );
            } else {
                hideStatus();
                hideLoading();
                //showErrorMessage("Error: " + resp.error.message);
            }
        });
    }
}

//To show file counter on 'Downlaod Selected(0)' button
function downloadMultipleCount(data) {
    var downloadMultiple = 0;
    for (var i = 0; i < $(".checkbox-selector").length; i++) {
        if ($(".checkbox-selector")[i].checked == true) {
            downloadMultiple++;
        }
    }
    $("#multiple-download").html("Download Selected(" + downloadMultiple + ")");
}

$(function () {
    //Prevent default settings for applying drag and drop
    $(document).on("drop dragover", function (e) {
        e.preventDefault();
    });
    $(".disabled").click(function (e) {
        e.preventDefault();
    });

    //Retrieve recordType,folderName,folderSubName,folderSubParentName on load
    $(document).ready(function () {

        var url = document.URL;
        var part = url.split("foldertype=")[1];
        recordType = part.split("?foldername=")[0];
        recordType=decodeURI(recordType);
        folderName = part.split("?foldername=")[1];
        folderName = folderName.split("?folderid=")[0];
        folderName=decodeURI(folderName);
        folderId = part.split("?folderid=")[1];
        folderId=decodeURI(folderId);
        folderSubParent=folderId;
        folderSubParentName=recordType;
        folderSubName = folderName;

    });

    //Refresh or Reloads the current folder
    $("#button-reload").click(function () {
        showLoading();
        showStatus("Loading Google Drive files...");
        $("#multiple-download").html("Download Selected(0)");
        getDriveFiles();
    });

    //View Document Folder in Google Drive
    $('#google-drive-link').click(function () {
        window.open("https://drive.google.com/drive/folders/" + currentFolder);
    });


    // FILE UPLOAD FUNCTION 
    $("#button-upload").click(function () {
        $("#fUpload").click();
    });

    $("#fUpload").bind("change", function () {
        var uploadObj = $("[id$=fUpload]");
        showLoading();
        showStatus("Uploading file in progress...");
        var file = uploadObj.prop("files")[0];
        var metadata = {
            title: file.name,
            description: "AKS - Upload to GoogleDrive from Netsuite",
            mimeType: file.type || "application/octet-stream",
            parents: [{
                kind: "drive#file",
                id: FOLDER_ID
            }]
        };
        var arrayBufferView = new Uint8Array(file);
        var uploadData = new Blob(arrayBufferView, {
            type: file.type || "application/octet-stream"
        });
        showProgressPercentage(0);

        try {
            var uploader = new MediaUploader({
                file: file,
                token: gapi.auth2
                .getAuthInstance()
                .currentUser.get()
                .getAuthResponse().access_token,
                metadata: metadata,
                onError: function (response) {
                    var errorResponse = JSON.parse(response);
                    showErrorMessage("Error: " + errorResponse.error.message);
                    $("#fUpload").val("");
                    $("#upload-percentage").hide(1000);
                    getDriveFiles();
                },
                onComplete: function (response) {
                    hideStatus();
                    $("#upload-percentage").hide(1000);
                    var errorResponse = JSON.parse(response);
                    if (errorResponse.message != null) {
                        showErrorMessage("Error: " + errorResponse.error.message);
                        $("#fUpload").val("");
                        getDriveFiles();
                    } else {
                        showStatus("Loading Google Drive files...");
                        getDriveFiles();
                    }
                },
                onProgress: function (event) {
                    showProgressPercentage(
                        Math.round(event.loaded / event.total * 100, 0)
                    );
                },
                params: {
                    convert: false,
                    ocr: false
                }
            });
            uploader.upload();
        } catch (exc) {
            showErrorMessage("Error: " + exc);
            $("#fUpload").val("");
            getDriveFiles();
        }
    });

    $("#button-share").click(function () {
        FOLDER_NAME = FOLDER_NAME_SubSubparent;
        FOLDER_ID = FOLDER_ID_SubSubparent;
        FOLDER_LEVEL = FOLDER_LEVEL_SubSubparent;
        FOLDER_PERMISSION = true;
        FOLDER_ARRAY = [];
        $("#span-navigation").html("");
        $(this).toggleClass("flash");
        if (
            $(this)
            .attr("class")
            .indexOf("flash") >= 0
        ) {
            $("#span-sharemode").html("ON");
        } else {
            $("#span-sharemode").html("OFF");
        }
        showLoading();
        showStatus("Loading Google Drive files...");
        getDriveFiles();
    });

    //To create new folder
    $("#button-addfolder").click(function () {
        $("#transparent-wrapper").show();
        $("#float-box").show();
        $("#txtFolder").val("");
    });

    //To crete a folder corresponding to record id
    $("#btnAddFolder").click(function () {
        if ($("#txtFolder").val() == "") {
            alert("Please enter the folder name");
        } else {
            $("#transparent-wrapper").hide();
            $("#float-box").hide();
            showLoading();
            showStatus("Creating folder in progress...");
            var access_token = gapi.auth2
            .getAuthInstance()
            .currentUser.get()
            .getAuthResponse().access_token;
            var request = gapi.client.request({
                path: "/drive/v2/files/",
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                    Authorization: "Bearer " + access_token
                },
                body: {
                    title: $("#txtFolder").val(),
                    mimeType: "application/vnd.google-apps.folder",
                    parents: [{
                        kind: "drive#file",
                        id: FOLDER_ID
                    }]
                }
            });

            request.execute(function (resp) {
                if (!resp.error) {
                    showStatus("Loading Google Drive files...");
                    getDriveFiles();
                } else {
                    hideStatus();
                    hideLoading();
                    showErrorMessage("Error: " + resp.error.message);
                }
            });
        }
    });

    //Create Record Type Folder
    $("#btnCreateFolder").click(function () {
        //folderSubParentName folderSubParent
        if (folderSubName) {
            var query = "";
            var mimeType = "application/vnd.google-apps.folder";
            query =
                "trashed=false and '" +
                folderSubParent +
                "' in parents and name = '" +
                folderSubName +
                "'";
            var request = gapi.client.drive.files.list({
                q: query
            });
            request.execute(function (resp) {
                var searchLength = resp.files;
                //searchLength.length;

                //If there is no folder corresponding to the record name,create that folder
                if (searchLength.length == 0) {
                    $("#transparent-wrapper").hide();
                    $("#float-box").hide();
                    showLoading();
                    showStatus("Creating folder in progress...");
                    var access_token = gapi.auth2
                    .getAuthInstance()
                    .currentUser.get()
                    .getAuthResponse().access_token;
                    var request = gapi.client.request({
                        path: "/drive/v2/files/",
                        method: "POST",
                        headers: {
                            "Content-Type": "application/json",
                            Authorization: "Bearer " + access_token
                        },
                        body: {
                            title: folderSubName,
                            mimeType: "application/vnd.google-apps.folder",
                            parents: [
                                {
                                    kind: "drive#file",
                                    id: folderSubParent
                                }
                            ]
                        }
                    });

                    request.execute(function (resp) {
                        if (!resp.error) {
                            showStatus("Loading Google Drive files...");
                            var levelNo = 2;
                            var myObjParent = new Object();
                            var myObjSubparent = new Object();
                            var myObjSubSubparent = new Object();
                            myObjParent = {
                                "data-id": "0B-E0q-jV3NwcQlFyZUsxOHVReGM",
                                "data-name": "Netsuite",
                                "data-level": "0",
                                "data-has-permission": " "
                            };
                            myObjSubparent = {
                                "data-id": folderSubParent,
                                "data-name": folderSubParentName,
                                "data-level": "1",
                                "data-has-permission": " "
                            };
                            myObjSubSubparent = {
                                "data-id": resp.id,
                                "data-name": resp.title,
                                "data-level": "2",
                                "data-has-permission": " "
                            };
                            currentFolder = resp.id;
                            browseFolderDirect(
                                levelNo,
                                myObjParent,
                                myObjSubparent,
                                myObjSubSubparent
                            );
                        } else {
                            hideStatus();
                            hideLoading();
                            showErrorMessage("Error: " + resp.error.message);
                        }
                    });
                }
                //If there is already existing folder corresponding to the record name,get that folder id
                else if (searchLength.length >= 1) {
                    resp = resp.files[0];
                    showStatus("Loading Google Drive files...");
                    var levelNo = 2;
                    var myObjParent = new Object();
                    var myObjSubparent = new Object();
                    var myObjSubSubparent = new Object();
                    myObjParent = {
                        "data-id": "0B-E0q-jV3NwcQlFyZUsxOHVReGM",
                        "data-name": "Netsuite",
                        "data-level": "0",
                        "data-has-permission": " "
                    };
                    myObjSubparent = {
                        "data-id": folderSubParent,
                        "data-name": folderSubParentName,
                        "data-level": "1",
                        "data-has-permission": " "
                    };
                    myObjSubSubparent = {
                        "data-id": resp.id,
                        "data-name": resp.name,
                        "data-level": "2",
                        "data-has-permission": " "
                    };
                    currentFolder = resp.id;
                    browseFolderDirect(
                        levelNo,
                        myObjParent,
                        myObjSubparent,
                        myObjSubSubparent
                    );
                } else {
                    hideStatus();
                    hideLoading();
                    //showErrorMessage("Error: " + resp.error.message);
                }
            });
        }
    });



    //Change Folder View
    $("#button-view").click(function () {
        showLoading();
        showStatus("Loading Google Drive files...");
        view = (view + 1) % 2;
        getDriveFiles();
    });

    //Download mutilpe files button
    $("#multiple-download").unbind("click");
    $("#multiple-download").click(function () {
        showLoading();
        showStatus("Downloading file in progress...");
        var fileId;
        var accessToken = gapi.auth2
        .getAuthInstance()
        .currentUser.get()
        .getAuthResponse().access_token;
        var i = 0;
        downloadBuffer();

        function downloadBuffer() {
            if (i < $(".checkbox-selector").length) {
                if ($(".checkbox-selector")[i].checked == true) {
                    FILE_COUNTER = $(".checkbox-selector")[i].dataset.fileCounter;
                    fileId = DRIVE_FILES[FILE_COUNTER].id;
                    var xhr = new XMLHttpRequest();
                    xhr.open(
                        "GET",
                        "https://www.googleapis.com/drive/v3/files/" +
                        fileId +
                        "?alt=media",
                        true
                    );
                    xhr.setRequestHeader("Authorization", "Bearer " + accessToken);
                    xhr.responseType = "arraybuffer";
                    xhr.send();
                    xhr.onload = function () {
                        var x = saveFile(
                            DRIVE_FILES[FILE_COUNTER].name,
                            DRIVE_FILES[FILE_COUNTER].mimeType,
                            xhr.response
                        );
                        if (x == undefined) {
                            i++;
                            downloadBuffer();
                        }
                    };
                } else {
                    i++;
                    downloadBuffer();
                }
            }
        }

        hideLoading();
        hideStatus();
    });

    //Close button action
    $(".btnClose, .imgClose").click(function () {
        $("#transparent-wrapper").hide();
        $(".float-box").hide();
        $(".float-box-preview").hide();
    });



});

/******************** END PAGE LOAD ********************/

/******************** DRIVER API ********************/
//Initialise the drive api to load/get files 
function getDriveFiles() {
    showStatus("Loading Google Drive files...");
    gapi.client.load("drive", "v3", getFiles);
}

//Query for searching and retrieving the files from drive 
function getFiles() {
    var query = "";
    if (ifShowSharedFiles()) {
        $(".button-opt").hide();
        query =
            FOLDER_ID == "0B-E0q-jV3NwcQlFyZUsxOHVReGM" ?
            "trashed=false and sharedWithMe" :
        "trashed=false and '" + FOLDER_ID + "' in parents";
        if (
            FOLDER_ID != "0B-E0q-jV3NwcQlFyZUsxOHVReGM" &&
            FOLDER_PERMISSION == "true"
        ) {
            $(".button-opt").show();
        }
    } else {
        $(".button-opt").show();
        query = "trashed=false and '" + FOLDER_ID + "' in parents";
    }
    var request = gapi.client.drive.files.list({
        maxResults: NO_OF_FILES,
        scope: "https://www.googleapis.com/auth/drive",
        q: query
    });

    request.execute(function (resp) {
        if (!resp.error) {
            DRIVE_FILES = resp.files;
            buildFiles();
        } else {
            showErrorMessage("Error: " + resp.error.message);
        }
    });
}


//Build folder contents(User Interface)
function buildFiles() {
    var fText = "";
    var buttonIndex = 0;
    if (view == 0) {
        if (DRIVE_FILES.length > 0) {
            for (var i = 0; i < DRIVE_FILES.length; i++) {
                DRIVE_FILES[i].id = DRIVE_FILES[i].id;
                DRIVE_FILES[i].name = DRIVE_FILES[i].name;
                DRIVE_FILES[i].mimeType = DRIVE_FILES[i].mimeType;
                DRIVE_FILES[i].fileExtension = getFileExtension(DRIVE_FILES[i].name);
                DRIVE_FILES[i].googleFileExtension = DRIVE_FILES[i].mimeType.split("/")[1];
                DRIVE_FILES[i].textContentURL = "";

                DRIVE_FILES[i].level = (parseInt(FOLDER_LEVEL) + 1).toString();

                DRIVE_FILES[i].thumbnailLink = DRIVE_FILES[i].thumbnailLink || "";

                DRIVE_FILES[i].fileType =
                    DRIVE_FILES[i].mimeType == "application/vnd.google-apps.folder" ?
                    "folder" :
                "file";

                var textContentURL = "";

                var textTitle =
                    DRIVE_FILES[i].fileType != "file" ?
                    "Browse " + DRIVE_FILES[i].name :
                DRIVE_FILES[i].name;

                fText += "<div class='" + DRIVE_FILES[i].fileType + "-box'>";

                if (DRIVE_FILES[i].fileType != "file") {
                    fText +=
                        "<div class='folder-icon' data-level='" +
                        DRIVE_FILES[i].level +
                        "' data-id='" +
                        DRIVE_FILES[i].id +
                        "' title='" +
                        textTitle +
                        "' data-name='" +
                        DRIVE_FILES[i].name +
                        "'><div class='image-preview'><img src='images/folder.png'/></div></div>";
                    fText +=
                        "<div class='item-title-folder' data-level='" +
                        DRIVE_FILES[i].level +
                        "' data-id='" +
                        DRIVE_FILES[i].id +
                        "' title='" +
                        textTitle +
                        "' data-name='" +
                        DRIVE_FILES[i].name +
                        "'>" +
                        DRIVE_FILES[i].name +
                        "</div>";
                } else {
                    if (DRIVE_FILES[i].thumbnailLink) {
                        fText +=
                            "<div class='download-checkbox'><input class='checkbox-selector'  type='checkbox' data-id='" +
                            DRIVE_FILES[i].id +
                            "' data-file-counter='" +
                            i +
                            "' onchange='downloadMultipleCount(this);'></div>";
                        fText +=
                            "<div class='image-icon' ' data-file-counter='" +
                            i +
                            "'><div class='image-preview'><a href='" +
                            DRIVE_FILES[i].thumbnailLink.replace("s220", "s800") +
                            "' data-lightbox='image-" +
                            i +
                            "'><img src='" +
                            DRIVE_FILES[i].thumbnailLink +
                            "'/></a></div></div>";
                    } else {
                        fText +=
                            "<div class='download-checkbox'><input class='checkbox-selector'  type='checkbox' data-id='" +
                            DRIVE_FILES[i].id +
                            "' data-file-counter='" +
                            i +
                            "' onchange='downloadMultipleCount(this);'></div>";
                        fText +=
                            "<div class='file-icon' ' data-file-counter='" +
                            i +
                            "'><div class='image-preview'><img src='images/" +
                            DRIVE_FILES[i].fileExtension +
                            "-icon.png" +
                            "'/></div></div>";
                    }
                    fText +=
                        "<div class='item-title-file' ' data-file-counter='" +
                        i +
                        "'>" +
                        DRIVE_FILES[i].name +
                        "</div>";
                }

                //button actions
                fText += "<div class='button-box'>";
                if (DRIVE_FILES[i].fileType != "folder") {
                    fText +=
                        "<span></span><button class='button-info' title='Info' onkeydown='previewSlider(this,event,null)' button-index='" +
                        buttonIndex +
                        "' data-id='" +
                        DRIVE_FILES[i].id +
                        "' data-file-counter='" +
                        i +
                        "'>Preview</button>";
                    fText +=
                        "<button class='button-download' style='margin-left: 2%;' title='Download' data-id='" +
                        DRIVE_FILES[i].id +
                        "' data-file-counter='" +
                        i +
                        "'>Download</button>";
                    buttonIndex++;
                }

                if (
                    DRIVE_FILES[i].textContentURL != null &&
                    DRIVE_FILES[i].textContentURL.length > 0
                ) {
                    fText +=
                        "<div class='button-text' title='Get Text' data-id='" +
                        DRIVE_FILES[i].id +
                        "' data-file-counter='" +
                        i +
                        "'></div>";
                }

                fText += "</div>";

                //closing div
                fText += "</div>";
            }
        } else {
            fText =
                "<div class='no-items'> There are currently no files in this folder <br> Drag & Drop Multiple files easily </div>";
        }
        var x = document.getElementById("drive-content");
        x.style.display = "block";
        hideStatus();
        $("#drive-folder-view").html(fText);
        x = document.getElementById("drive-folder-view");
        x.style.display = "block";
        x = document.getElementById("drive-list-view");
        x.style.display = "none";
    } else {
        if (DRIVE_FILES.length > 0) {
            for (var i = 0; i < DRIVE_FILES.length; i++) {
                DRIVE_FILES[i].id = DRIVE_FILES[i].id;
                DRIVE_FILES[i].name = DRIVE_FILES[i].name;
                DRIVE_FILES[i].mimeType = DRIVE_FILES[i].mimeType;
                DRIVE_FILES[i].fileExtension = getFileExtension(DRIVE_FILES[i].name);
                DRIVE_FILES[i].googleFileExtension = DRIVE_FILES[i].mimeType.split("/")[1];
                DRIVE_FILES[i].textContentURL = "";
                DRIVE_FILES[i].level = (parseInt(FOLDER_LEVEL) + 1).toString();
                DRIVE_FILES[i].thumbnailLink = DRIVE_FILES[i].thumbnailLink || "";
                DRIVE_FILES[i].fileType =
                    DRIVE_FILES[i].mimeType == "application/vnd.google-apps.folder" ?
                    "folder" :
                "file";

                var textContentURL = "";

                var textTitle =
                    DRIVE_FILES[i].fileType != "file" ?
                    "Browse " + DRIVE_FILES[i].name :
                DRIVE_FILES[i].name;

                fText += "<div class='" + DRIVE_FILES[i].fileType + "-boxlist'>";

                if (DRIVE_FILES[i].fileType != "file") {
                    fText +=
                        "<div class='folder-icon-list' data-level='" +
                        DRIVE_FILES[i].level +
                        "' data-id='" +
                        DRIVE_FILES[i].id +
                        "' title='" +
                        textTitle +
                        "' data-name='" +
                        DRIVE_FILES[i].name +
                        "'><div class='image-preview-list'><img src='images/folder.png'/></div></div>";
                    fText +=
                        "<div class='item-title-folder-list' data-level='" +
                        DRIVE_FILES[i].level +
                        "' data-id='" +
                        DRIVE_FILES[i].id +
                        "' title='" +
                        textTitle +
                        "' data-name='" +
                        DRIVE_FILES[i].name +
                        "'>" +
                        DRIVE_FILES[i].name +
                        "</div>";
                } else {
                    if (DRIVE_FILES[i].thumbnailLink) {
                        fText +=
                            "<div class='image-icon-list' ' data-file-counter='" +
                            i +
                            "'><div class='image-preview-list'><a href='" +
                            DRIVE_FILES[i].thumbnailLink.replace("s220", "s800") +
                            "' data-lightbox='image-" +
                            i +
                            "'><img src='" +
                            DRIVE_FILES[i].thumbnailLink +
                            "'/></a></div></div>";
                    } else {
                        fText +=
                            "<div class='file-icon-list' ' data-file-counter='" +
                            i +
                            "'><div class='image-preview-list'><img src='images/" +
                            DRIVE_FILES[i].fileExtension +
                            "-icon.png" +
                            "'/></div></div>";
                    }
                    fText +=
                        "<div class='item-title-file-list' ' data-file-counter='" +
                        i +
                        "'>" +
                        DRIVE_FILES[i].name +
                        "</div>";
                }

                //button actions
                fText += "<div class='button-box'>";
                if (DRIVE_FILES[i].fileType != "folder") {
                    fText +=
                        "<span></span><button class='button-info' title='Info' onkeydown='previewSlider(this,event,null)' button-index='" +
                        buttonIndex +
                        "' data-id='" +
                        DRIVE_FILES[i].id +
                        "' data-file-counter='" +
                        i +
                        "'>Preview</button>";
                    fText +=
                        "<button class='button-download' style='margin-left: 2%;' title='Download' data-id='" +
                        DRIVE_FILES[i].id +
                        "' data-file-counter='" +
                        i +
                        "'>Download</button>";
                    fText +=
                        "<div class='download-checkbox-list'><input class='checkbox-selector'  type='checkbox' data-id='" +
                        DRIVE_FILES[i].id +
                        "' data-file-counter='" +
                        i +
                        "' onchange='downloadMultipleCount(this);'></div>";
                    buttonIndex++;

                }

                if (
                    DRIVE_FILES[i].textContentURL != null &&
                    DRIVE_FILES[i].textContentURL.length > 0
                ) {
                    fText +=
                        "<div class='button-text' title='Get Text' data-id='" +
                        DRIVE_FILES[i].id +
                        "' data-file-counter='" +
                        i +
                        "'></div>";
                }

                fText += "</div>";

                //closing div
                fText += "</div>";
            }
        } else {
            fText =
                "<div class='no-items'> There are currently no files in this folder<br> Drag & Drop Multiple files easily </div>";
        }

        var x = document.getElementById("drive-content");
        x.style.display = "block";
        hideStatus();
        $("#drive-list-view").html(fText);
        x = document.getElementById("drive-folder-view");
        x.style.display = "none";
        x = document.getElementById("drive-list-view");
        x.style.display = "block";
    }
    initDriveButtons();
    hideLoading();
}

//To get file extension
function getFileExtension(filename) {
    return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename)[0] : undefined;
}

//Initialize the click button for each individual drive file/folder
//this need to be recalled everytime the Google Drive data is generated
function initDriveButtons() {
    //Initiate the delete button click
    $(".button-delete").unbind("click");
    $(".button-delete").click(function () {
        var c = confirm("Are you sure you want to delete this?");
        if (c) {
            showLoading();
            showStatus("Deleting file in progress...");
            var request = gapi.client.drive.files.delete({
                fileId: $(this).attr("data-id")
            });

            request.execute(function (resp) {
                hideStatus();
                if (resp.error) {
                    showErrorMessage("Error: " + resp.error.message);
                }
                getDriveFiles();
            });
        }
    });

    //Initiate the download button
    $(".button-download").unbind("click");
    $(".button-download").click(function () {
        showLoading();
        showStatus("Downloading file in progress...");
        FILE_COUNTER = $(this).attr("data-file-counter");
        var fileId = DRIVE_FILES[FILE_COUNTER].id;
        var accessToken = gapi.auth2
        .getAuthInstance()
        .currentUser.get()
        .getAuthResponse().access_token;
        var xhr = new XMLHttpRequest();
        xhr.open(
            "GET",
            "https://www.googleapis.com/drive/v3/files/" + fileId + "?alt=media",
            true
        );
        xhr.setRequestHeader("Authorization", "Bearer " + accessToken);
        xhr.responseType = "arraybuffer";
        xhr.onload = function () {
            saveFile(
                DRIVE_FILES[FILE_COUNTER].name,
                DRIVE_FILES[FILE_COUNTER].mimeType,
                xhr.response
            );
        };
        xhr.send();
        /*

                       // Alternate Download Method
                       window.open("https://drive.google.com/uc?export=download&id="+DRIVE_FILES[FILE_COUNTER].id);
                       <a href="https://drive.google.com/uc?export=download&id="+DRIVE_FILES[FILE_COUNTER].id downlaod/>

                        */

        setTimeout(function () {
            hideLoading();
            hideStatus();
        }, 1500);
    });

    //Initiate the Information button for preview
    $(".button-info").unbind("click");
    $(".button-info,.file-icon,.file-icon-list,.image-icon,.image-icon-list,.item-title-file,.item-title-file-list").click(function () {
        FILE_COUNTER = $(this).attr("data-file-counter");
        buttonPreviewId = $(this).attr("button-index");
        $("#transparent-wrapper").show();
        $("#float-box-preview").show();
        if (DRIVE_FILES[FILE_COUNTER] != null) {
            var previewFileID =
                "https://drive.google.com/file/d/" +
                DRIVE_FILES[FILE_COUNTER].id +
                "/preview";
            $("#google-file-preview").attr("src", previewFileID);
            $("#google-file-preview").attr("data-file-counter", FILE_COUNTER);
            $("#google-file-preview-name").html(DRIVE_FILES[FILE_COUNTER].name);
            var FILE_COUNTER_buttonPreviewIdRight;
            FILE_COUNTER_buttonPreviewIdRight = (Math.abs(buttonPreviewId + 1) % ($('.button-info').length));
            FILE_COUNTER = $('.button-info')[FILE_COUNTER_buttonPreviewIdRight].dataset.fileCounter;
            $("#float-box-preview-button-right").attr("button-index", FILE_COUNTER_buttonPreviewIdRight);
            $("#float-box-preview-button-right").attr("data-file-counter", FILE_COUNTER);
            var FILE_COUNTER_buttonPreviewIdLeft;
            FILE_COUNTER_buttonPreviewIdLeft = ((buttonPreviewId - 1) % ($('.button-info').length)) < 0 ? ($('.button-info').length - 1) : ((buttonPreviewId - 1) % ($('.button-info').length));
            FILE_COUNTER = $('.button-info')[FILE_COUNTER_buttonPreviewIdLeft].dataset.fileCounter;
            $("#float-box-preview-button-left").attr("button-index", FILE_COUNTER_buttonPreviewIdLeft);
            $("#float-box-preview-button-left").attr("data-file-counter", FILE_COUNTER);

        }
    });


    //Initiate the get text button
    $(".button-text").unbind("click");
    $(".button-text").click(function () {
        FILE_COUNTER = $(this).attr("data-file-counter");
        showLoading();
        showStatus("Getting text file in progress...");
        var accessToken = gapi.auth2
        .getAuthInstance()
        .currentUser.get()
        .getAuthResponse().access_token;
        var xhr = new XMLHttpRequest();
        xhr.open("GET", DRIVE_FILES[FILE_COUNTER]["exportLinks"]["text/plain"]);
        xhr.setRequestHeader("Authorization", "Bearer " + accessToken);
        xhr.onload = function () {
            callBackGetText(xhr.responseText);
        };
        xhr.onerror = function () {
            callBackGetText(null);
        };
        xhr.send();
    });

    //Initiate the click folder browse icon
    //For Default view
    $(".folder-icon,.item-title-folder").unbind("click");
    $(".folder-icon,.item-title-folder").click(function () {
        browseFolder($(this));
    });
    //For List View
    $(".folder-icon-list,.item-title-folder-list").unbind("click");
    $(".folder-icon-list,.item-title-folder-list").click(function () {
        browseFolder($(this));
    });

    //Initiate the breadcrumb navigation link click
    $("#drive-breadcrumb a").unbind("click");
    $("#drive-breadcrumb a").click(function () {
        browseFolder($(this));
    });
}


//To Cycle through preview by left/right arrow keys or on buton click
function previewSlider(data, ev, trigger) {
    //left=37,right=39
    var FILE_COUNTER_buttonPreviewId;
    if (buttonPreviewId == undefined) {
        buttonPreviewId = $(data).attr("button-index");
    }
    if (event.keyCode == 37 || event.keyCode == 39 || trigger != null) {
        event.preventDefault();
        if (event.keyCode == 37 || trigger == 'left') {
            FILE_COUNTER_buttonPreviewId = ((buttonPreviewId - 1) % ($('.button-info').length)) < 0 ? ($('.button-info').length - 1) : ((buttonPreviewId - 1) % ($('.button-info').length));
            FILE_COUNTER = $('.button-info')[FILE_COUNTER_buttonPreviewId].dataset.fileCounter;
        }
        if (event.keyCode == 39 || trigger == 'right') {
            FILE_COUNTER_buttonPreviewId = (Math.abs(buttonPreviewId + 1) % ($('.button-info').length));
            FILE_COUNTER = $('.button-info')[FILE_COUNTER_buttonPreviewId].dataset.fileCounter;
        }
        $("#transparent-wrapper").show();
        $("#float-box-preview").show();
        if (DRIVE_FILES[FILE_COUNTER] != null) {
            var previewFileID =
                "https://drive.google.com/file/d/" +
                DRIVE_FILES[FILE_COUNTER].id +
                "/preview";
            $("#google-file-preview").attr("src", previewFileID);
            $("#google-file-preview").attr("data-file-counter", FILE_COUNTER);
            $("#google-file-preview-name").html(DRIVE_FILES[FILE_COUNTER].name);
            var FILE_COUNTER_buttonPreviewIdLeft;
            FILE_COUNTER_buttonPreviewIdLeft = ((buttonPreviewId - 1) % ($('.button-info').length)) < 0 ? ($('.button-info').length - 1) : ((buttonPreviewId - 1) % ($('.button-info').length));
            //buttonPreviewId=FILE_COUNTER_buttonPreviewIdLeft;
            FILE_COUNTER = $('.button-info')[FILE_COUNTER_buttonPreviewIdLeft].dataset.fileCounter;
            $("#float-box-preview-button-left").attr("button-index", FILE_COUNTER_buttonPreviewIdLeft);
            $("#float-box-preview-button-left").attr("data-file-counter", FILE_COUNTER);
            var FILE_COUNTER_buttonPreviewIdRight;
            FILE_COUNTER_buttonPreviewIdRight = (Math.abs(buttonPreviewId + 1) % ($('.button-info').length));
            //buttonPreviewId=FILE_COUNTER_buttonPreviewIdRight;
            FILE_COUNTER = $('.button-info')[FILE_COUNTER_buttonPreviewIdRight].dataset.fileCounter;
            $("#float-box-preview-button-right").attr("button-index", FILE_COUNTER_buttonPreviewIdRight);
            $("#float-box-preview-button-right").attr("data-file-counter", FILE_COUNTER);
            buttonPreviewId = FILE_COUNTER_buttonPreviewId;
        }
    }
}


//Saves downloaded files from buffer/memory
function saveFile(name, type, data) {
    if (data != null && navigator.msSaveBlob)
        return navigator.msSaveBlob(
            new Blob([data], {
                type: type
            }),
            name
        );
    var a = $("<a style='display: none;'/>");
    var url = window.URL.createObjectURL(
        new Blob([data], {
            type: type
        })
    );
    a.attr("href", url);
    a.attr("download", name);
    $("body").append(a);
    a[0].click();
    window.URL.revokeObjectURL(url);
    a.remove();
}

//browse folder (To browse through folder,creating pathname)
function browseFolder(obj) {
    FOLDER_ID = $(obj).attr("data-id");
    FOLDER_NAME = $(obj).attr("data-name");
    FOLDER_LEVEL = parseInt($(obj).attr("data-level"));
    FOLDER_PERMISSION = $(obj).attr("data-has-permission");

    if (typeof FOLDER_NAME === "undefined") {
        FOLDER_NAME = FOLDER_NAME_SubSubparent;
        FOLDER_ID = FOLDER_ID_SubSubparent;
        FOLDER_LEVEL = FOLDER_LEVEL_SubSubparent;
        FOLDER_PERMISSION = true;
        FOLDER_ARRAY = [];
    } else {
        if (FOLDER_LEVEL == FOLDER_ARRAY.length && FOLDER_LEVEL > 0) {
            //do nothing
        } else if (FOLDER_LEVEL < FOLDER_ARRAY.length) {
            var tmpArray = cloneObject(FOLDER_ARRAY);
            FOLDER_ARRAY = [];

            for (var i = 0; i < tmpArray.length; i++) {
                FOLDER_ARRAY.push(tmpArray[i]);
                if (tmpArray[i].Level >= FOLDER_LEVEL) {
                    break;
                }
            }
        } else {
            var fd3 = {
                Name: FOLDER_NAME,
                ID: FOLDER_ID,
                Level: FOLDER_LEVEL,
                Permission: FOLDER_PERMISSION
            };
            FOLDER_ARRAY.push(fd3);
        }
    }

    var sbNav = "";
    for (var i = 0; i < 1; i++) {
        sbNav += "<span class='breadcrumb-arrow'></span>";
        sbNav +=
            "<span class='folder-name'><a class='disabled' data-id='" +
            FOLDER_ARRAY[i].ID +
            "' data-level='" +
            FOLDER_ARRAY[i].Level +
            "' data-name='" +
            FOLDER_ARRAY[i].Name +
            "' data-has-permission='" +
            FOLDER_PERMISSION +
            "'>" +
            FOLDER_ARRAY[i].Name +
            "</a></span>";
    }

    for (var i = 1; i < FOLDER_ARRAY.length; i++) {
        sbNav += "<span class='breadcrumb-arrow'></span>";
        sbNav +=
            "<span class='folder-name'><a data-id='" +
            FOLDER_ARRAY[i].ID +
            "' data-level='" +
            FOLDER_ARRAY[i].Level +
            "' data-name='" +
            FOLDER_ARRAY[i].Name +
            "' data-has-permission='" +
            FOLDER_PERMISSION +
            "'>" +
            FOLDER_ARRAY[i].Name +
            "</a></span>";
    }
    $("#span-navigation").html(sbNav.toString());

    showLoading();
    showStatus("Loading Google Drive files...");
    getDriveFiles();
}

//browse folderDirect (To directly view folder on the click of 'View contents on this folder' button,creating pathname)
function browseFolderDirect(levelNo, myObjParent, myObjSubparent, myObjSubSubparent) {
    FOLDER_ID = $(myObjSubSubparent).attr("data-id");
    FOLDER_NAME = $(myObjSubSubparent).attr("data-name");
    FOLDER_LEVEL = parseInt($(myObjSubSubparent).attr("data-level"));
    FOLDER_PERMISSION = $(myObjSubSubparent).attr("data-has-permission");
    //Setting subparent for fallback
    FOLDER_ID_SubParent = $(myObjSubparent).attr("data-id");
    FOLDER_NAME_SubParent = $(myObjSubparent).attr("data-name");
    FOLDER_LEVEL_SubParent = parseInt($(myObjSubparent).attr("data-level"));
    FOLDER_PERMISSION_SubParent = $(myObjSubparent).attr("data-has-permission");
    //Setting subsubparent for fallback
    FOLDER_ID_SubSubparent = $(myObjSubSubparent).attr("data-id");
    FOLDER_NAME_SubSubparent = $(myObjSubSubparent).attr("data-name");
    FOLDER_LEVEL_SubSubparent = parseInt($(myObjSubSubparent).attr("data-level"));
    FOLDER_PERMISSION_SubSubparent = $(myObjSubSubparent).attr(
        "data-has-permission"
    );
    if (typeof FOLDER_NAME === "undefined") {
        FOLDER_NAME = FOLDER_NAME_SubSubparent;
        FOLDER_ID = FOLDER_ID_SubSubparent;
        FOLDER_LEVEL = FOLDER_LEVEL_SubSubparent;
        FOLDER_PERMISSION = true;
        FOLDER_ARRAY = [];
    } else {
        var fd1 = {
            Name: FOLDER_NAME_SubParent,
            ID: FOLDER_ID_SubParent,
            Level: FOLDER_LEVEL_SubParent,
            Permission: FOLDER_PERMISSION_SubParent
        };
        FOLDER_ARRAY.push(fd1);
        var fd2 = {
            Name: FOLDER_NAME_SubSubparent,
            ID: FOLDER_ID_SubSubparent,
            Level: FOLDER_LEVEL_SubSubparent,
            Permission: FOLDER_PERMISSION_SubSubparent
        };
        FOLDER_ARRAY.push(fd2);
    }
    // class='disabled'

    var sbNav = "";
    sbNav += "<span class='breadcrumb-arrow'></span>";
    sbNav +=
        "<span class='folder-name'><a class='disabled' data-id='" +
        FOLDER_ID_SubParent +
        "' data-level='" +
        FOLDER_LEVEL_SubParent +
        "' data-name='" +
        FOLDER_NAME_SubParent +
        "' data-has-permission='" +
        FOLDER_PERMISSION_SubParent +
        "'>" +
        FOLDER_NAME_SubParent +
        "</a></span>";
    sbNav += "<span class='breadcrumb-arrow'></span>";
    sbNav +=
        "<span class='folder-name'><a  data-id='" +
        FOLDER_ID_SubSubparent +
        "' data-level='" +
        FOLDER_LEVEL_SubSubparent +
        "' data-name='" +
        FOLDER_NAME_SubSubparent +
        "' data-has-permission='" +
        FOLDER_PERMISSION_SubSubparent +
        "'>" +
        FOLDER_NAME_SubSubparent +
        "</a></span>";

    $("#span-navigation").html(sbNav.toString());

    showLoading();
    showStatus("Loading Google Drive files...");
    $("#drive-location").hide();
    getDriveFiles();

    setTimeout(function () {
        $("#drive-box").show();
        $("#drive-box").css("display", "inline-block");
    }, 1000);
}

//call back function for getting text
function callBackGetText(response) {
    if (response == null) {
        showErrorMessage("Error getting text content.");
    } else {
        hideLoading();
        hideStatus();
        $("#transparent-wrapper").show();
        $("#float-box-text").show();
        $("#text-content").html(response.replace(/(\r\n|\n|\r)/gm, "<br>"));
    }
}

//function to clone an object
function cloneObject(obj) {
    if (obj === null || typeof obj !== "object") {
        return obj;
    }
    var temp = obj.constructor();
    for (var key in obj) {
        temp[key] = cloneObject(obj[key]);
    }
    return temp;
}

//show whether the display mode is share files or not
function ifShowSharedFiles() {
    return $("#button-share.flash").length > 0 ? true : false;
}

//function to return bytes into different string data format
function formatBytes(bytes) {
    if (bytes < 1024) return bytes + " Bytes";
    else if (bytes < 1048576) return (bytes / 1024).toFixed(3) + " KB";
    else if (bytes < 1073741824) return (bytes / 1048576).toFixed(3) + " MB";
    else return (bytes / 1073741824).toFixed(3) + " GB";
}

/******************** DRAG AND DROP UPLOAD FUNCTION ********************/
/*            
    Process the drop

    The drop event is fired when the user drops the file(s).In the following drop handler,
    if the browser supports DataTransferItemList interface, the getAsFile() method is used to access each file;
    otherwise the DataTransfer interface's files property is used to access each file.

    Note that in this code any drag item that is not a file is ignored.
*/

function drop_handler(ev) {
    ev.preventDefault();
    // If dropped items aren't files, reject them
    var dt = ev.dataTransfer;
    if (dt.items) {
        // Use DataTransferItemList interface to access the file(s)
        for (var i = 0; i < dt.items.length; i++) {
            if (dt.items[i].kind == "file") {
                var f = dt.items[i].getAsFile();
                showLoading();
                showStatus("Uploading file in progress...");
                var file = f;
                var metadata = {
                    title: file.name,
                    description: "AKS - Upload to GoogleDrive from Netsuite",
                    mimeType: file.type || "application/octet-stream",
                    parents: [{
                        kind: "drive#file",
                        id: FOLDER_ID
                    }]
                };
                var arrayBufferView = new Uint8Array(file);
                var uploadData = new Blob(arrayBufferView, {
                    type: file.type || "application/octet-stream"
                });
                showProgressPercentage(0);

                try {
                    var uploader = new MediaUploader({
                        file: file,
                        token: gapi.auth2
                        .getAuthInstance()
                        .currentUser.get()
                        .getAuthResponse().access_token,
                        metadata: metadata,
                        onError: function (response) {
                            var errorResponse = JSON.parse(response);
                            showErrorMessage("Error: " + errorResponse.error.message);
                            $("#upload-percentage").hide(1000);
                            getDriveFiles();
                        },
                        onComplete: function (response) {
                            hideStatus();
                            $("#upload-percentage").hide(1000);
                            var errorResponse = JSON.parse(response);
                            if (errorResponse.message != null) {
                                showErrorMessage("Error: " + errorResponse.error.message);
                                getDriveFiles();
                            } else {
                                showStatus("Loading Google Drive files...");
                                getDriveFiles();
                            }
                        },
                        onProgress: function (event) {
                            showProgressPercentage(
                                Math.round(event.loaded / event.total * 100, 0)
                            );
                        },
                        params: {
                            convert: false,
                            ocr: false
                        }
                    });
                    uploader.upload();
                } catch (exc) {
                    showErrorMessage("Error: " + exc);
                    getDriveFiles();
                }

                console.log("... file[" + i + "].name = " + f.name);
            }
        }
    } else {
        // Use DataTransfer interface to access the file(s)
        for (var i = 0; i < dt.files.length; i++) {
            console.log("... file[" + i + "].name = " + dt.files[i].name);
        }
    }
}

/*                
    Prevent the browser's default drag behavior

    The following dragover event handler calls preventDefault() to turn off the browser's default drag and drop handler.

*/

function dragover_handler(ev) {
    // Prevent default select and drag behavior
    ev.preventDefault();
}

/*
    Cleanup

    The dragend handler is fired when the drag operation ends(signaling the drop has occurred or the drag has been canceled).
     In the following handler,if the browser supports the DataTransferItemList interface, the list's remove() method is used to 
     delete the file drag data; otherwise the DataTransfer object's clearData() method is used to delete the data.

*/

function dragend_handler(ev) {
    // Remove all of the drag data
    var dt = ev.dataTransfer;
    if (dt.items) {
        // Use DataTransferItemList interface to remove the drag data
        for (var i = 0; i < dt.items.length; i++) {
            dt.items.remove(i);
        }
    } else {
        // Use DataTransfer interface to remove the drag data
        ev.dataTransfer.clearData();
    }
}

/******************** END DRIVER API ********************/

/******************** NOTIFICATION ********************/
//show loading animation
function showLoading() {
    if ($("#drive-box-loading").length === 0) {
        $("#drive-box").prepend("<div id='drive-box-loading'></div>");
    }
    $("#drive-box-loading").html(
        "<div id='loading-wrapper'><div id='loading'><img src='images/loading-bubble.gif'></div></div>"
    );
}

//hide loading animation
function hideLoading() {
    $("#drive-box-loading").html("");
}

//show status message
function showStatus(text) {
    $("#status-message").show();
    $("#status-message").html(text);
}

//hide status message
function hideStatus() {
    $("#status-message").hide();
    $("#status-message").html("");
}

//show upload progress
function showProgressPercentage(percentageValue) {
    if ($("#upload-percentage").length == 0) {
        $("#drive-box").prepend("<div id='upload-percentage' class='flash'></div>");
    }
    if (!$("#upload-percentage").is(":visible")) {
        $("#upload-percentage").show(1000);
    }
    $("#upload-percentage").html(percentageValue.toString() + "%");
}

//show error message
function showErrorMessage(errorMessage) {
    $("#error-message").html(errorMessage);
    $("#error-message").show(100);
    setTimeout(function () {
        $("#error-message").hide(100);
    }, 3000);
}

/******************** END NOTIFICATION ********************/

upload.js

/**
* Helper for implementing retries with backoff. Initial retry
* delay is 1 second, increasing by 2x (+jitter) for subsequent retries
*
* @constructor
*/
var RetryHandler = function () {
    this.interval = 1000; // Start at one second
    this.maxInterval = 60 * 1000; // Don't wait longer than a minute 
};

/**
* Invoke the function after waiting
*
* @param {function} fn Function to invoke
*/
RetryHandler.prototype.retry = function (fn) {
    setTimeout(fn, this.interval);
    this.interval = this.nextInterval_();
};

/**
* Reset the counter (e.g. after successful request.)
*/
RetryHandler.prototype.reset = function () {
    this.interval = 1000;
};

/**
* Calculate the next wait time.
* @return {number} Next wait interval, in milliseconds
*
* @private
*/
RetryHandler.prototype.nextInterval_ = function () {
    var interval = this.interval * 2 + this.getRandomInt_(0, 1000);
    return Math.min(interval, this.maxInterval);
};

/**
* Get a random int in the range of min to max. Used to add jitter to wait times.
*
* @param {number} min Lower bounds
* @param {number} max Upper bounds
* @private
*/
RetryHandler.prototype.getRandomInt_ = function (min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min);
};


/**
* Helper class for resumable uploads using XHR/CORS. Can upload any Blob-like item, whether
* files or in-memory constructs.
*
* @example
* var content = new Blob(["Hello world"], {"type": "text/plain"});
* var uploader = new MediaUploader({
*   file: content,
*   token: accessToken,
*   onComplete: function(data) { ... }
*   onError: function(data) { ... }
* });
* uploader.upload();
*
* @constructor
* @param {object} options Hash of options
* @param {string} options.token Access token
* @param {blob} options.file Blob-like item to upload
* @param {string} [options.fileId] ID of file if replacing
* @param {object} [options.params] Additional query parameters
* @param {string} [options.contentType] Content-type, if overriding the type of the blob.
* @param {object} [options.metadata] File metadata
* @param {function} [options.onComplete] Callback for when upload is complete
* @param {function} [options.onProgress] Callback for status for the in-progress upload
* @param {function} [options.onError] Callback if upload fails
*/
var MediaUploader = function (options) {
    var noop = function () { };
    this.file = options.file;
    this.contentType = options.contentType || this.file.type || 'application/octet-stream';
    this.metadata = options.metadata || {
        'title': this.file.name,
        'mimeType': this.contentType
    };
    this.token = options.token;
    this.onComplete = options.onComplete || noop;
    this.onProgress = options.onProgress || noop;
    this.onError = options.onError || noop;
    this.offset = options.offset || 0;
    this.chunkSize = options.chunkSize || 0;
    this.retryHandler = new RetryHandler();

    this.url = options.url;
    if (!this.url) {
        var params = options.params || {};
        params.uploadType = 'resumable';
        this.url = this.buildUrl_(options.fileId, params, options.baseUrl);
    }
    this.httpMethod = options.fileId ? 'PUT' : 'POST';
};

/**
* Initiate the upload.
*/
MediaUploader.prototype.upload = function () {
    var self = this;
    var xhr = new XMLHttpRequest();

    xhr.open(this.httpMethod, this.url, true);
    xhr.setRequestHeader('Authorization', 'Bearer ' + this.token);
    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.setRequestHeader('X-Upload-Content-Length', this.file.size);
    xhr.setRequestHeader('X-Upload-Content-Type', this.contentType);

    xhr.onload = function (e) {
        if (e.target.status < 400) {
            var location = e.target.getResponseHeader('Location');
            this.url = location;
            this.sendFile_();
        } else {
            this.onUploadError_(e);
        }
    } .bind(this);
    xhr.onerror = this.onUploadError_.bind(this);
    xhr.send(JSON.stringify(this.metadata));
};

/**
* Send the actual file content.
*
* @private
*/
MediaUploader.prototype.sendFile_ = function () {
    var content = this.file;
    var end = this.file.size;

    if (this.offset || this.chunkSize) {
        // Only bother to slice the file if we're either resuming or uploading in chunks
        if (this.chunkSize) {
            end = Math.min(this.offset + this.chunkSize, this.file.size);
        }
        content = content.slice(this.offset, end);
    }

    var xhr = new XMLHttpRequest();
    xhr.open('PUT', this.url, true);
    xhr.setRequestHeader('Content-Type', this.contentType);
    xhr.setRequestHeader('Content-Range', "bytes " + this.offset + "-" + (end - 1) + "/" + this.file.size);
    xhr.setRequestHeader('X-Upload-Content-Type', this.file.type);
    if (xhr.upload) {
        xhr.upload.addEventListener('progress', this.onProgress);
    }
    xhr.onload = this.onContentUploadSuccess_.bind(this);
    xhr.onerror = this.onContentUploadError_.bind(this);
    xhr.send(content);
};

/**
* Query for the state of the file for resumption.
*
* @private
*/
MediaUploader.prototype.resume_ = function () {
    var xhr = new XMLHttpRequest();
    xhr.open('PUT', this.url, true);
    xhr.setRequestHeader('Content-Range', "bytes */" + this.file.size);
    xhr.setRequestHeader('X-Upload-Content-Type', this.file.type);
    if (xhr.upload) {
        xhr.upload.addEventListener('progress', this.onProgress);
    }
    xhr.onload = this.onContentUploadSuccess_.bind(this);
    xhr.onerror = this.onContentUploadError_.bind(this);
    xhr.send();
};

/**
* Extract the last saved range if available in the request.
*
* @param {XMLHttpRequest} xhr Request object
*/
MediaUploader.prototype.extractRange_ = function (xhr) {
    var range = xhr.getResponseHeader('Range');
    if (range) {
        this.offset = parseInt(range.match(/\d+/g).pop(), 10) + 1;
    }
};

/**
* Handle successful responses for uploads. Depending on the context,
* may continue with uploading the next chunk of the file or, if complete,
* invokes the caller's callback.
*
* @private
* @param {object} e XHR event
*/
MediaUploader.prototype.onContentUploadSuccess_ = function (e) {
    if (e.target.status == 200 || e.target.status == 201) {
        this.onComplete(e.target.response);
    } else if (e.target.status == 308) {
        this.extractRange_(e.target);
        this.retryHandler.reset();
        this.sendFile_();
    }
};

/**
* Handles errors for uploads. Either retries or aborts depending
* on the error.
*
* @private
* @param {object} e XHR event
*/
MediaUploader.prototype.onContentUploadError_ = function (e) {
    if (e.target.status && e.target.status < 500) {
        this.onError(e.target.response);
    } else {
        this.retryHandler.retry(this.resume_.bind(this));
    }
};

/**
* Handles errors for the initial request.
*
* @private
* @param {object} e XHR event
*/
MediaUploader.prototype.onUploadError_ = function (e) {
    this.onError(e.target.response); // TODO - Retries for initial upload
};

/**
* Construct a query string from a hash/object
*
* @private
* @param {object} [params] Key/value pairs for query string
* @return {string} query string
*/
MediaUploader.prototype.buildQuery_ = function (params) {
    params = params || {};
    return Object.keys(params).map(function (key) {
        return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
    }).join('&');
};

/**
* Build the drive upload URL
*
* @private
* @param {string} [id] File ID if replacing
* @param {object} [params] Query parameters
* @return {string} URL
*/
MediaUploader.prototype.buildUrl_ = function (id, params, baseUrl) {
    var url = baseUrl || 'https://www.googleapis.com/upload/drive/v2/files/';
    if (id) {
        url += id;
    }
    var query = this.buildQuery_(params);
    if (query) {
        url += '?' + query;
    }
    return url;
};

Leave a comment

Your email address will not be published. Required fields are marked *