กล่องโต้ตอบและแถบด้านข้างในเอกสาร Google Workspace

สคริปต์ที่เชื่อมโยงกับ Google เอกสาร ชีต หรือฟอร์มจะแสดงองค์ประกอบอินเทอร์เฟซผู้ใช้ได้หลายประเภท เช่น การแจ้งเตือนและพรอมต์ที่สร้างไว้ล่วงหน้า รวมถึงกล่องโต้ตอบและแถบด้านข้างที่มีหน้าบริการ HTML ที่กำหนดเอง โดยปกติแล้ว องค์ประกอบเหล่านี้ จะเปิดจากรายการในเมนู (โปรดทราบว่าใน Google ฟอร์ม องค์ประกอบอินเทอร์เฟซผู้ใช้จะมองเห็นได้เฉพาะต่อผู้แก้ไขที่เปิดแบบฟอร์มเพื่อแก้ไขเท่านั้น ไม่ใช่ผู้ใช้ที่เปิดแบบฟอร์มเพื่อตอบกลับ)

กล่องโต้ตอบการแจ้งเตือน

การแจ้งเตือนคือกล่องโต้ตอบที่สร้างไว้ล่วงหน้าซึ่งจะเปิดในเครื่องมือแก้ไข Google เอกสาร ชีต สไลด์ หรือฟอร์ม ปุ่ม "ตกลง" จะแสดงข้อความและปุ่ม "ตกลง" โดยคุณไม่จำเป็นต้องระบุชื่อและปุ่มทางเลือก ซึ่งคล้ายกับการเรียกใช้ window.alert() ใน JavaScript ฝั่งไคลเอ็นต์ภายในเว็บเบราว์เซอร์

การแจ้งเตือนจะระงับสคริปต์ฝั่งเซิร์ฟเวอร์ขณะที่กล่องโต้ตอบเปิดอยู่ สคริปต์จะกลับมาทำงานอีกครั้งหลังจากที่ผู้ใช้ปิดกล่องโต้ตอบ แต่การเชื่อมต่อ JDBC จะไม่คงอยู่ในระหว่างการระงับ

ดังที่แสดงในตัวอย่างด้านล่าง ทั้ง Google เอกสาร, ฟอร์ม, สไลด์ และชีตจะใช้เมธอด Ui.alert() ซึ่งมีอยู่ใน 3 รูปแบบ หากต้องการลบล้างปุ่ม "ตกลง" เริ่มต้น ให้ส่งค่าจาก enum Ui.ButtonSet เป็นอาร์กิวเมนต์ buttons หากต้องการประเมินว่าผู้ใช้คลิกปุ่มใด ให้เปรียบเทียบค่าที่แสดงผลสำหรับ alert() กับ enum ของ Ui.Button

function onOpen() {
  SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
      .createMenu('Custom Menu')
      .addItem('Show alert', 'showAlert')
      .addToUi();
}

function showAlert() {
  var ui = SpreadsheetApp.getUi(); // Same variations.

  var result = ui.alert(
     'Please confirm',
     'Are you sure you want to continue?',
      ui.ButtonSet.YES_NO);

  // Process the user's response.
  if (result == ui.Button.YES) {
    // User clicked "Yes".
    ui.alert('Confirmation received.');
  } else {
    // User clicked "No" or X in the title bar.
    ui.alert('Permission denied.');
  }
}

กล่องโต้ตอบการแจ้ง

พรอมต์คือกล่องโต้ตอบที่สร้างไว้ล่วงหน้าซึ่งจะเปิดขึ้นภายในเครื่องมือแก้ไข Google เอกสาร ชีต สไลด์ หรือฟอร์ม ปุ่ม "ตกลง" จะแสดงข้อความ ช่องป้อนข้อความ และปุ่ม "ตกลง" โดยคุณตั้งชื่อและปุ่มทางเลือกหรือไม่ก็ได้ ซึ่งคล้ายกับการเรียกใช้ window.prompt() ใน JavaScript ฝั่งไคลเอ็นต์ภายในเว็บเบราว์เซอร์

ข้อความแจ้งจะระงับสคริปต์ฝั่งเซิร์ฟเวอร์ขณะที่กล่องโต้ตอบเปิดอยู่ สคริปต์จะกลับมาทำงานอีกครั้งหลังจากที่ผู้ใช้ปิดกล่องโต้ตอบ แต่การเชื่อมต่อ JDBC จะไม่คงอยู่ในระหว่างการระงับ

