Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

HTML+CSS+JavaScript

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Три взаимодействующих селекта
 
 автор: Mookapek   (06.02.2009 в 03:06)   письмо автору
 
 

Надо сделать 3 поля типа <select>, взаимодействующих следующим образом:
В первом поле выбирается город, во втором - районы города, в третьем - станции метро города. Для каждого города свои районы и станции метро.
<?<html>
<
head>
<
meta http-equiv="content-type" content="text/html; charset=win-1251">
<
script>
var 
Dis = new Array ();
Dis [0]  = 'Арбат=Царицыно'// и другие
Dis [1]  = 'Центральный=Калининский'// и другие

var Met = new Array ();
Met [0]  = 'Арбатская=Смоленская';
Met [1]  = 'Петроградская=Пионерская';

function 
change_select (x)
{
var 
obj document.forms.myForm.district;
for (var 
obj.options.length0j--) obj.options [j] = null;
for (var 
dist Dis [1].split ('='), t0dist.lengthj++)
   {
   
document.createElement ('option');
   
t.text dist [j];
   
t.value dist [j];
   
obj.options.add (t);
   }

var 
obj2 document.forms.myForm.metro;
for (var 
j2 obj2.options.lengthj2 0j2--) obj2.options [j2] = null;
for (var 
metr Met [1].split ('='), t2j2 0j2 metr.lengthj2++)
   {
   
t2 document.createElement ('option');
   
t2.text metr [j2];
   
t2.value metr [j2];
   
obj2.options.add (t2);
   }
}
</script>
</head>
<body>
<form name="myForm">
Город:
<select name="Cities" onchange="change_select (this.selectedIndex)">
<option></option>
<option>Москва</option>
<option>Петербург</option>
</select>
<br>
Район:
<select name="district">
<option></option>
</select>
<br>
Метро:
<select name="metro">
<option></option>
</select>

</form>
</body>
</html>


Вот так пробовал, но работает некорректно. Уж и не знаю, что делать.
Спасибо.

  Ответить  
 
 автор: PAT   (06.02.2009 в 15:50)   письмо автору
 
   для: Mookapek   (06.02.2009 в 03:06)
 

Что именно "некорректно работает"?

  Ответить  
 
 автор: Mookapek   (06.02.2009 в 16:52)   письмо автору
 
   для: PAT   (06.02.2009 в 15:50)
 

Например, выбираю Москву. В районе отображается Арбат, Царицыно. В метро - Арбатская, Смоленская. Всё нормально пока. Потом меняю Москву на пустой option. В районе теперь пусто, а вот в меню метро остались все те же Арбатская, Смоленская. А надо, чтобы пустому значению в графе город соответствовало пустое значение и в метро. Надеюсь, понятно объяснил.

  Ответить  
 
 автор: PAT   (06.02.2009 в 19:30)   письмо автору
 
   для: Mookapek   (06.02.2009 в 16:52)
 

Мне видится, что при пустом опшене в первом селекте два других вовсе должны быть недоступны.
Ибо незачем давать пользователю тыкать в селекты, когда выбора нет.

Поэтому предлагаю:
1) изначально установить на селекты районов и метро атрибут disabled.
2) функцию вашу дополнить следующим (выделенным жирно):
function change_select (x)
{
with (document.forms.myForm)
if (!x) {district.disabled = true; metro.disabled = true; return}
else {district.disabled = false; metro.disabled = false}


var obj = document.forms.myForm.district;
for (var j = obj.options.length; j > 0; j--) obj.options [j] = null;
if (x) for (var dist = Dis [x - 1].split ('='), t, j = 0; j < dist.length; j++)
   {
   t = document.createElement ('option');
   t.text = dist [j];
   t.value = dist [j];
   obj.options.add (t);
   }

var obj2 = document.forms.myForm.metro;
for (var j2 = obj2.options.length; j2 > 0; j2--) obj2.options [j2] = null;
if (x) for (var metr = Met [x - 1].split ('='), t2, j2 = 0; j2 < metr.length; j2++)
   {
   t2 = document.createElement ('option');
   t2.text = metr [j2];
   t2.value = metr [j2];
   obj2.options.add (t2);
   }
}


Ну и, наконец, неплохо было бы задать стилями для селектов какую-то стабильную ширину, чтобы они не "прыгали" при изменении текста опшенов:
<select style="width: 200px" name="district" disabled>
и
<select style="width: 200px" name="metro" disabled>


