Сделай сам: менеджер шаблонных ответов на любые письма
easy

Сделай сам: менеджер шаблонных ответов на любые письма

Отправляем текст в буфер обмена одним кликом.

Иногда на работе нужно дать шаблонные ответы: например, «отбивку» о полученной задаче, стандартное извинение в соцсетях, напоминание по задаче или приглашение на встречу. Чтобы каждый раз не сочинять письмо заново, сделаем что-то вроде менеджера шаблонов.

Это будет специальная страница с заранее прописанными шаблонами. Вам останется только кликнуть по шаблону и вставить текст в нужном месте. Пока что всё будет выглядеть и работать просто, а в будущих частях разовьём идею и сделаем красиво.

Логика проекта

Так как это веб-страница, писать будем на HTML и JavaScript. За основу возьмём наш стандартный шаблон.

<!DOCTYPE html>
<html>
<!-- Служебная часть -->

<head>
  <!-- Заголовок страницы -->
  <title>Заголовок</title>
  <!-- Настраиваем служебную информацию для браузеров -->
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style type="text/css">
    /*Тут будут стили */
  </style>
  <!-- Закрываем служебную часть страницы -->
</head>

<body>
  <!-- Тут будет наша страница -->
</body>
<!-- Конец всей страницы -->

</html>

Принцип работы:

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

Смысл в том, что теперь можно ничего не выделять мышкой, чтобы скопировать текст — достаточно нажать на шаблон, и он уже в буфере обмена. Это быстрее и удобнее.

Заполняем страницу

Первым делом пишем заголовок:

<h1>Выберите шаблон ответа</h1>

Чтобы потом в скрипте понимать, куда именно нажал пользователь, завернём каждый текстовый шаблон в отдельный блок тегом <div>..</div>. Это позволит нам присвоить каждому блоку своё уникальное имя и даст нам возможность оформить их красиво. Для переноса строк и деления на абзацы используем тег <br> — он вставляет перенос на новую строку.

<div id="sel01_div">Здравствуйте!
  <br>
  <br>
  Спасибо за письмо — я обязательно рассмотрю его и совсем скоро дам ответ.</div>
<div id="sel02_div">Привет!
  <br>
  <br>
  Я видел, что ты мне прислал. Отпишусь, как будет время, ага?</div>
<div id="sel03_div">Коллеги! Спешу напомнить вам, что этот вопрос в приоритете у руководства, поэтому примите все
  возможные меры для скорейшего разрешения ситуации.
  <br>
  <br>
  Стейкхолдера по задаче прошу уделить ей особое внимание, результат нужен ASAP.</div>

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

А ещё мы тут применяем одну хитрость. Посмотрите на id у каждого блока — у них отличается только цифра и окончание. Это пригодится нам для следующих элементов, где будем хранить сами шаблоны — мы назовём их точно так же, но без окончания h2. Благодаря этому мы сможем обработать все клики в одной функции.

Пока всё выглядит мелко и некрасиво. Сейчас исправим.

Добавляем красоту

Чтобы наша страница с шаблонами выглядела немного красивее и ей было удобно пользоваться, добавим стиля.

Текст должен стать крупнее и читаемее. Для этого мы:

  • увеличим размер текста
  • поменяем шрифт
  • добавим отступы
  • явно пропишем, что текст в обычном состоянии чёрный — это пригодится нам на втором этапе.

То же самое в виде стилей:

div{
   font-size: 20px;
   font-family: 'Arial';
   margin: 60px;
   color: black;
   }

А теперь сделаем так, чтобы при наведении мышки у нас подсвечивался выбранный шаблон. Нам понадобится ховер — мы уже рассказывали о нём, когда делали стильные ссылки:

/*подсвечиваем текст при наведении на него*/
   div:hover{
color: #cf0000;
   }
Всё ещё не идеально, но намного понятнее

Готовим шаблоны для копирования

Кажется, что всё готово к тому, чтобы мы начали писать скрипт, но ещё рано. Последнее, что нам осталось, — подготовить сами шаблоны.

Мы не можем использовать тот текст, который внутри блока div — если мы получим его содержимое с помощью свойства document.getElementById().InnerHTML, то у нас будут в шаблоне все теги, которые мы прописали внутри блока: <br>, <p> и все остальные. Чтобы у нас копировался только текст, мы сделаем на странице невидимые элементы textarea и положим шаблоны туда. Они поддерживают переносы строк, поэтому нам не нужно будет использовать дополнительные теги — как мы напишем, так и будет скопировано.