ดังที่แสดงในตัวอย่างด้านล่าง Google เอกสาร ฟอร์ม สไลด์ และชีตจะใช้เมธอด Ui.prompt() ซึ่งมี 3 รูปแบบ หากต้องการลบล้างปุ่ม "ตกลง" เริ่มต้น ให้ส่งค่าจาก enum Ui.ButtonSet เป็นอาร์กิวเมนต์ buttons หากต้องการประเมินคำตอบของผู้ใช้ ให้บันทึกค่าที่แสดงผลสำหรับ prompt() จากนั้นเรียกใช้ PromptResponse.getResponseText() เพื่อดึงข้อมูลของผู้ใช้ และเปรียบเทียบค่าที่ส่งกลับสำหรับ PromptResponse.getSelectedButton() กับค่าแจกแจง Ui.Button

function onOpen() {
  SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
      .createMenu('Custom Menu')
      .addItem('Show prompt', 'showPrompt')
      .addToUi();
}

function showPrompt() {
  var ui = SpreadsheetApp.getUi(); // Same variations.

  var result = ui.prompt(
      'Let\'s get to know each other!',
      'Please enter your name:',
      ui.ButtonSet.OK_CANCEL);

  // Process the user's response.
  var button = result.getSelectedButton();
  var text = result.getResponseText();
  if (button == ui.Button.OK) {
    // User clicked "OK".
    ui.alert('Your name is ' + text + '.');
  } else if (button == ui.Button.CANCEL) {
    // User clicked "Cancel".
    ui.alert('I didn\'t get your name.');
  } else if (button == ui.Button.CLOSE) {
    // User clicked X in the title bar.
    ui.alert('You closed the dialog.');
  }
}

กล่องโต้ตอบที่กำหนดเอง

กล่องโต้ตอบที่กำหนดเองแสดงอินเทอร์เฟซผู้ใช้บริการ HTML ภายในเครื่องมือแก้ไข Google เอกสาร ชีต สไลด์ หรือฟอร์มได้

กล่องโต้ตอบที่กําหนดเองจะไม่ระงับสคริปต์ฝั่งเซิร์ฟเวอร์ขณะที่กล่องโต้ตอบเปิดอยู่ คอมโพเนนต์ฝั่งไคลเอ็นต์จะเรียกใช้สคริปต์ฝั่งเซิร์ฟเวอร์แบบไม่พร้อมกันโดยใช้ google.script API สำหรับอินเทอร์เฟซบริการ HTML ได้

กล่องโต้ตอบจะปิดตัวเองได้ด้วยการเรียกใช้ google.script.host.close() ในฝั่งไคลเอ็นต์ของอินเทอร์เฟซบริการ HTML อินเทอร์เฟซอื่นๆ ไม่สามารถปิดกล่องโต้ตอบได้ โดยมีเพียงผู้ใช้หรือตัวมันเองเท่านั้น

ดังที่แสดงในตัวอย่างด้านล่าง ทั้ง Google เอกสาร, ฟอร์ม, สไลด์ และชีตจะใช้เมธอด Ui.showModalDialog() เพื่อเปิดกล่องโต้ตอบ

Code.gs

function onOpen() {
  SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
      .createMenu('Custom Menu')
      .addItem('Show dialog', 'showDialog')
      .addToUi();
}

function showDialog() {
  var html = HtmlService.createHtmlOutputFromFile('Page')
      .setWidth(400)
      .setHeight(300);
  SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
      .showModalDialog(html, 'My custom dialog');
}

Page.html

Hello, world! <input type="button" value="Close" onclick="google.script.host.close()" />

แถบด้านข้างที่กำหนดเอง

แถบด้านข้างแสดงอินเทอร์เฟซผู้ใช้บริการ HTML ภายในเครื่องมือแก้ไข Google เอกสาร ฟอร์ม สไลด์ และชีตได้

แถบด้านข้างจะไม่ระงับสคริปต์ฝั่งเซิร์ฟเวอร์ขณะที่กล่องโต้ตอบเปิดอยู่ คอมโพเนนต์ฝั่งไคลเอ็นต์จะเรียกใช้สคริปต์ฝั่งเซิร์ฟเวอร์แบบไม่พร้อมกันโดยใช้ google.script API สำหรับอินเทอร์เฟซบริการ HTML ได้

แถบด้านข้างจะปิดตัวเองได้โดยเรียกใช้ google.script.host.close() ในฝั่งไคลเอ็นต์ของอินเทอร์เฟซบริการ HTML อินเทอร์เฟซอื่นๆ ไม่สามารถปิดแถบด้านข้างได้ แต่มีเพียงตัวผู้ใช้หรือตัวผู้ใช้เองเท่านั้น

