2015-06-26 8 views
0

Я пытаюсь реализовать каскадные выпадающие меню в веб-приложении для каталогов. Цель состоит в том, чтобы выбрать таблицу базы данных в первом меню и отобразить столбцы в этой таблице во втором меню. Моя стратегия заключается в использовании JQuery с PHP-скриптом-помощником для запуска запроса к базе данных.JQuery каскадные выпадающие списки с php и катализатором

Jquery код:

$("#db_table").change(function() { 
    console.log("dbtable changed"); 
    $("#db_field").load("[% c.uri_for('/field_get.php')%]?choice=" + $("#db_table").val()); 
}); 

PHP:

<?php 
    $username = "webuser"; 
    $password = "webuser"; 
    $hostname = "localhost"; 

    $dbhandle = mysql_connect($hostname, $username, $password) or die("Unable to connect to MySQL"); 
    $selected = mysql_select_db("mousesom", $dbhandle) or die("Could not load database"); 
    $choice = mysql_real_escape_string($_GET['choice']); 

    $query = "SELECT column_name FROM information_schema.columns WHERE table_name = '$choice';"; 

    $result = mysql_query($query); 

    while ($row = mysql_fetch_array($result)) { 
     echo "<option>" . $row{'dd_val'} . "</option>"; 
    } 
?> 

HTML:

Table:<select id="db_table"> 
    <option selected value="base">Choose a Table</option> 
    <option value="neurons">Neurons</option> 
    <option value="peaks_factors">Transcription Factors</option> 
    <option value="peaks">Peaks</option> 
    <option value="peaks_selection">Selection</option> 
    <option value="peaks_histmods">Histone Modification</option> 
</select> 
Field:<select id="db_field"> 
    <option value="Placeholder">Please Select a Table</option> 
</select> 

Я до сих пор проверить, что Javascript запрос стрельбы, но я не получаю ожидаемый ответ. На основании вывода журнала из тестового сервера Catalyst, кажется, скорее всего, необходимые аргументы не передаются в PHP скрипт хелперов, а не отщепившийся в параметры запроса с помощью катализатора вместо ...

[info] *** Request 8 (0.013/s) [17122] [Fri Jun 26 19:22:50 2015] *** 
[debug] Path is "/" 
[debug] Arguments are "field_get.php" 
[debug] "GET" request for "field_get.php" from "10.21.136.40" 
[debug] Query Parameters are: 
.-------------------------------------+--------------------------------------. 
| Parameter       | Value        | 
+-------------------------------------+--------------------------------------+ 
| choice        | peaks_histmods      | 
'-------------------------------------+--------------------------------------' 

Очевидно, что это не то, что я хочу, и мне интересно, имеет ли Catalyst другой способ передать эти параметры в вспомогательный скрипт или какой-нибудь другой способ обхода проблемы. Я искал различные документы и до сих пор пришел с пустыми руками. Любая помощь будет оценена!

ответ

1

Ваш запрос обрабатывается так, как будто это действие Catalyst, потому что вы говорите ему, когда используете код шаблона [% c.uri_for() %]. Если вы собираетесь вызвать PHP-скрипт, он должен находиться за пределами пространства имен Catalyst URI, возможно, поставив его среди ваших ресурсов root/static или где-нибудь еще ваш веб-сервер ожидает найти ресурсы PHP.

Сказав это, я не понимаю, зачем вы вводите PHP в этот микс. Контроллер Catalyst, который возвращает список имен столбцов, должен быть тривиальным для реализации. Следующий непроверенный код предполагает, что у вас есть дескриптор базы данных, доступный в вашем приложении Catalyst под названием $dbh. Какой бы ни был слой абстракции БД (DBIC?), Есть простой способ получить это. Вы также можете выбрать для этого правильный код модели.

sub get_fields :Args(1) { 
    my ($self, $c, $table) = @_; 
    my $qry = "SELECT column_name FROM information_schema.columns WHERE table_name = ?"; 
       # we'll have none of that nasty SQL injection-vulnerable code here... 
    my $result = ""; 
    my @res = $dbh->selectall_arrayref($qry, { Slice=>{} }, $table); 
    map { $result .= sprintf("<option>%s</option>", $_->{column_name} } @res; 
    $c->res->body($result); 
} 

Я буду первым, чтобы указать на то, что этот подход не является лучшей практикой, но это может дать вам некоторые идеи о том, как это должно быть сделано. (Подсказка: лучшей практикой было бы вернуть имена столбцов в виде JSON и обрабатывать теги <option> в jQuery, вместо того, чтобы создавать фрагмент HTML в вашем действии Catalyst. Поскольку вы можете найти метод, который принимает имя таблицы и возвращает ее столбцы может быть обобщенно полезным.)


Update

Вы можете использовать Catalyst :: View :: JSON, и помещая список столбцов в $c->stash->{json}, он будет делать правильные вещи, даже если это излишний случай для прецедента. Вы также можете просто конвертировать в JSON и вернуть его в $c->res->body(): если это не пусто, вся обработка шаблона обойдена. Так что вам нужно может быть столь же просто, как:

use JSON; 

sub get_fields :Args(1) { 
    my ($self, $c, $table) = @_; 
    my @rows = $c->model('InformationSchema')->result_set('Columns')->search({table_name => $table}); 
    my $columnlist = [ map { $_->column_name } @rows ]; 
    $c->res->body(to_json($columnlist)); 
} 

... но немного больше проверки ошибок не было бы плохо.

Доступ из JQuery сводится к тому, что-то вроде (опять же, непроверенные):

$("#db_table").change(function() { 
    $.ajax({ 
     type: "GET", 
     url: "[% c.uri_for('/__your_module__/get_fields/') %]" + $("#db_table").val(), 
     success: function(json){ 
      $.each(json, function(i, val) { 
       $('#db_field').append($('<option>').text(val).attr('value', val)); 
      }); 
     } 
    }); 
}); 
+0

Это имеет смысл. Я довольно просто использовал этот подход, потому что я новичок в этом, и это первый способ, которым я столкнулся в поиске способа его реализации. Решение, которое вы предлагаете, кажется намного лучше, и я попробую его попробовать. Чтобы быть уверенным, что я на правильном пути, чтобы использовать подход JSON, мне нужно будет написать код модели для выполнения запроса БД, а затем вернуть результат как JSON и сохранить его в stash? Мне нужен Catalyst :: View :: JSON для этого? Как получить доступ к JSON в stash из jquery? Извините за вопросы новичков - опять же, я очень новичок в этом! – user3396385

+0

Я думал, что отправил комментарий, чтобы предупредить вас, что я обновил свой ответ, но, очевидно, нет. В любом случае, см. Мой обновленный ответ ... – RET

+0

Спасибо за обновление! Я видел ваш ответ, но не был в течение большей части прошлой недели, и я просто возвращаюсь к этому проекту. До сих пор я работал с html-фрагментами, и я думаю, что довольно просто изменить его для работы с выходом JSON на основе информации, которую вы указали выше. Не могу поблагодарить вас за вашу помощь! – user3396385