Javascript и Drupal
Прислано: Khurgin
пн, 21/07/2008 - 13:33
Я новичок в drupal, но по этому вопросу облазил всё что мог.
Может быть вы сможете мне подсказать, буду очень благодарен.
Ситуация:
Пишу модуль к drupal 6. Drupal стоит поверх денвера. Модуль выводит на страницу в блок content html код.
Вывод находится в функции: function mymodule_block($op='list', $delta=0).
В ней генерится html код, записывается в переменную $block_content и выдается через
$block['content'] = $block_content;
return $block;
Пока я не начал использовать javascript всё выводилось нормально.
Потом я решил добавить в выод таблицу с прокруткой, для чего применил javascript.
Отдельно от друпала скрипт рабоает.
Но в друпале нет.
Часть скрипта, что пишется в я смог добавить в на свою страницу, где используется с помощью
drupal_add_js("myGrid.js");
Но вот вызов javascript функции из сделать не получается. Drupal просто игнорирует тег и вместо вызова функции, которая должна выводить таблицу - просто пишет "0".
Более того, если этот скрипт вызова просто добавить на страницу через админку, то выпадает ошибка
Parse error: syntax error, unexpected '<' in Z:\home\drupal\www\includes\common.inc(1537) : eval()'d code on line 2
Скрипт вызова функции:
var currencies = ["ARS","ATS","AUD","BBD","BEF","BGL","BMD","BRL","BSD","CAD",
"CHF","CLP","CNY","CYP","CZK","DEM","DKK","DZD","EGP","ESP",
"EUR","FIM","FJD","FRF","GBP","GRD","HKD","HUF","IDR","IEP",
"ILS","INR","ISK","ITL","JMD","JOD","JPY","KRW","LBP","LUF",
"MXN","MYR","NLG","NOK","NZD","PHP","PKR","PLN","PTE","ROL",
"RUR","SAR","SDD","SEK","SGD","SKK","THB","TRL","TTD","TWD",
"USD","VEB","XAG","XAU","XCD","XDR","XPD","XPT","ZAR","ZMK"];
var data =
{
nCol:6,
nRow:10,
nCellWidth:70,
nCellHeight:20
};
data.colHeaders = currencies;
data.rowHeaders = currencies;
data.values = new Array();
for ( var i = 0; i < currencies.length; i++ )
{
data.values.push(new Array());
for ( var j = 0; j < currencies.length; j++ )
{
if ( i == j )
data.values[i].push('-');
else
data.values[i].push(Math.round(10000*Math.random() / Math.random())/10000);
}
}
new Grid('theGrid', data);
В админке друпала для страницы, где находится мой модуль я выбрал Input format "PHP code".
Вопрос:
Подскажите пожалуйста в чём может быть проблема и как вообще правильно работать с javascript при написании модулей.
- Khurgin's blog
- Для комментирования войдите или зарегистрируйтесь
http://api.drupal.ru/api/function/drupal_add_js/6
- Для комментирования войдите или зарегистрируйтесь
Да, я пытался использовать эту функцию, но у меня не получилось. Буду очень признателен более развернутому ответу и примерам применения.
- Для комментирования войдите или зарегистрируйтесь
проводили аналогии с другими модулями, использующими свои js?
- Для комментирования войдите или зарегистрируйтесь
Что ты как то путанно описал. Но насколько я понял, у тебя есть скрипт, который написан в отдельном файле. Однако Jquery ты не пользуешься, и функцию вызова прописываешь прямо в HTML коде. Тогда ты должен использовать ‘inline’ в вызове. Вот так:
drupal_add_js( 'moy_funcia()','inline');
Ну или даже весь скрипт, что ты привел:
drupal_add_js('var currencies = ["ARS","ATS","AUD","BBD","BEF","BGL","BMD","BRL","BSD","CAD", "CHF","CLP","CNY","CYP","CZK","DEM","DKK","DZD","EGP","ESP", "EUR","FIM","FJD","FRF","GBP","GRD","HKD","HUF","IDR","IEP", "ILS","INR","ISK","ITL","JMD","JOD","JPY","KRW","LBP","LUF", "MXN","MYR","NLG","NOK","NZD","PHP","PKR","PLN","PTE","ROL", "RUR","SAR","SDD","SEK","SGD","SKK","THB","TRL","TTD","TWD", "USD","VEB","XAG","XAU","XCD","XDR","XPD","XPT","ZAR","ZMK"]; var data = { nCol:6, nRow:10, nCellWidth:70, nCellHeight:20 }; data.colHeaders = currencies; data.rowHeaders = currencies; data.values = new Array(); for ( var i = 0; i < currencies.length; i++ ) { data.values.push(new Array()); for ( var j = 0; j < currencies.length; j++ ) { if ( i == j ) data.values[i].push('-'); else data.values[i].push(Math.round(10000*Math.random() / Math.random())/10000); } } new Grid("theGrid", data); ','inline');
А вообще советую пользоваться Jquery. Не надо ни одной строчки кода в html писать. Все делается через скриптовый файл.
- Для комментирования войдите или зарегистрируйтесь
Vergilius, попробовал сделать как ты предлагал, но не смотря на параметр inline скрипт добавился просто в head ко всем остальным и вызова функции не произошло.
У меня модуль генерит html в строковой переменной $blockcontent и мне нужно добавить в неё сгенерированный javascript' ом new Grid('theGrid', data);
Как это сделать? Спасибо заранее!
- Для комментирования войдите или зарегистрируйтесь
Химический Али, среди стандартных модулей drupal похожего не нашёл. Посоветуешь что посмотреть? Спасибо!
- Для комментирования войдите или зарегистрируйтесь
А в коде страницы проверял, твой код присутствует?
- Для комментирования войдите или зарегистрируйтесь
Если нет, то в шаблоне страницы может пропущена строчка:
<?php print $scripts ?>
или вот такая:
<?php print $closure ?>
в конце странички обычно вставляют.
- Для комментирования войдите или зарегистрируйтесь
gorr, в модуле я пишу:
.......
$block_content .= ''[tbody]
[tr]
[td]';
drupal_add_js(" ... ", "inline");
$block_content .= '[/td]
.....
В получаемом коде оказывается просто:
[tr] [td][/td]
И вместо того, чтобы быть вызванным между тегами td - текст скрипта тобавляется в head ко всем остальным скриптам.
<?php print $scripts ?> в шаблоне есть
- Для комментирования войдите или зарегистрируйтесь
Уверен, что твой код работает? Проверял в тестовом файле?
Если да, то попробуй сделать так:
drupal_add_js( 'moy_funcia()','inline', ‘gridobj’);
То есть тут ты добавляешь скрипт в переменную ‘gridobj’ (лю6ое название можно). До6авлять скриптов можно сколько хочешь, они будут располагаться в том порядке, каком ты их добавлял. Скрипты не выводятся через обычный drupal_get_js (то есть в head не будет), а вызывается функцией:
drupal_get_js('gridobj');
Эту функцию нужно вставить на странице, где тебе нужно. Например, говоришь, у тебя есть строковая переменная $blockcontent. Так вот в ее определении вставь drupal_get_js(' gridobj '); там где тебе нужно:
“... $blockcontent определение….”.drupal_get_js('gridobj').”….$blockcontent определение.....”
И все таки советую пользоваться Jquery. Ведь порой javascript нужно вставлять во многих местах, и это не удобно. А с jquery все твои скрипты будут в одном файле.
- Для комментирования войдите или зарегистрируйтесь
Vergilius, спасибо огромное!!! Заработало!!!
А насчёт jquery в друпале - что посоветуешь посмотреть на эту тему?
- Для комментирования войдите или зарегистрируйтесь
Не-не, ты что. Если у тебя все вставилось, есть теги , но скрипт не выполняется, то это дело уже в твоем скрипте, а не в Drupal. Javascript – client-side язык, то есть он интерпретируется броузером пользователя, а не движком сайта.
Проверь, чтобы у тебя в хеде был файл с определениями функций, чтобы вызов функции стоял там где нужно. У тебя, например, я не вижу определения функции grid, что она вообще делает? Иногда бывает, что нужно интерпретировать скрипт только после полной загрузки страницы. Следовательно нужно использовать событие onload.
Чтобы проверить, что скрипт ра6отает вставь в свой $blockcontent следующий скрипт.
drupal_add_js( 'document.write(“SCRIPT_RABOTAET”) ','inline', ‘gridobj’);
......
“... $blockcontent определение….”. drupal_get_js(' gridobj ').”….$blockcontent определение.....”;
Если он заработает, то это лишнее доказательство ошибки в твоем скрипте, а не друпала.
- Для комментирования войдите или зарегистрируйтесь
Пока писал ответ - ты уже все решил ;)
- Для комментирования войдите или зарегистрируйтесь
Насчет jquery я посоветую:
Но это если ты знаешь английский. Наверняка есть доки на русском. Через Google посмотри. В любом случае Jquery очень советую. Сам я относительно недавно познакомился с этой библиотекой, сразу понял, что это офигенно удобно. Как CSS файл, только javascript пишется. До этого писал как и ты, прямо в HTML.
- Для комментирования войдите или зарегистрируйтесь
Vergilius, чего-то я никак не найду, как инжектить код jQuery в странички, сгенерённые Друпалом? Там же вроде нужно ещё jquery.js подключать или drupal.js... Их надо самому вставлять или есть какая-то автоматизация?
- Для комментирования войдите или зарегистрируйтесь
Если ты не менял шаблон, то у тебя и так все скрипты выводятся. Друпал собирает их по всем функциям, которые запускает. В одной функции есть код drupal_add_js(‘'misc/jquery.js'’), в другой drupal_add_js(‘misc/drupal.js’), в третьей drupal_add_js(‘misc/ajax.js’), в четвертой drupal_add_js(‘misc/textarea.js’) и так далее. Потом на страницу через функцию drupal_get_js() выводится весь массив:
Таким образом получается, что на разных страницах набор скриптов разный (так как запускаются разные функции).
И ты тоже можешь добавить свой скрипт в какой-ли6о из своих функций. Написал скрипт moy_script.js, поместил его в папку moy_sait/sites/all/misc/ , чтобы не засорять дефолтную папку /misc, иначе трудно сайт будет апгрейдить. Затем в своей функции прописал drupal_add_js(‘sites/all/misc/moy_script.js’) (без слэша перед “sites”). И если эта функция запускается перед тем как вывести какую либо страницу, то твой скрипт появится в о6щем списке. Можно вызвать по-другому. Например, в своей шабоне в head после <?php print $scripts ?> (чтобы jquery.js был ДО твоего скрипта) написать:
drupal_add_js( 'sites/all/misc/moy_script.js','visov','visov_moy_script');
drupal_get_js(‘visov_moy_script’);
Если у тебя по какой то причине в коде странице нет вызова jquery.js то можешь добавить:
drupal_add_js( 'misc/jquery.js','visov','visov_moy_script');
drupal_add_js( 'sites/all/misc/moy_script.js','visov','visov_moy_script');
drupal_get_js(‘visov_moy_script’);
Для работы тебе нужны минимум jquery.js и твой скрипт. Drupal.js , ajax.js и т.д. – это плагины, расширяющие возможности, но можно работать и без них.
Вообщем, делаешь как я сказал, в своем скрипте ‘visov_moy_script’ прописываешь что-нибудь типа:
$(document).ready(function(){ //Говорим броузеру, чтобы запускал нижний скрипт только после загрузки страницы
$("#edit-pass").click(function(){ //Говорим броузеру, что когда кликнут на объект с id "edit-pass" выполнить функцию. Значок # указывает на то, что "edit-pass" - это id объекта.
$("#edit-submit").val("HELLO!!"); // Функция добавляет в value объекта edit-submit (это id клавиши LOG IN) слово "HELLO".
});
$("#edit-name").keyup(function(){ // Говорим броузеру, что когда отпустят клавишу клавиатуры,печатая в объекте с id "edit-name", выполнить функцию.Значок # указывает на то, что "edit-name" - это id объекта.
if($("#edit-name").val()!=""){ // Если объект не пустой, то выполнить нижеследующее условие. Заметь, что когда val() без ничего, то он выводит value объекта, когда val("какой_нибудь_simvol") содержит что-нибудь в скобочках, тогда он наоборот заполняет value объекта.
$("#edit-name").css({ backgroundColor:"red", color:"white" }); // изменить css объекта
}else{
$("#edit-name").css({ backgroundColor:"white", color:"black" }); // в случае, если в edit-name ничего напечатано, то css изменяется к изначальным значениям.
}
});
$("#edit-submit").click(function(event){ // если кликнут по клавиши edit-submit (это id клавиши LOG IN), то выполнить следующую функцию
event.preventDefault(); //говорим браузеру, чтобы он не отсылал нас на другую страницу, когда мы кликнем по клавише.
$("#edit-pass-wrapper").hide(); // спрятать объект с id edit-pass-wrapper
});
}); //окончание $(document).ready(function(){
Потом заходишь на страницу не логинясь, как анонимус (чтобы окошко User login было видно) и проверяешь. Кликнешь по строке ввода password и кнопка “Log in” изменится на “HELLO”; напечатаешь что-нибудь в строке ввода username и задний фон с цветом шрифта изменится, если сотрешь, то все вернется к черно-белому; кликнешь по клавише Log in и строка ввода password исчезнет.
Вообщем вот таким образом и можно выполнять javascript 6ез вмешательства в HTML. Весь javascript в отдельном файле moy_script.
- Для комментирования войдите или зарегистрируйтесь
Vergilius, классно расписал, как по нотам, молодец!
- Для комментирования войдите или зарегистрируйтесь
jquery.js + drupal.js добавляются автоматом при первом обращении к drupal_add_js
- Для комментирования войдите или зарегистрируйтесь
Если ты добавляешь их просто, без указания scope, то да. Если ты указываешь scope они не добавятся. Я, например, стер дефолтный drupal_get_js у себя. Вместо него у меня стоит drupal_get_js через scope.
- Для комментирования войдите или зарегистрируйтесь
Спасибо, очень полезно.
На счёт русской документации, думаю нет необходимости её искать, пользуюсь переводом Google, помогает здорово.
- Для комментирования войдите или зарегистрируйтесь
Заходите на http://www.visualjquery.com -- отличная шпаргалка
- Для комментирования войдите или зарегистрируйтесь





Комментарии