ดังที่แสดงในตัวอย่างด้านล่าง ทั้ง Google เอกสาร, ฟอร์ม, สไลด์ และชีตจะใช้เมธอด Ui.showSidebar() เพื่อเปิดแถบด้านข้าง

Code.gs

function onOpen() {
  SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
      .createMenu('Custom Menu')
      .addItem('Show sidebar', 'showSidebar')
      .addToUi();
}

function showSidebar() {
  var html = HtmlService.createHtmlOutputFromFile('Page')
      .setTitle('My custom sidebar');
  SpreadsheetApp.getUi() // Or DocumentApp or SlidesApp or FormApp.
      .showSidebar(html);
}

Page.html

Hello, world! <input type="button" value="Close" onclick="google.script.host.close()" />

กล่องโต้ตอบการเปิดไฟล์

Google Picker เป็นกล่องโต้ตอบ "เปิดไฟล์" สำหรับข้อมูลที่เก็บไว้ในเซิร์ฟเวอร์ของ Google ซึ่งรวมถึง Google ไดรฟ์, Google Image Search, Google Video Search และอื่นๆ

ดังที่แสดงในตัวอย่างด้านล่าง JavaScript API ฝั่งไคลเอ็นต์ของ Picker จะใช้ในบริการ HTML เพื่อสร้างกล่องโต้ตอบที่กำหนดเองซึ่งอนุญาตให้ผู้ใช้เลือกไฟล์ที่มีอยู่หรืออัปโหลดไฟล์ใหม่ แล้วส่งต่อการเลือกนั้นกลับไปยังสคริปต์เพื่อใช้งานต่อไป

หากต้องการเปิดใช้เครื่องมือเลือกและรับคีย์ API ให้ทำตามวิธีการต่อไปนี้

  1. ตรวจสอบว่าโปรเจ็กต์สคริปต์ใช้โปรเจ็กต์ GCP มาตรฐานอยู่
  2. เปิดใช้ "Google Picker API" ในโปรเจ็กต์ Google Cloud
  3. ขณะที่โปรเจ็กต์ Google Cloud ยังเปิดอยู่ ให้เลือก API และบริการ จากนั้นคลิกข้อมูลเข้าสู่ระบบ
  4. คลิกสร้างข้อมูลเข้าสู่ระบบ > คีย์ API การดำเนินการนี้จะสร้างคีย์ แต่คุณควรแก้ไขคีย์เพื่อเพิ่มทั้งการจำกัดแอปพลิเคชันและการจำกัด API ให้กับคีย์
  5. คลิกปิดในกล่องโต้ตอบคีย์ API
  6. ถัดจากคีย์ API ที่คุณสร้าง ให้คลิกเพิ่มเติม ไอคอนเพิ่มเติม> แก้ไขคีย์ API
  7. ในส่วนข้อจำกัดแอปพลิเคชัน ให้ทำตามขั้นตอนต่อไปนี้

    1. เลือกผู้อ้างอิง HTTP (เว็บไซต์)
    2. ในส่วนการจำกัดเว็บไซต์ ให้คลิกเพิ่มรายการ
    3. คลิก Referrer แล้วป้อน *.google.com
    4. เพิ่มรายการอื่นและป้อน *.googleusercontent.com เป็นผู้อ้างอิง
    5. คลิกเสร็จ
  8. ทำตามขั้นตอนต่อไปนี้ในส่วนข้อจำกัด API

    1. เลือกจำกัดคีย์
    2. ในส่วนเลือก API ให้เลือก Google Picker API และคลิกตกลง

      หมายเหตุ: Google Picker API จะไม่ปรากฏขึ้นจนกว่าคุณจะเปิดใช้ เนื่องจากรายการจะแสดงเฉพาะ API ที่เปิดใช้สำหรับโปรเจ็กต์ Cloud เท่านั้น

  9. ในส่วนคีย์ API ให้คลิกคัดลอกไปยังคลิปบอร์ด คัดลอกไปยังคลิปบอร์ด

  10. คลิกบันทึกด้านล่าง

code.gs

picker/code.gs
/**
 * Creates a custom menu in Google Sheets when the spreadsheet opens.
 */
function onOpen() {
  try {
    SpreadsheetApp.getUi().createMenu('Picker')
        .addItem('Start', 'showPicker')
        .addToUi();
  } catch (e) {
    // TODO (Developer) - Handle exception
    console.log('Failed with error: %s', e.error);
  }
}

/**
 * Displays an HTML-service dialog in Google Sheets that contains client-side
 * JavaScript code for the Google Picker API.
 */
