воскресенье, 21 июня 2020 г.

Табличные диалоговые окна. Подсказки ввода dadata.ru

Таблицы google имеют достаточно большие возможности в построении различного рода CRM. Пользуясь не только формулами, но и скриптами, можно достаточно быстро выстроить модель обработки различного рода данных. 


Примером взаимодействия пользователя и таблицы может служить вызов скрипта с использованием кнопок и меню, созданных специально для того чтобы неподготовленный пользователь смог запустить нужную ему функцию. 
Таблицы порой могут разрастаться до невообразимой сложности и для исключения ошибок при вводе новых данных могут понадобиться подтверждающие действия. Захотел пользователь что то изменить очень важное, мы можем для уточнения его действий запросить подтверждение, используя встроенные средства. Например, скрипт создания нового листа в таблице:

function onOpen(e) {
  SpreadsheetApp.getUi() 
      .createMenu('Custom menu')
      .addItem('Создать лист', 'createNewSheet')
      .addItem('Создать лист с названием','createNewSheetWithName')
      .addToUi();
}
function createNewSheet(){
    let answer=Browser.msgBox('Вы собираетесь создать новый лист? Вы уверены?',Browser.Buttons.YES_NO);
    if (answer=='yes'){
        SpreadsheetApp.getActive().insertSheet().activate()
    }
}

Во-первых, мы добавили своё меню с одним пунктом Создать лист. Во-вторых, используя методы Browser создали дополнительную проверку для пользователя. И новый лист будет создан только если пользователь подтвердит и нажмёт Да. 
Методы Browser ограничены оповещением и набором кнопок. Было бы гораздо лучше если бы при создании нового листа мы могли бы задать его название. 

function createNewSheetWithName(){
    let answer = Browser.inputBox('Новый лист','Введите название листа' , Browser.Buttons.OK_CANCEL)
    if (answer!='cancel'){
        SpreadsheetApp.getActive().insertSheet().setName(answer).activate()
    }
}

При запуске данной функции будет запрашиваться название нового листа и при нажатии кнопки Ок будет вставляться новый лист и переименовываться.
На этом возможности Browser заканчиваются, а нам очень бы хотелось организовать ввод данных клиентов с помощью этакой формы со множеством полей:
Что же необходимо для того чтобы формы позволили вводить данные?

1. Необходимо сформировать файл html содержащий в себе такую форму
<!DOCTYPE html>
<html>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <base target="_top">
  <style>
.group {
  position: relative;
  margin-bottom: 30px;
}

input {
  font-size: 16px;
  padding: 10px;
  display: block;
  width: 300px;
  border: none;
  border-bottom: 1px solid #ccc;
}
input:focus {
  outline: none;
}
label {
  color: #999;
  font-size: 18px;
  position: absolute;
  pointer-events: none;
  left: 10px;
  top: 15px;
  transition: 0.2s ease all;
  -moz-transition: 0.2s ease all;
  -webkit-transition: 0.2s ease all;
}

/* active state */
input:focus ~ label, input:valid ~ label {
  top: -10px;
  font-size: 14px;
  color: #5264AE;
}


/* BOTTOM BARS ================================= */
.bar {
  position: relative;
  display: block;
  width: 320px;
}
.bar:before, .bar:after {
  content: "";
  height: 2px;
  width: 0;
  bottom: 0;
  position: absolute;
  background: #5264AE;
  transition: 0.2s ease all;
  -moz-transition: 0.2s ease all;
  -webkit-transition: 0.2s ease all;
}
.bar:before {
  left: 50%;
}
.bar:after {
  right: 50%;
}

/* active state */
input:focus ~ .bar:before,
input:focus ~ .bar:after {
  width: 50%;
}
      </style>
  </head>
  <body>
<form onsubmit="sendData(); return false;">
    <div class="group">      
       <input type="text" id="name">
       <span class="bar"></span>
       <label>ФИО:</label>
    </div>
    <div class="group">      
       <input type="text" id="address">
       <span class="bar"></span>
       <label>Адрес:</label>
    </div>
    <div class="group">      
      <input type="text" id="organisation">
      <span class="bar"></span>
      <label>Организация:</label>
   </div>
   <input type="submit" value="Ok">
 </form>
<script>
function sendData()
{
  var outData = {};
  var elements = document.forms[0].querySelectorAll( "input" );
  for(var i=0;i<elements.length;i++) outData[elements[i].id] = elements[i].value;
  google.script.run.sendData(outData);
  google.script.host.close()
}
   
</script>
  </body>
</html>
Стилевое наполнение было взято отсюда.

2. Написать функцию - обработчик данных который был указан в html файле, а именно функцию 
sendData:
function sendData(form){
  SpreadsheetApp.getActive().getSheetByName('Клиенты').appendRow([form.name, form.address,form.organisation])} 
  }
3. Написать функцию, которая позволит отображать наш html в интерфейсе таблиц, daData:
function daData(){
    let html=HtmlService.createHtmlOutputFromFile('index')
    SpreadsheetApp.getUi().showModelessDialog(html,'Ввод данных клиента')
}
здесь index - название нашего html файла в редакторе скриптов.
 
И вот вроде бы и всё, но хочется чего то большего и красивого. Хочется подключить к форме сервис подсказок dadata.ru - замечательно описанный сервис с api и большим количеством плюшек. 

Подсмотрев описание api подсказок, можно достаточно просто и быстро реализовать такую вещь.

Где посмотреть весь код и что то изменить для себя ? - 
Сделайте копию таблицы.

Если захотите воспользоваться подсказками daData.ru необходимо пройти у них регистрацию, из личного кабинета скопировать API ключ. И заменить в редакторе скриптов в файле index2.html в 104 строке myApiToken на свой.

Если остались вопросы милости прошу в комментарии.

PS: Достаточно давно в мессенджере Телеграм существует чат и канал, в которых помогают людям работающим с google таблицами.
Любой ваш вопрос по теме не останется без ответа.
Возникают вопросы, милости просим.
 

5 комментариев:

  1. Работает отлично! Спасибо!

    ОтветитьУдалить
  2. Роман, классно! подскажи как подключить выпадающий список из другого гугл-дока?

    ОтветитьУдалить
    Ответы
    1. Доброго дня.
      На отдельный лист вывести нужный список из нужной таблицы посредством importrange.

      Удалить