PS. "Дисаблирование" можете, разумеется, везде убрать (и в инпутах, и в функции первые три жирные строки). Оставьте только в функции дважды if (x)

  Ответить  
 
 автор: Mookapek   (07.02.2009 в 03:16)   письмо автору
 
   для: PAT   (06.02.2009 в 19:30)
 

Ага, if (x) помогло. Спасибо, PAT!

  Ответить  
 
 автор: Mookapek   (08.02.2009 в 20:41)   письмо автору
 
   для: PAT   (06.02.2009 в 19:30)
 

Обнаружилась еще одна проблемка.
Сценарию с тремя "селектами" передается методом POST данные, включающими в себя название города, района и станции метро. Поэтому надо, чтобы при загрузке странице эти данные устанавливались в "селекты".
Делаю так:
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=win-1251">
<script>
var Dis = new Array ();
Dis [0]  = 'Арбат=Царицыно'; // и другие
Dis [1]  = 'Центральный=Калининский'; // и другие

var Met = new Array ();
Met [0]  = 'Арбатская=Смоленская';
Met [1]  = 'Петроградская=Пионерская';

function change_select (x)
{
var obj = document.forms.myForm.district;
for (var j = obj.options.length; j > 0; j--) obj.options [j] = null;
for (var dist = Dis [x - 1].split ('='), t, j = 0; j < dist.length; j++)
   {
   t = document.createElement ('option');
   t.text = dist [j];
   t.value = dist [j];
   obj.options.add (t);
   if(t.value == "<?php echo $_POST['district']; ?>")
           {
        obj.options[j+1].selected = true;
        }

   }

var obj2 = document.forms.myForm.metro;
for (var j2 = obj2.options.length; j2 > 0; j2--) obj2.options [j2] = null;
for (var metr = Met [x - 1].split ('='), t2, j2 = 0; j2 < metr.length; j2++)
   {
   t2 = document.createElement ('option');
   t2.text = metr [j2];
   t2.value = metr [j2];
   obj2.options.add (t2);
   if(t2.value == "<?php echo $_POST['metro']; ?>")
           {
        obj2.options[j2+1].selected = true;
        }

   }
}
</script>
</head>
<body onload="change_select (document.myForm.region.selectedIndex)">
<form name="myForm">
Город:
<select name="Cities" onchange="change_select (this.selectedIndex)">
<option></option>
<option <?php if($_POST['region'] == 'Москва') echo "selected"?>>Москва</option>
<option <?php if($_POST['region'] == 'Санкт-Петербург') echo "selected"?>>Санкт-Петербург</option>
</select>
<br>
Район:
<select name="district">
<option></option>
</select>
<br>
Метро:
<select name="metro">
<option></option>
</select>

</form>
</body>
</html>


Дело в том, что при загрузке страницы с "селектами" город нормально устанавливается, а район и метро при раскрытие списков ничего не выдают. Приходится менять город, а затем снова ставить предыдущий, чтобы сработал onchange. Попытался отладить это путем установки в боди onload, но бес толку. Жирным выделил изменения.

  Ответить  
 
 автор: PAT   (08.02.2009 в 22:48)   письмо автору
 
   для: Mookapek   (08.02.2009 в 20:41)
 

Ошибки выделены жирно
<option <?php if($_POST['region'] == 'Москва') echo "selected"?>>Москва</option>
<option <?php if($_POST['region'] == 'Санкт-Петербург') echo "selected"?>>Санкт-Петербург</option>
и
... onload="change_select (document.myForm.region.selectedIndex)">
Замените на Cities.

И почему-то не вижу в функции двойного if (x).

  Ответить  
 
 автор: Mookapek   (08.02.2009 в 22:58)   письмо автору
 
   для: PAT   (08.02.2009 в 22:48)
 

А, я чуть неправильно скопировал код. У меня везде стоит "region", а не "Cities" и двойной if(x) тоже есть. Но вышеперечисленная проблема так и осталась. То есть загвоздка в чем то другом...

  Ответить  
 
 автор: PAT   (08.02.2009 в 23:02)   письмо автору
 
   для: Mookapek   (08.02.2009 в 22:58)
 