function showPicker() {
  try {
    const html = HtmlService.createHtmlOutputFromFile('dialog.html')
        .setWidth(600)
        .setHeight(425)
        .setSandboxMode(HtmlService.SandboxMode.IFRAME);
    SpreadsheetApp.getUi().showModalDialog(html, 'Select a file');
  } catch (e) {
    // TODO (Developer) - Handle exception
    console.log('Failed with error: %s', e.error);
  }
}

/**
 * Gets the user's OAuth 2.0 access token so that it can be passed to Picker.
 * This technique keeps Picker from needing to show its own authorization
 * dialog, but is only possible if the OAuth scope that Picker needs is
 * available in Apps Script. In this case, the function includes an unused call
 * to a DriveApp method to ensure that Apps Script requests access to all files
 * in the user's Drive.
 *
 * @return {string} The user's OAuth 2.0 access token.
 */
function getOAuthToken() {
  try {
    DriveApp.getRootFolder();
    return ScriptApp.getOAuthToken();
  } catch (e) {
    // TODO (Developer) - Handle exception
    console.log('Failed with error: %s', e.error);
  }
}

dialog.html

picker/dialog.html
<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
  <script>
    // IMPORTANT: Replace the value for DEVELOPER_KEY with the API key obtained
    // from the Google Developers Console.
    var DEVELOPER_KEY = 'ABC123 ... ';
    var DIALOG_DIMENSIONS = {width: 600, height: 425};
    var pickerApiLoaded = false;

    /**
     * Loads the Google Picker API.
     */
    function onApiLoad() {
      gapi.load('picker', {'callback': function() {
        pickerApiLoaded = true;
      }});
     }

    /**
     * Gets the user's OAuth 2.0 access token from the server-side script so that
     * it can be passed to Picker. This technique keeps Picker from needing to
     * show its own authorization dialog, but is only possible if the OAuth scope
     * that Picker needs is available in Apps Script. Otherwise, your Picker code
     * will need to declare its own OAuth scopes.
     */
    function getOAuthToken() {
      google.script.run.withSuccessHandler(createPicker)
          .withFailureHandler(showError).getOAuthToken();
    }

    /**
     * Creates a Picker that can access the user's spreadsheets. This function
     * uses advanced options to hide the Picker's left navigation panel and
     * default title bar.
     *
     * @param {string} token An OAuth 2.0 access token that lets Picker access the
     *     file type specified in the addView call.
     */
    function createPicker(token) {
      if (pickerApiLoaded && token) {
        var picker = new google.picker.PickerBuilder()
            // Instruct Picker to display only spreadsheets in Drive. For other
            // views, see https://developers.google.com/picker/docs/#otherviews
            .addView(google.picker.ViewId.SPREADSHEETS)
            // Hide the navigation panel so that Picker fills more of the dialog.
            .enableFeature(google.picker.Feature.NAV_HIDDEN)
            // Hide the title bar since an Apps Script dialog already has a title.
            .hideTitleBar()
            .setOAuthToken(token)
            .setDeveloperKey(DEVELOPER_KEY)
            .setCallback(pickerCallback)
            .setOrigin(google.script.host.origin)
            // Instruct Picker to fill the dialog, minus 2 pixels for the border.
            .setSize(DIALOG_DIMENSIONS.width - 2,
                DIALOG_DIMENSIONS.height - 2)
            .build();
        picker.setVisible(true);
      } else {
        showError('Unable to load the file picker.');
      }
    }

    /**
     * A callback function that extracts the chosen document's metadata from the
     * response object. For details on the response object, see
     * https://developers.google.com/picker/docs/result
     *
     * @param {object} data The response object.
     */
    function pickerCallback(data) {
      var action = data[google.picker.Response.ACTION];
      if (action == google.picker.Action.PICKED) {
        var doc = data[google.picker.Response.DOCUMENTS][0];
        var id = doc[google.picker.Document.ID];
        var url = doc[google.picker.Document.URL];
        var title = doc[google.picker.Document.NAME];
        document.getElementById('result').innerHTML =
            '<b>You chose:</b><br>Name: <a href="' + url + '">' + title +
            '</a><br>ID: ' + id;
      } else if (action == google.picker.Action.CANCEL) {
        document.getElementById('result').innerHTML = 'Picker canceled.';
      }
    }

    /**
     * Displays an error message within the #result element.
     *
     * @param {string} message The error message to display.
     */
    function showError(message) {
      document.getElementById('result').innerHTML = 'Error: ' + message;
    }
  </script>
</head>
<body>
  <div>
    <button onclick="getOAuthToken()">Select a file</button>
    <p id="result"></p>
  </div>
  <script src="https://apis.google.com/js/api.js?onload=onApiLoad"></script>
</body>
</html>