Все привет!
Есть такая проблема: сделал сайт, где при переходе по ссылкам страницы подгружаются ajax-ом, и все бы ничего, но вот на одной из страниц мне нужно расположить форму... тоже ajax-овую.
А косяк заключается в том, что если перейти на страницу с формой непосредственно, то форма сабмитится нормально. Если же форма подгружена аяксом, то после сабмита страница перезагружается. Соответственно. мне непонятно, тут мой косяк или просто необходимы дополнительные пляски с бубном?
Можно посмотреть по этой ссылке: http://photoalice.16mb.com/ - листаем на раздел "вопрос-ответ", там внизу форма. При сабмите страница перезагрузится. Если же перейти непосредственно на http://photoalice.16mb.com/faq, то сабмит будет аяксовый.
Что-то тут не так...
Сейчас еще плохо соображаю... поэтому конкретно не подскажу но:
сравните список подгруженных js в том и в том случае... похоже... когда форма грузиться аяксом, нужный js не подгружен..поэтому отрабатывает стандартный сабмит..
ЗЫ..если я прав, выясните, какой js нужен, и подгружаете его на страничку, где появиться форма, заранее..
Да, так оно и есть, и костылем пофиксить это - не вопрос. Но дело в том, что сайт я делаю больше в учебных целях. чем из необходимости, поэтому меня интересует, предусмотрена ли какая-либо плюшка у друпала на этот счет?)) Если да - то какая, если нет - привет, костыли!!
Пофиксил проблему, подробное описание прилагаю ниже, чтобы другим меньше гуглить. Если мое решение - не тру-вэй, буду рад, если меня поправят (а я ищу больше не решение, а именно тру-вэй)
Итак, изначально у нас страница грузится безо всяких форм, соответственно не подключаются необходимые для корректной работы библиотеки. Пофиксить это можно включением следующего кода в шаблон:
Теперь у нас на странице есть все необходимые скрипты. Но этого мало.
Когда мы подгружаем форму аяксом, она корректно конструируется, но ей не назначаются классы, говорящие о том, что она ajax-processed. Дело в том, что это делается динамически из misc/ajax.js ,а именно вот в этом куске кода:
Drupal.behaviors.AJAX={
attach:function(context, settings){ // Load all Ajax behaviors specified in the settings. for(var base in settings.ajax){ if(!$('#'+ base +'.ajax-processed').length){ var element_settings = settings.ajax[base];
Как видно, в цикле здесь проходится массив settings.ajax и для каждого элемента этого массива биндятся соответствующие события и добавляются необходимые классы. Но в нашем-то случае у объекта settings нет элемента ajax, потому что на начальной странице нету никаких форм,так что цикла не происходит. Как это поправить? Я решил просто заполнить этот массив вручную при загрузке. Выглядит это так:
...то есть тупо переписал то что мне выдал драгонфлай в точке останова на правильной странице с формами. Конечно, этот скрипт не универсален и будь наша форма по-другому названа, он выглядел бы по-другому. Второй минус - если нам понадобится добавить ещё одну динамически подгружаемую форму, то для нее тоже придется ручками добавлять подобный яваскрипт. В общем, копипаст, быдлокодинг и деградация
Но зато работает!
(по ссылке на тестовый сайт сейчас все по-старому, экспериментировал на локалхосте)
Комментарии
вопрос то какой?
Блин!! Криво запостилось
Вопрос в том, что, как я понял из документации, вот этого куска кода доолжно быть достаточо, чтобы форма стала аяксовой:
<?php
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Send'),
'#ajax' => array(
'callback' => 'faqform_ajaxsubmit',
'wrapper' => 'submit-message',
),
);
?>
А косяк заключается в том, что если перейти на страницу с формой непосредственно, то форма сабмитится нормально. Если же форма подгружена аяксом, то после сабмита страница перезагружается. Соответственно. мне непонятно, тут мой косяк или просто необходимы дополнительные пляски с бубном?
Можно посмотреть по этой ссылке: http://photoalice.16mb.com/ - листаем на раздел "вопрос-ответ", там внизу форма. При сабмите страница перезагрузится. Если же перейти непосредственно на http://photoalice.16mb.com/faq, то сабмит будет аяксовый.
Что-то тут не так...
читайте про Drupal.attachBehaviors
Так было бы что аттачить: дело в том, что форма сделана на drupal form api, так что на js у меня ни строчки не написано про сабмит.
Сейчас еще плохо соображаю... поэтому конкретно не подскажу но:
сравните список подгруженных js в том и в том случае... похоже... когда форма грузиться аяксом, нужный js не подгружен..поэтому отрабатывает стандартный сабмит..
ЗЫ..если я прав, выясните, какой js нужен, и подгружаете его на страничку, где появиться форма, заранее..
Да, так оно и есть, и костылем пофиксить это - не вопрос. Но дело в том, что сайт я делаю больше в учебных целях. чем из необходимости, поэтому меня интересует, предусмотрена ли какая-либо плюшка у друпала на этот счет?)) Если да - то какая, если нет - привет, костыли!!
Пофиксил проблему, подробное описание прилагаю ниже, чтобы другим меньше гуглить. Если мое решение - не тру-вэй, буду рад, если меня поправят (а я ищу больше не решение, а именно тру-вэй)
Итак, изначально у нас страница грузится безо всяких форм, соответственно не подключаются необходимые для корректной работы библиотеки. Пофиксить это можно включением следующего кода в шаблон:
<?php drupal_add_library('system', 'drupal.ajax');
drupal_add_library('system', 'drupal.form');
drupal_add_library('system', 'jquery.form');
drupal_add_library('system', 'druapl.progress');
drupal_add_library('system', 'drupal.textarea');
?>
Теперь у нас на странице есть все необходимые скрипты. Но этого мало.
Когда мы подгружаем форму аяксом, она корректно конструируется, но ей не назначаются классы, говорящие о том, что она ajax-processed. Дело в том, что это делается динамически из misc/ajax.js ,а именно вот в этом куске кода:
attach: function (context, settings) {
// Load all Ajax behaviors specified in the settings.
for (var base in settings.ajax) {
if (!$('#' + base + '.ajax-processed').length) {
var element_settings = settings.ajax[base];
if (typeof element_settings.selector == 'undefined') {
element_settings.selector = '#' + base;
}
$(element_settings.selector).each(function () {
element_settings.element = this;
Drupal.ajax[base] = new Drupal.ajax(base, this, element_settings);
});
$('#' + base).addClass('ajax-processed');
}
}
Как видно, в цикле здесь проходится массив settings.ajax и для каждого элемента этого массива биндятся соответствующие события и добавляются необходимые классы. Но в нашем-то случае у объекта settings нет элемента ajax, потому что на начальной странице нету никаких форм,так что цикла не происходит. Как это поправить? Я решил просто заполнить этот массив вручную при загрузке. Выглядит это так:
$(document).ready(function(){
//--------------
//--------------
//initialisation
if(Drupal.settings.ajax == undefined){
Drupal.settings.ajax = {
'edit-submit': {
callback: "faqform_ajaxsubmit",
event: "mousedown",
keypress: true,
prevent: 'key',
submit: {
_triggering_element_name: "op",
_triggering_element_value: "Отправить"
},
url: 'system/ajax',
wrapper:'submit-message'
}
};
}
...то есть тупо переписал то что мне выдал драгонфлай в точке останова на правильной странице с формами. Конечно, этот скрипт не универсален и будь наша форма по-другому названа, он выглядел бы по-другому. Второй минус - если нам понадобится добавить ещё одну динамически подгружаемую форму, то для нее тоже придется ручками добавлять подобный яваскрипт. В общем, копипаст, быдлокодинг и деградация
Но зато работает!
(по ссылке на тестовый сайт сейчас все по-старому, экспериментировал на локалхосте)