Необходимо ввести дополнительный аргумент в функцию, т.е. кроме selectedIndex в функцию надо будет передавать ещё и ВАРИАНТ ВЫЗОВА этой функции
function change_select (x, y)

При вызове через оnload передавать y=true, а при вызове из селекта - y=false.
И, соответственно, при y=true производить вашу вновь введённую проверку, а при y=false - не производить. Вот так:
if(y && t.value == "<?php echo $_POST['district']; ?>")
           {
        obj.options[j+1].selected = true;
        }
и
 if(y && t2.value == "<?php echo $_POST['metro']; ?>")
           {
        obj2.options[j2+1].selected = true;
        } 
Иначе всякий раз при последующей смене города на тот, который "пришёл" из POST-данных, будут выделяться POST-район и POST-метро, чего вам не надо.

И вообще-то - на будущее - выкладывайте здесь браузерный код (без PHP-вставок). Так легче будет определять ошибки. Ибо никто ведь, кроме вас, не знает, что там скрывается под $_POST['region'] :-)
У меня чистый HTML (где я напрямую подставил selected у Петербурга; Центральный и Петроградская в операторах if) отлично работает.

  Ответить  
 
 автор: Mookapek   (09.02.2009 в 01:59)   письмо автору
 
   для: PAT   (08.02.2009 в 23:02)
 

Иначе всякий раз при последующей смене города на тот, который "пришёл" из POST-данных, будут выделяться POST-район и POST-метро, чего вам не надо.
Вот это мне как раз и надо.
В общем дело так. Я выбираю Москву, Арбат, Арбатскую. Далее значения отсылаются скрипту-обработчику, там есть варианты: подтвердить, пересмотреть. Если я нажимаю на "пересмотреть",
то загружается страница с "селектами", и в "селектах" должны быть установлены те значения, которые я выставил ранее, т.е. Москва, Арбат, Арбатская. Вместо этого у меня выводится Москва, (пусто), (пусто). Далее я меняю Москву на Петербург, потом обратно, и в итоге отображается Москва, Арбат, Арбатская. Так вот хотелось бы обойтись без манипуляций со сменой города.

  Ответить  
 
 автор: PAT   (09.02.2009 в 02:57)   письмо автору
 
   для: Mookapek   (09.02.2009 в 01:59)
 

Вы меня не поняли.
Повторяю - предложенные мною изменения в скрипте как раз ПОЛНОСТЬЮ ОБЕСПЕЧИВАЮТ ваши требования. Выбрал клиент Москву-Арбат-Арбатскую, нажал на сабмит - скрипт по ONLOAD не только САМ сформирует селекты для Москвы, но и отметит Арбат и Арбатскую.

Если у вас это не работает, то, значит, вы где-то путаетесь с PHP-сценарием.
Потому что - ПОВТОРЯЮ - у меня при замене ваших PHP-вставок на ПРЯМЫЕ значения Москва-Арбат-Арбатская всё работает ОТЛИЧНО.


Дополнительный аргумент функции нужен для того, чтобы на странице, в которой после загрузки уже отмечены Москва-Арбат-Арбатская, при ДАЛЬНЕЙШИХ манипуляциях клиента СНОВА НЕ ВЫДЕЛЯЛИСЬ Арбат и Арбатская при выборе клиентом Москвы. Поняли или нет?

  Ответить  
 
 автор: Mookapek   (09.02.2009 в 20:37)   письмо автору
 
   для: PAT   (09.02.2009 в 02:57)
 

Мдее... видимо у меня ONLOAD не работает.

  Ответить  
 
 автор: Mookapek   (09.02.2009 в 20:47)   письмо автору
 
   для: Mookapek   (09.02.2009 в 20:37)
 

Да, теперь понял, почему не работает.
Страница у меня разделена по этапам. На первом этапе одно заполняется, на втором - другое, на третьем - третье.

<html>
<head>....</head>
<body onload="...">
<?php if($_POST['etap'] == 1)
{
?>
.....
<?php } if($_POST['etap'] == 2)
{
?>
.....
<?php } if($_POST['etap'] == 3)
{
?>
.....
<?php ?>
</body>
</html>

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

  Ответить  
 
 автор: Mookapek   (09.02.2009 в 21:06)   письмо автору
 
   для: Mookapek   (09.02.2009 в 20:47)
 

Да, собственно так и есть. Поставив три экземпляра <body></body>, по одному в каждый из этапов всё заработало.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования