Интеграция JS скрипта в Друпал 7. Часть 4

Наконец то мы добрались к реализации чего то заслуживающего внимания. В предыдущей статье мы заставили работать js скрипт тултипа в Друпал. Теперь попробуем создать реально работающий модуль.
Нашей задачей, будет создание тултипов к элементам формы создания материала article. Если в предыдущей статье механизм реализации был проще пареной репы, то реализовать наш скрипт для страницы какой либо формы будет сложнее, хотя и не намного.
Первым делом вернем все на место в файле page.tpl.php . Прикинем каким образом нужно реализовать данную задачу. Первое что нужно, это обеспечить подгрузку файлов тултипа только на нужной странице. Возможны несколько вариантов как это сделать, но мы остановимся на варианте определения ID формы создания материала article. Т.е. наш модуль будет отрабатывать только на странице с формой имеющей идентификатор article_node_form . Конечно с ИД формы стандартного типа материала все ясно, тем не менее рассмотрим как этот ИД узнать. В файле tooltips.module нашего модуля используем хук hook_form_alter  .

<?php
function tooltips_form_alter(&$form, &$form_state, $form_id){
  debug($form_id);
}
​
Этот код выведет ИД всех присутствующих на странице форм. Теперь, когда мы знаем ИД нужной нам формы, мы можем иметь доступ к любому ее элементу теперь уже используя хук hook_form_FORM_ID_alter. В том же tooltips.module пишем теперь такой код.
<?php
function tooltips_form_article_node_form_alter(&$form, &$form_state, $form_id){
debug($form); 
}
Этот код выведет нам весь массив формы. Если в 3-й строке написать так
debug($form['title']['#title']);
получим 'Title'. Как обращаться к элементам массива можно увидеть в выводе дебаггера. Пример выше отображен в выводе  
debug($form);
в виде вот такого фрагмента
  'title' => 
  array (
    '#type' => 'textfield',
    '#title' => 'Title',
    '#required' => true,
    '#default_value' => NULL,
    '#maxlength' => 255,
    '#weight' => -5,
  ),
Соответственно, значения элементов можно не только выводить, но и менять. Например, мы можем изменить данную надпись на свою.
Пишем так..
<?php
function tooltips_form_article_node_form_alter(&$form, &$form_state, $form_id){
$form['title']['#title']='Новое значение'; 
}
Было так...

Стало так...

Поскольку все материалы типа article создаются в одной форме, с одними и теми-же полями, то используя хук мы можем привязать к каждому нужному нам элементу атрибут data-tooltip и задать в нем ИД тултипа для данного поля. Привязывать тултип непосредственно к элементу было бы неправильным, так как в таком случае, тултип будет появляться при обычной работе с полем (вводе данных), раздражая пользователя и отвлекая внимание. Разумнее привязка тултипа к какому нибудь атрибуту элемента, например title, или description. Можно использовать в качестве элемента для вызова тултипа текст, или картинку, или юникодовский значок. Мы реализуем для наглядности первый и третий вариант, так как с картинками больше возни, а используемые нами способы универсальны и менее трудоемки в реализации.
Начиная создание элементов вызова тултипов, необходимо определить их внешний вид, а это сответственно требует подгрузки CSS файлов. Заодно подгрузим и JS файл. На этот раз все по правилам.
<?php
//***************************************************
function tooltips_form_article_node_form_alter(&$form, &$form_state, $form_id){
//определяем путь к модулю
$path_tool = drupal_get_path('module', 'tooltips'); 
//создаем переменную пути для css файла
$path_tool_st = $path_tool . '/css/stickytooltip.css';
//создаем переменную пути для js файла
$path_tool_js = $path_tool . '/js/stickytooltip.js';
//подгружаем css
drupal_add_css($path_tool_st);
//подгружаем js
drupal_add_js($path_tool_js);
Т.е. определяем переменную пути к модулю, переменные путей к файлам и только тогда подгружаем файлы с использованием этих переменных.
Следует упомянуть, что стилевые свойства всех элементов вызова тултипов одинаковы, поэтому они вынесены отдельным классом "tip" , который будет находиться в CSS файле нашего модуля. Вот такой класс ...
.tip{
cursor:pointer;
color:red;
font-size:10px;
box-shadow: 3px 3px 5px #818181;
}
Определяем курсор как для ссылки. Цвет красный. Размер шрифта 10рх. Ну и тень.
CSS и JS файлы подключены, теперь можно создавать элементы вызова тултипов. 
Вот такой  значок, возьмем отсюда . Чтобы знать к какому атрибуту элемента формы привязывать значок, или текст, необходимо иметь хоть небольшие познания в CSS, структуре массивов и Form API друпал. Конечно страшное словосочетание Form API не должно вызывать отчаяния. В нашем случае, достаточно знать какие атрибуты имеют элементы формы и как к ним можно обратиться.
Итак.... выводим массив формы, используя debug($form); в нашем модуле. Этот массив удобно скопировать в редактор кода, потому что такие редакторы отслеживают блоки кода, заключенные в скобки, а дебаггер выводит структуры массивов как раз в очень удобном для работы в таких редакторах виде. На картинке фрагмент массива в редакторах Notepad++ и PSPad. 
Далее дело техники.
Например выведем первый элемент вызова тултипа в виде слова HELP в описании (атрибут #description) элемента формы Title . Определяемся по какому признаку будем искать в массиве формы данный элемент. Оптимальнее по названию Title . Если поиск нечувствителен к регистру, то найдется имя массива title , если чувствителен, то элемент этого массива '#title' => 'Title', . Фрагмент кода, содержащий данный массив, мы можем видеть выше. Открыв форму мы видим, что описание элемента Title отсутствует и в самом массиве данного атрибута ( #description ) нет, но это совсем не означает что его не может быть. Можно например зайти на страницу редактирования материала и добавить это описание. Поскольку мы добавляем свой код к существующему атрибуту элемента формы, то необходимо учитывать, что данный атрибут может содержать некоторое значение, а может быть пустым, как в данном случае. Поэтому мы сначала извлекаем значение атрибута, добавляем к существующему свой код, а потом передаем данные в форму. По такому принципу мы создаем четыре элемента вызова тултипа.
//формируем элементы вызова тултипов
//title (description)
$descr=$form['title']['#description'];
$form['title']['#description']=$descr.'&nbsp;<span class="tip" data-tooltip="tip1">HELP</span>';
//tags (description)
$descr=$form['field_tags']['und']['#description'];
$form['field_tags']['und']['#description']=$descr.'&nbsp;<span class="tip" style="position:relative;top:5px;font-size:18px;border:1px solid #777;" data-tooltip="tip2">&#x267f;</span>';
//body (title)
$descr=$form['body']['und'][0]['#title'];
$form['body']['und'][0]['#title']=$descr.'&nbsp;<span class="tip" data-tooltip="tip3">HELP</span>&nbsp;';
//body teaser (title)
$descr=$form['body']['und'][0]['summary']['#title'];
$form['body']['und'][0]['summary']['#title']=$descr.'&nbsp;<span class="tip" data-tooltip="tip4">HELP</span>&nbsp;';
Первый, добавляется к описанию поля ввода названия документа. В данном случае описания нет, но если бы оно было, то наш элемент добавился бы к его окончанию.
Второй, тоже самое, только здесь описание имеется и в качестве элемента вызова тултипа использован символ юникода. В данном случае, поскольку этот элемент имеет некоторые отличия от прочих, в код добавления элемента включен элемент style, для придания некоторых дополнительных стилевых особенностей значку, потому что без таковых он бы отображался немного некорректно.
Третий, добавляется после названия элемента Body
Ну и четвертый, в каком то смысле экспериментальный, добавляется к названию поля ввода тизера и в обычном состоянии он не виден.
Файлы подгружаются, элементы вызова тултипов созданы. Теперь необходимо реализовать функционал. Для этого просто нужно создать контейнер тултипов, описать сам код тултипов и вывести его на странице.
В том же файле tooltips.module создаем открывающие теги контейнера тултипов.
$cont='<div id="mystickytooltip" class="stickytooltip"><div style="padding:5px">';
Создаем сами тултипы.
$tip1='<div id="tip1" class="atip" style="width:350px;"><b>This a title field</b>. Душа моя озарена неземной радостью, как эти чудесные весенние утра, которыми я наслаждаюсь от всего сердца. Я совсем один и блаженствую в здешнем краю, словно созданном для таких, как я.
Я так счастлив, мой друг, так упоен ощущением покоя, что искусство мое страдает от этого. Ни одного штриха не мог бы я сделать, а никогда не был таким большим художником, как в эти минуты.
</div>';
$tip2='<div id="tip2" class="atip" style="width:350px"><b>Tags field</b>. Душа моя озарена неземной радостью, как эти чудесные весенние утра, которыми я наслаждаюсь от всего сердца. Я совсем один и блаженствую в здешнем краю, словно созданном для таких, как я.
Я так счастлив, мой друг, так упоен ощущением покоя, что искусство мое страдает от этого. Ни одного штриха не мог бы я сделать, а никогда не был таким большим художником, как в эти минуты.
<br>Когда от милой моей долины поднимается пар и полдневное солнце стоит над непроницаемой чащей темного леса и лишь редкий луч проскальзывает в его святая святых, а я лежу в высокой траве у быстрого ручья и, прильнув 
</div>';
$tip3='<div id="tip3" class="atip" style="width:350px"><b>Body field</b>. Я так счастлив, мой друг, так упоен ощущением покоя, что искусство мое страдает от этого. Ни одного штриха не мог бы я сделать, а никогда не был таким большим художником, как в эти минуты.
<br>Когда от милой моей долины поднимается пар и полдневное солнце стоит над непроницаемой чащей темного леса и лишь редкий луч проскальзывает в его святая святых, а я лежу в высокой траве у быстрого ручья и, прильнув 
</div>';
$tip4='<div id="tip4" class="atip" style="width:350px"><b>Teaser field</b>. Я так счастлив, мой друг, так упоен ощущением покоя, что искусство мое страдает от этого. Ни одного штриха не мог бы я сделать, а никогда не был таким большим художником, как в эти минуты.
<br>Когда от милой моей долины поднимается пар и полдневное солнце стоит над непроницаемой чащей темного леса и лишь редкий луч проскальзывает в его святая святых, а я лежу в высокой траве у быстрого ручья и, прильнув 
</div>';
Создаем строку статуса тултипа и закрывающие теги контейнера.
$cont_end='</div><div class="stickystatus"></div></div>';
Выводим все созданное на странице формы, используя атрибут формы #suffix . Этот атрибут может иметь как сама форма, так и практически все ее элементы. В элемент #prefix помещается код, который затем выводится перед элементом и соответственно в элемент #suffix то, что после элемента.
$form['#suffix'] = $cont.$tip1.$tip2.$tip3.$tip4.$cont_end;
Далее остается только закрыть скобку функции tooltips_form_article_node_form_alter .

Ну вот собственно и все. Наш модуль работает. Никакие системные файлы не затронуты, т.е. если модуль отключить, никакого мусора после него не останется.
Работоспособность модуля проверялась в 4-х типах браузеров и в 5-ти темах оформления. Результаты стабильные.
Исходники в аттаче.

Подводя итоги этих нескольких статей, можно сказать.... модуль работает и вполне может быть использован на рабочих сайтах. Однако это еще в какой то мере, заготовка. Например можно расширить функционал модуля, задействовав его для нескольких форм создания материалов. Сделать это элементарно просто, используя структуру switch . Вообще, найдя какое нибудь эффективное программное решение (конечно же я говорю о самом скрипте, а не о нашем модуле), нужно "выдавить" из него максимум. Поэтому необходимо включить интеллект. Вот уже пришла одна идея, однако, как говорил Каневский, в своем "Следствие вели ...." : "Это уже совсем другая история".
Благодарю за внимание.
 
ВложениеРазмер
Файл tooltips.rar3.66 KB