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

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

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

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

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

Шаблон страницы

    
language: HTML
<!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> — он встав­ля­ет пере­нос на новую стро­ку.

    
language: HTML
<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». Если мы в скрип­те смо­жем отбро­сить эту часть (а мы смо­жем), то мож­но будет сде­лать все­го один обра­бот­чик на всю стра­ни­цу. А пока про­сто доба­вим эти эле­мен­ты на стра­ни­цу:

    
language: HTML
<!-- а вот тут уже сами наши шаблоны, которые пойдут в буфер обмена  -->

 

<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:

    
language: 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);

});


Ско­пи­ро­вать код
Код ско­пи­ро­ван

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

Готовый код

    
language: HTML
<!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 шаб­ло­нов. Сей­час это не про­бле­ма, но если про­ект будет исполь­зо­вать­ся, доволь­но быст­ро это ста­нет про­бле­мой.
  • Что­бы доба­вить свой шаб­лон, нуж­но редак­ти­ро­вать код. А хочет­ся, что­бы мож­но было добав­лять пря­мо на стра­ни­це.

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