За невидимость отвечает атрибут hidden="true" — мы пропишем его в каждом элементе. А чтобы мы могли их различать, у каждого шаблона будет своё имя. Оно будет совпадать с именем соответствующего блока <div>, но без окончания «_div». Если мы в скрипте сможем отбросить эту часть (а мы сможем), то можно будет сделать всего один обработчик на всю страницу. А пока просто добавим эти элементы на страницу:

<!-- а вот тут уже сами наши шаблоны, которые пойдут в буфер обмена  -->
<textarea id='sel01' hidden="true">Здравствуйте!
  Спасибо за письмо — я обязательно рассмотрю его и совсем скоро дам ответ.</textarea>
<textarea id='sel02' hidden="true">Привет!
  
  Я видел, что ты мне прислал. Отпишусь, как будет время, ага?</textarea>

И так далее для остальных шаблонов. Решение костыльное, но быстрое и рабочее.

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

Или так: на странице вывести короткие названия шаблонов, а в textarea вставить их полные тексты. Это вариант для тех, кто делает решение лично для себя.

Пишем скрипт

У нас всё готово, осталось добавить на страницу обработчик нажатия на блок с шаблоном текста.

Прежде всего подключаем jQuery — будем использовать его для того, чтобы находить элементы на странице по их именам:

<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

Чтобы не писать много одинаковых функций, которые делают то же самое, сделаем одну на всех. Для этого мы прямо в объявлении обработчика события click через запятую перечислим все имена объектов, за которыми надо следить. Так как мы нажимаем на блоки с текстом, которые оформлены внутри блоков <div>..</div>, то и имена возьмём оттуда. В нынешней реализации их может быть не более 100 штук.

Единственная магия, которую мы делаем в скрипте, — это создание виртуальной текстовой области на странице, через которую мы копируем текст. Работает это так:

  • мы не можем выделить текст в существующих элементах textarea, потому что они невидимые и в них текст не выделяется.
  • чтобы это обойти, мы создаём виртуальный такой же элемент, в который копируем нужный текст.
  • затем мы его виртуально размещаем на странице , выделяем внутри него весь текст и копируем его в буфер обмена.
  • чтобы этот элемент не висел в памяти, удаляем его сразу после использования.

То же самое на языке JavaScript:

// строковая переменная, которая нам поможет обратиться к скрытым элементам с шаблонами
var s;
// обработчик клика, который следит сразу за всеми нужными разделами с шаблонами
$('#sel02_div, #sel01_div, #sel03_div, #sel04_div, #sel05_div, #sel06_div').on('click', function () {
  // получаем имя элемента, на который кликнули 
  s = this.id;
  // берём первые 5 символов, чтобы по ним обратиться к скрытым элементам
  s = s.slice(0, 5);
  // создаём временный новый элемент textarea, из которого буфер обмена заберёт текст шаблона
  var aux = document.createElement("textarea");
  // отправляем в этот элемент текст из нужного шаблона
  aux.value = document.getElementById(s).value;
  // виртуально добавляем этот элемент на страницу
  document.body.appendChild(aux);
  // выбираем весь текст в виртуальном элементе
  aux.select();
  // копируем выделенный текст в буфер обмена
  document.execCommand("copy");
  // дело сделано — удаляем виртуальный элемент со страницы
  document.body.removeChild(aux);
});

На нашем сервере вы можете посмотреть, как это работает.

<!DOCTYPE html>
<html>
<!-- служебная часть -->

<head>
  <!-- заголовок страницы -->
  <title>Шаблоны ответов</title>
  <!-- настраиваем служебную информацию для браузеров -->
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- задаём CSS-стили прямо здесь же, чтобы всё было в одном файле -->
  <!-- подключаем jQuery -->
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <style type="text/css">
    /*настраиваем внешний вид шаблонов*/
    div {
      font-size: 20px;
      font-family: 'Arial';
      margin: 60px;
      color: black;
    }

    /*подсвечиваем текст при наведении на него*/
    div:hover {
      color: #cf0000;
    }
  </style>
  <!-- закрываем служебную часть страницы -->
