php, появляющиеся select-ы (обратите внимание ВОПРОС НЕ ПО SQL!!!)

markyzz

Задача следующая:
Страничка с деревом выбора.
То есть пользователь видит выбор:
 

<form action = "index.htm" method = "post">
<SELECT name = cat>
<OPTION value = "001"> 1. человек <здесь закрывающийся Тэг, просто его не видно>
<OPTION value = "002"> 2. бобер
<OPTION value = "003"> 3. зомби
<OPTION value = "004"> 4. гриб
<OPTION value = "005"> 5. дерево
<OPTION value = "006"> 6. гора
</SELECT>
<input type = submit value = "дальше">
</form>

при нажатии на кнопочку (или даже лучше чтобы без нее - то есть просто выбрав что-то в выпадающей меню) на этой же страничке появляется еще одна выборка и тд.
в данный момент все реализовано через жопу.
запрос отправляется этому же файлу в котором и форма
в пхп-коде есть говно-условие, что бы нарисовать еще одну похожую форму , если в первой что-то ввели
страничка перегружается и в первой форме снова появляется дефолтное значение... в общем, стыдно такое говно показывать, но, все же покажу:
 
 
<?php
/*тут нет никаких SQL, вам показалось*/
$val = $_POST[cat];
if ($val != 0)
{
/*тут нет никаких SQL, вам показалось*
if ($number != 0)
{
echo "<form action = \"index.html\" method = \"post\">";
echo "<SELECT name = grp>";
while (/*какой-то цикл БЕЗ SQL*/)
{
echo "<OPTION value =".$GPNUM.">$GPNUM ".$txt; /*просто какие-то переменные - не важно откуда*/
}
echo "</SELECT>";
echo "</form>";
}
}
mysql_close; <------ МИРАЖ! Нет тут ничего
?>

ну вот как-то так.
вопрос: как все эти дела сделать не так паршиво?

alexkravchuk

==========================
$val = $_POST[cat];
.....
$query = "SELECT * FROM S WHERE C = '$val'";
==========================
1) Будем считать, что пользователи добрые и слов "SQL-инъекция" не знают :)
2) Очень не понятна логика построения таблицы в БД, как связаны столбцы C, D, G, TEXT. Конкретно, какие ограничения на D накладываются, они уникальны, или могут повторяться? Если D не уникальны, может ли быть ситуация, когда двум одинаковым D соответствуют разные G? Если так, что поведение программы может быть непредсказуемым.

Первое, что хочется, это убрать sql-запросы из цикла, свести к одному запросу. Но, для этого лучше знать больше о данных.
Второе, разделить запросы к БД и генерирование HTML, хотя это не так уже существенно, конечно.

hwh2010

$val = $_POST[cat];
....
$query = "SELECT * FROM S WHERE C = '$val'";
очень хочется отправить качестве $_POST[cat] какую-нибудь гадость, содержащую апострофы

markyzz

вопрос не по SQL-запросам, а по формированию новой формы :)
Забудем, что работа с БД!
Интересует именно процесс появления новых и новых форм на страничке и чтобы старые от этого нового появления не сбрасывались
То есть чтобы пользователь видел, что он до этого вводил
А если он передумает, то изменение в первой форме повлияло бы на все остальные. скажем, они бы исчезли или предоставили ему новый вариант выбора дальше.
вот именно этот вопрос интересует :)

0000

Посмотри jQuery, в частности реализацию Ajax.
Допустим выбирается что-то в селекте. На этом селекте вешаешь событие onchange.
В обработчике onchange получаешь, что выбрал пользователь и отправляешь запрос на сервак "в фоне" (ajax). Получаешь ответ, парсишь его, заполняешь другой селект.
Разумеется решение работает где включена поддержка Java Script.
Ajax можно и без jQuery использовать, немного сложнее. Но jQuery обычно и так используется. Или какой другой Фреймворк.
P.S. У <option> закрывающий тег Пушкин ставить будет?
P.P.S. Для отладки сайтов рекомендую использовать Firefox и поставить к нему плагин Firebug. Очень удобно, в том числе и для просмотра верстки.
Пример (возможно косяки, поскольку правил свой рабочий пример)

<script type="text/javascript" src="jquery-1.5.1.min.js"></script> // ОБЯЗАТЕЛЬНО! А то работать не будет.

<select id = "sel" name = "sel" style="width:190px" onchange="updateSelect;">
<option value="1">A1</option>
<option value="2">A2</option>
<option value="3">A3</option>
</select>

<script type="text/javascript">

