Форум Joomla! Україна

Повна версія: Створення модуля з AJAX-кодом
Ви переглядаєте спрощену версію. Переглянути повну версію з віповідним форматуванням.
Здравствуйте!
Я новичок в WEB-программировании, но уже имею опыт создания довольно сложного (успешно работающего) модуля под Joomla-1.5, извлекающего данные из MySQL-базы и предъявляющего их пользователю в виде 2-х таблиц с объединениями подобных ячеек, иерархией, и т.д. Также переделал под себя AJAX-код, формирующий связанные динамические списки (взятый отсюда: http://htmlweb.ru/ajax/example/region.php ) - "чистый" упрощённый вариант страницы (без Joomla, оформления, и т.д.) можно глянуть здесь: http://cherry.jr1.ru/index9.php
Работает ожидаемым образом. А теперь - проблема: хочу запихнуть эти динамические списки в новый Joomla-модуль другого моего (уже Joomla-шного) сайта, только как это правильно сделать? Основную проблему вижу в том, что при формировании WEB-страницы Joomla-модуль выводится последовательным вызовом основных своих файлов - helper.php и default.php - и этот вызов при каждой загрузке страницы имеет однократный характер. А для выполнения AJAX-запросов формирования связанных динамических списков необходим циклический многократный взаимный вызов php- и javascript-кода. Отсюда и возникает вопрос: как правильно распределить, например, следующий AJAX-код между модульными файлами helper.php и default.php ?
Код:
<?php
// указываем параметры для подключения к MySQL
$host='localhost';
$database='h57447';
$user='h57447';
$pswd='hlUUs0Hi';
// подключаемся к MySQL
$dbh = mysql_connect($host, $user, $pswd) or die("Не могу соединиться с MySQL.");
mysql_select_db($database) or die("Не могу подключиться к базе.");

function sql($query) // Выполняет запрос $query к БД
    {$res=mysql_query ($query);
    if(!$res)die("Запрос:\n".$query."\n");
    return $res;}

function param($param) // Извлекает переданные WEB-странице (серверу) клиентским браузером параметры, независимо от их метода передачи, и удаляет экранирование символов, произведенное функцией addslashes()
    {$param=(isset($_GET[$param])?$_GET[$param]:(isset($_POST[$param])?$_POST[$param]:false));
    if (get_magic_quotes_gpc()) $param=stripslashes($param);
    return $param;}

if(isset($_POST['ulica']) and !isset($_POST['dom']) and !isset($_POST['kvr']))
    {echo "<option value='0'>выбрать дом</option>\n";
    $res = sql('SELECT LOWER(home) as home FROM list_xat WHERE kod_strit="'.addslashes(param('ulica')).'" group by 1');
    while($row = mysql_fetch_array($res))
        echo "<option value='" . iconv("CP1251", "UTF-8", $row['home']). "'>" . iconv("CP1251", "UTF-8", $row['home']). "</option>\n";
    die;}
elseif(isset($_POST['ulica']) and isset($_POST['dom']) and !isset($_POST['kvr']))
    {echo "<option value='0'>выбрать квартиру</option>\n";
    echo "<option value='' selected='selected'>отсутствует</option>\n";
    $res = sql('SELECT LOWER(nk) as nk FROM list_xat WHERE home="'.iconv("UTF-8", "CP1251", addslashes(param('dom'))).'" AND kod_strit="'.addslashes(param('ulica')).'" group by 1');
    while($row = mysql_fetch_array($res))
        echo "<option value='" . iconv("CP1251", "UTF-8", $row['nk']). "'>" . iconv("CP1251", "UTF-8", $row['nk']). "</option>\n";
    die;}
elseif(isset($_POST['kvr']))
    {$kvr=addslashes(param('kvr'));
   // FormZapros(); // Функция вывода данных; пока не описана, вместо неё пока:
    echo "Улица: ".addslashes(param('uln'))." <br /> Дом:  ".addslashes(param('dom'))." <br /> Квр  :  ".$kvr." <br />";
    die;}

?>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<select name="ulica" id="ulica"
    onLoad="this.focus = false;"
    onChange="ajaxLoad('dom', 'index9.php', '', 'ulica='+this.options[this.selectedIndex].value, '');
              document.getElementById('dom').disabled='';">
    <option value="0">выбрать улицу</option>
    <?php
    $res = sql('SELECT * FROM list_ul');
    while($row = mysql_fetch_array($res))
        {if($row['kod_strit']==@$ulica)
            {echo "<option value='" . $row['kod_strit'] . "' selected='selected'>" . iconv("CP1251", "UTF-8", $row['name_strit']). "</option>\n";
            $ulica=$row['kod_strit'];
            $uln=$row['name_strit'];
            }
        else
            echo "<option value='" . $row['kod_strit'] . "'>" . iconv("CP1251", "UTF-8", $row['name_strit']). "</option>\n";
        }
    ?>
</select>

<select name="dom" id="dom" <?php print(@$ulica?'':'disabled="disabled"')?>
    onChange="ajaxLoad('kvr', 'index9.php', '','dom='+this.options[this.selectedIndex].value+'&ulica='+document.getElementById('ulica').options[document.getElementById('ulica').selectedIndex].value+'&uln='+document.getElementById('ulica').options[document.getElementById('ulica').selectedIndex].text,'');
              document.getElementById('kvr').disabled='';">
    <option value="0" disabled="disabled">выбрать дом</option>
    <?php
    if(@$ulica)
        {$res = sql('SELECT LOWER(home) as home FROM list_xat WHERE kod_strit='.$ulica.' group by 1');
        while($row = mysql_fetch_array($res))
            {if($row['home']==@$dom)
                {echo "<option value='" . iconv("CP1251", "UTF-8", $row['home']). "' selected='selected'>" . iconv("CP1251", "UTF-8", $row['home']). "</option>\n";
                $dom=$row['home'];
                }
            else
                echo "<option value='" . iconv("CP1251", "UTF-8", $row['home']). "'>" . iconv("CP1251", "UTF-8", $row['home']). "</option>\n";
            }
        }
    ?>
</select>

<select name="kvr" id="kvr" <?php print(@$dom?'':'disabled="disabled"')?>
    onChange="ajaxLoad('info', 'index9.php', '','ulica='+document.getElementById('ulica').options[document.getElementById('ulica').selectedIndex].value+'&dom='+document.getElementById('dom').options[document.getElementById('dom').selectedIndex].value+'&kvr='+this.options[this.selectedIndex].value+'&uln='+document.getElementById('ulica').options[document.getElementById('ulica').selectedIndex].text,'');">
    <option value="0" disabled="disabled">выбрать квартиру</option>
    <?php
    if(@$dom)
        {$res = sql('SELECT LOWER(nk) as nk FROM list_xat WHERE home='.iconv("UTF-8", "CP1251", $dom).' and kod_strit='.$ulica.' group by 1');
        while($row = mysql_fetch_array($res))
            {if($row['nk']==@$kvr)
                {echo "<option value='" . iconv("CP1251", "UTF-8", $row['nk']). "' selected='selected'>" . iconv("CP1251", "UTF-8", $row['nk']). "</option>\n";
                $kvr=$row['nk'];}
            else
                {echo "<option value='" . iconv("CP1251", "UTF-8", $row['nk']). "'>" . iconv("CP1251", "UTF-8", $row['nk']). "</option>\n";}
            }
        }
    ?>
</select>

<div id="info"></div>

<script language=JavaScript>
    function ajaxLoad(obj,url,defMessage,post,callback)
        {var ajaxObj;
        if (defMessage) {document.getElementById(obj).innerHTML=defMessage;}
        var ajaxObj = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();                
        ajaxObj.open ((post?'POST':'GET'), url);
        if (post&&ajaxObj.setRequestHeader)
            {ajaxObj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=windows-1251;");}
        ajaxObj.onreadystatechange = ajaxCallBack(obj,ajaxObj,(callback?callback:null));
        ajaxObj.send(post);
        return false;
        }
    function updateObj(obj, data, bold, blink)
        {if (bold)
            {data=data.bold()}
        if (blink)
            {data=data.blink()}
        if (window.ActiveXObject) // код для IE
            {var obj1=eval('document.all.'+obj);
            if (obj1.tagName.toUpperCase()=='SELECT' && data.toLowerCase().indexOf("<option")>-1 && data.toLowerCase().lastIndexOf("</option>")>-1) // Если obj и data - список и опции для него, соответственно - обходим баг http://support.microsoft.com/kb/276228
                {var div1 = document.createElement('div');
                div1.innerHTML = '<select>' + data + '</select>';
                var opts = div1.firstChild.options;
                for (var i=0; i < opts.length; i++)
                    {obj1.options[i] = new Option(opts[i].text, opts[i].value); //полная замена элемента на новый
                    obj1.options[i].selected=opts[i].selected;
                    if (opts[i].defaultselected)
                        {obj1.options[i].defaultselected}
                    }
                div1.parentNode.removeChild(div1);}
            else // Если obj - не СПИСОК или data - не содержит опций для него
                {obj1.innerHTML = data;}
            }
        else // код для остальных браузеров
            {document.getElementById(obj).innerHTML = data;}
        }
    function ajaxCallBack(obj, ajaxObj, callback)
        {return function()
            {if (ajaxObj.readyState == 4)
                {if (callback)
                    {if (!callback(obj,ajaxObj))
                        {return;} }
                if (ajaxObj.status==200)
                    {updateObj(obj, ajaxObj.responseText);}
                else
                    {updateObj(obj, ajaxObj.status+' '+ajaxObj.statusText,1,1);}
                }
            }
        }
</script>
Или подскажите, где о таком согласовании можно почитать, а то я уже погуглил и пояндексил, но ничего похожего не нашёл.
Я був наваяв приклад "Як під'єднати в свій php-скрипт API Joomla! Framework" так мені набагато простіше і швидше працювати з ajax. А на сайті самої Joomla! є достатньо інформації по написанню модулів Creating a Hello World Module for Joomla 1.5 та Creating a simple module. Як вам мабуть Joomla використовує MVC архітектуру написання додатків, тобіш на рахунок що має бути і в якому файлі відповідь наступна.
  • mod_helloworld.php - стартовий файл модуля і він лише викликає функції з helper.php
    helper.php - робить виборки з БД чи займається іншою підготовкою інформації
    tmpl/default.php - повинен містити в ідеалі лише HTML та вставки потрібних даних в потрібні місця
Щиро дякую, fisk!
Щодо написання MVC-модулів я якраз ускладнень не бачу - писав же, і доволі успішно, щоправда - без застосування AJAX-технології. А ось тепер - хочу саме її застосувати, в рамках Joomla-шного модуля. Ускладнення в мене виникають саме в "нестиковці" циклічності викликів, притаманної AJAX-технологіям, та НЕциклічним принципом спрацювання самих MVC-модулів - адже такий модуль спрацювує лише один раз при кожному завантаженні WEB-сторінки, а для AJAX'у потрібно, щоб модуль спрацьовував циклічно на кожний запит без перезавантаження сторінки. Ось саме в цьому моя проблема.
Побіжно ознайомився з написаною вами статтею - здається, вона мені багато в чому може допомогти. Хоча поки що - для мене в ній не вистачає конкретного прикладу вставки туди JavaScript-коду. Можливо це через побіжність ознайомлення. Зараз займусь більш детальним вивченням та спробами застосування. Ще раз дякую вам!
І ще одне. Якщо це, звичайно, не становить комерційну таємницю - чи не можна поглянути на програмний код вашого "Ajax-модуля для Virtuemart для підбору автомобільних шин та дисків по марці автомобіля для Joomla" - здається, в ньому вже вирішені всі мої питання та ускладнення. Наскільки я зрозумів з демо-опису.
на рахунок модуля "подбору шин дисків по марці автомобіля" можеш зайти на сайт спонсора, що оплатив модуль і "пощупати" його в дії, можу ще додати, що він складається і з модуля і з компонента котрий обробляє та відображає результати пошуку.
Ще раз дякую, fisk!
Скористаюсь вашою порадою.