</head>
<!-- началось содержимое страницы -->

<body>
  <h1>Выберите шаблон ответа</h1>
  <!-- ниже — наши варианты  ответов, но сами шаблоны мы будем копировать из других элементов -->
  <div id="sel01_div">Здравствуйте!
    <br>
    <br>
    Спасибо за письмо — я обязательно рассмотрю его и совсем скоро дам ответ.</div>
  <div id="sel02_div">Привет!
    <br>
    <br>
    Я видел, что ты мне прислал. Отпишусь, как будет время, ага?</div>
  <div id="sel03_div">Коллеги! Спешу напомнить вам, что этот вопрос в приоритете у руководства, поэтому примите все
    возможные меры для скорейшего разрешения ситуации.
    <br>
    <br>
    Стейкхолдера по задаче прошу уделить ей особое внимание, результат нужен ASAP.</div>
  <div id="sel04_div">Добрый день!
    <br>
    <br>
    Мне понравился ваш проект, и чтобы начать над ним работать мне нужны
    <br>
    - устав
    <br>
    - договор аренды
    <br>
    - выписка ЕГРН
    <br>
    <br>
    Как пришлёте документы, я их изучу и свяжусь с вами.
  </div>
  <!-- а вот тут уже сами наши шаблоны, которые пойдут в буфер обмена  -->
  <textarea id='sel01' hidden="true">Здравствуйте!
Спасибо за письмо — я обязательно рассмотрю его и совсем скоро дам ответ.</textarea>
  <textarea id='sel02' hidden="true">Привет!
Я видел, что ты мне прислал. Отпишусь, как будет время, ага?</textarea>
  <textarea id='sel03' hidden="true">Коллеги! Спешу напомнить вам, что этот вопрос в приоритете у руководства, поэтому примите все возможные меры для скорейшего разрешения ситуации.
Стейкхолдера по задаче прошу уделить ей особое внимание, результат нужен ASAP.</textarea>
  <textarea id='sel04' hidden="true">Добрый день!
Мне понравился ваш проект, и чтобы начать над ним работать мне нужны
- устав
- договор аренды
- выписка ЕГРН
Как пришлёте документы, я их изучу и свяжусь с вами.</textarea>
  <!-- пишем скрипт, который будет копировать выбранный шаблон по клику в буфер обмена -->
  <script>
    // строковая переменная, которая нам поможет обратиться к скрытым элементам с шаблонами
    var s;
    // обработчик клика, который следит сразу за всеми нужными разделами с шаблонами
    $('#sel02_div, #sel01_div, #sel03_div, #sel04_div, #sel05_div, #sel06_div').on('click', function () {
      // получаем имя элемента, на который кликнули 
      s = this.id;
      // берём первые 5 символов, чтобы по ним обратиться к скрытым элементам
      s = s.slice(0, 5);
      // создаём временный новый элемент textarea, из которого буфер обмена заберёт текст шаблона
      var aux = document.createElement("textarea");
      // отправляем в этот элемент текст из нужного шаблона
      aux.value = document.getElementById(s).value;
      // виртуально добавляем этот элемент на страницу
      document.body.appendChild(aux);
      // выбираем весь текст в виртуальном элементе
      aux.select();
      // копируем выделенный текст в буфер обмена
      document.execCommand("copy");
      // дело сделано — удаляем виртуальный элемент со страницы
      document.body.removeChild(aux);
    });
  </script>
  <!-- закончилось содержимое страницы -->
</body>
<!-- конец всего HTML-документа -->

</html>

Что дальше

У нас уже получился рабочий проект. Какие в нём проблемы:

  • Костыльная реализация данных: сейчас блоки с текстом шаблонов вшиты в страницу и перечислены вручную. А надо, чтобы они сидели в каком-нибудь массиве и заполняли страницу автоматически.
  • Так себе дизайн, нужно думать и рисовать. Сделаем это в будущем.
  • Ограничение на 99 шаблонов. Сейчас это не проблема, но если проект будет использоваться, довольно быстро это станет проблемой.
  • Чтобы добавить свой шаблон, нужно редактировать код. А хочется, чтобы можно было добавлять прямо на странице.

Будем решать!

Обложка:

Даня Берковский

Корректор:

Ирина Михеева

Вёрстка:

Маша Климентьева

Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Вам может быть интересно
easy