function updateSelect
{
$.get("request.php?..." + $('#sel').val // Отправляем запрос на сервер. В #sel получаем, что выбрал пользователь.
function(data){
var oData = eval("(" + data + ")"); // Данные с сервера пришли в формате json (использовал json_encode(результирующий массив);)

var text = '';
for (var RowNo in oData)
text = text + '<option value = \'' + oData[RowNo].id + '\'>' + oData[RowNo].name + '</option>';
$('#sel2').html(text); // заполняем второй селект
});
}
</script>

Maurog

P.S. У <option> закрывающий тег Пушкин ставить будет?
а как же великий и могучий HTML ? :grin:

markyzz

Разумеется решение работает где включена поддержка Java Script.
Джава-скрипта нет....
Но общий смысл понял - спасибо.

PooH

лучше заведи страничку с такими техническими запросами (getdata.php?action=var&option1=var2)

PooH

блин, так не AJAX нужен?

hwh2010

тебе что ли хочется узнать об атрибует selected элемента option?
в таком случае вопрос был ваще не по sql и не по php, а по html
если будешь слушать зообастиков и делать через ajax — тогда вообще не делай перезагрузки страницы, не смешивай два стиля
проще — без js, на чистом html (а во многих случаях — и для юзера удобнее)

doublemother

если будешь слушать зообастиков и делать через ajax — тогда вообще не делай перезагрузки страницы, не смешивай два стиля
Культурные люди делают возможность перезагрузки страницы и return false в js обработчике, чтобы всё работало как у людей с js, так и у параноиков.

markyzz

ага - про selected я уже думал.. в итоге, наверное, так и буду делать...
Просто у меня изначально сомнения были - ведь с обновлением странички происходит обновление всей цепочки выборов... хотя, может я просто зря это все так... писать в лоб да и все

PooH

Интересует именно процесс появления новых и новых форм на страничке и чтобы старые от этого нового появления не сбрасывались
То есть чтобы пользователь видел, что он до этого вводил
А если он передумает, то изменение в первой форме повлияло бы на все остальные. скажем, они бы исчезли или предоставили ему новый вариант выбора дальше.
вот именно этот вопрос интересует
без использования JS получится не очень красиво:
пусть пользователь уже ввел 3 последовательных выбора (т.е. на текущем этапе он видит на страничке 4 селекта - 3 с уже выбранными параметрами и 1 с не выбранным)
при изменении выбора в первых трех надо будет перезагружать страничку
предлагаю сделать примерно так:
http://php-exe-ru.1gb.ru/lists/index.php

PooH

index.php
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html dir="ltr" lang="ru-RU">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title id='title'>list example</title>
</head>

<body>

<div style="width:800px;margin:0px auto;">
<form action="index.php" method="GET">
<?php

require_once 'db.php';

$option1 = empty($_GET['option1']) ? '' : htmlspecialchars($_GET['option1']);
$option2 = empty($_GET['option2']) ? '' : htmlspecialchars($_GET['option2']);
$option3 = empty($_GET['option3']) ? '' : htmlspecialchars($_GET['option3']);
$option4 = empty($_GET['option4']) ? '' : htmlspecialchars($_GET['option4']);
$option5 = empty($_GET['option5']) ? '' : htmlspecialchars($_GET['option5']);

$options = array ( $option1, $option2, $option3, $option4, $option5 );

$i = 0;
$start = array( '2', '2' );
$pos = $start;

foreach( $options as $option ) {

if( empty($option) ) break;

if( in_array( $option, array( 'up', 'down', 'left', 'right' ) ) ) {

$i++;

if( $pos[0] < 0 or $pos[0] > 4 or $pos[1] < 0 or $pos[1] > 4 or $db[$pos[0]][$pos[1]] != 1 ) die( 'incorrect position' );

?>

<div style="width:130px;padding:10px 10px 0px 10px;float:left;text-align:center;">
<select name="option<?php echo $i; ?>" disabled>
<?php if( $pos[0] - 1 > -1 and $db[$pos[0] - 1][$pos[1]] ) { ?> <option value="up"<?php if($option == 'up') echo ' selected="selected"'; ?>> Up &uarr; </option> <?php } ?>
<?php if( $pos[0] + 1 < 5 and $db[$pos[0] + 1][$pos[1]] ) { ?> <option value="down"<?php if($option == 'down') echo ' selected="selected"'; ?>> Down &darr; </option> <?php } ?>
<?php if( $pos[1] - 1 > -1 and $db[$pos[0]][$pos[1] - 1] ) { ?> <option value="left"<?php if($option == 'left') echo ' selected="selected"'; ?>> Left &larr; </option> <?php } ?>
<?php if( $pos[1] + 1 < 5 and $db[$pos[0]][$pos[1] + 1] ) { ?> <option value="right"<?php if($option == 'right') echo ' selected="selected"'; ?>> Right &rarr; </option> <?php } ?>
</select>
<input type="hidden" name="option<?php echo $i; ?>" value="<?php echo $option; ?>"/>
</div>

<?php

switch( $option ) {

case 'up':
$cell[$pos[0]][$pos[1]] .= '&uarr;';
$pos[0] = $pos[0] - 1;
break;
case 'down':
$cell[$pos[0]][$pos[1]] .= '&darr;';
$pos[0] = $pos[0] + 1;
break;
case 'left':
$cell[$pos[0]][$pos[1]] .= '&larr;';
$pos[1] = $pos[1] - 1;
break;
case 'right':
$cell[$pos[0]][$pos[1]] .= '&rarr;';
$pos[1] = $pos[1] + 1;
break;

}

} else {
die( 'Кривые руки detected!' );
}
}

if( $i < 5 ) {
?>

<div style="width:130px;padding:10px 10px 0px 10px;float:left;text-align:center;">
<select name="option<?php echo $i + 1; ?>">
<?php if( $pos[0] - 1 > -1 and $db[$pos[0] - 1][$pos[1]] ) { ?> <option value="up"> Up &uarr; </option> <?php } ?>
<?php if( $pos[0] + 1 < 5 and $db[$pos[0] + 1][$pos[1]] ) { ?> <option value="down"> Down &darr; </option> <?php } ?>
<?php if( $pos[1] - 1 > -1 and $db[$pos[0]][$pos[1] - 1] ) { ?> <option value="left"> Left &larr; </option> <?php } ?>
<?php if( $pos[1] + 1 < 5 and $db[$pos[0]][$pos[1] + 1] ) { ?> <option value="right"> Right &rarr; </option> <?php } ?>
</select>
</div>

<div style="width:50px;padding:10px 0px 0px 0px;float:right;text-align:center;">
<input type="submit" value="GO!"/>
</div>
<?php
} ?>
</form>

<div style="clear:both;width:100%;height:1px;"></div>

<?php
for( $j = 0; $j < $i; $j++ ) {
?>
<div style="width:130px;padding:0px 10px;float:left;text-align:center;">
<form action="index.php" type="GET">
<?php
for( $l = 0; $l < $j; $l++ ) {
?><input type="hidden" name="option<?php echo $l + 1; ?>" value="<?php echo $options[$l]; ?>"> <?php
} ?>
<input type="submit" value="change"/>
</form>
</div> <?php
} ?>

<div style="clear:both;width:100%;height:1px;padding:25px 0 0 0;border-bottom:1px solid black;"></div>

<div style="clear:both;width:125px;margin:25px auto;height:125px;border-bottom:1px solid black;border-right:1px solid black;"> <?php

for( $x = 0; $x < 5; $x++ ) {
for( $y = 0; $y < 5; $y++ ) {
?>
<div style="width:24px;height:24px;border-top:1px solid black;border-left:1px solid black;float:left;background:<?php if( $pos[0] == $x and $pos[1] == $y ) { ?>green<?php } else { if( $db[$x][$y] ) { ?>transparent<?php } else { ?>red<?php } } ?>;text-align:center;vertical-align:middle;">
<span style="font-size:10px;"><?php echo $cell[$x][$y]; ?></span>
</div>
<?php
}
} ?>

</div>
</div>
</body>
</html>

db.php
 
<?php

$db = array (
array( 1, 1, 1, 0, 1
array( 1, 0, 1, 1, 0
array( 1, 1, 1, 1, 1
array( 0, 1, 0, 0, 0
array( 1, 1, 1, 0, 1 )
)

?>

PooH

основная идея: запись предыдущих шагов в hidden inputs, для изменения параметров на предыдущем шаге - отдельные формы с hidden inputs

PooH

если будешь слушать зообастиков и делать через ajax — тогда вообще не делай перезагрузки страницы, не смешивай два стиля
проще — без js, на чистом html (а во многих случаях — и для юзера удобнее)
только надо юзеру дать понять, что изменение "верхнего" списка изменит все "нижние" списки
проще заблокировать изменение всех списков, кроме самого нижнего, но при этом оставить ссылку на изменение верхних списков:
list1(disabled) (link to change) -> list2(disabled) (link to change) -> list3(disabled) (link to change) -> list4

PooH

проще — без js, на чистом html (а во многих случаях — и для юзера удобнее)
ну тут можно поспорить - без js - это надо таскать за собой всю цепочку выборов, вставлять скрытые инпуты и перезагружать страничку по сто раз
с js все получается логичнее и красивее

hwh2010

ну может
я в каком-то далёком году писал ровно такую хрень — даёшь программе многомерный массив такой, а она реализует дерево выбора с помощью select-ов
не так и сложно

markyzz

Спасибо огромное! Бум разбираться :)
Оставить комментарий
Имя или ник:
Комментарий: