Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Наши скрипты > Изменение значения в списке select


Автор: Aliance 19.9.2005, 17:39
Задача: изменить значения во втором выпадающем списке, следуя выбору из первого.

Решение:
Код

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
  "http://www.w3.org/tr/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Изменение значения в поле Select (c) Aliance</title>
<script type="text/javascript">

var regiondb = new Object()
regiondb["africa"] = [{value:"1", text:"Каир"},
                      {value:"2", text:"Триполи"},
                      {value:"3", text:"Алжир"},
                      {value:"4", text:"Претория"}];
regiondb["asia"] = [{value:"1", text:"Банкок"},
                    {value:"2", text:"Дели"},
                    {value:"3", text:"Улан-Батор"},
                    {value:"4", text:"Джакарта"},
                    {value:"5", text:"Токио"}];
regiondb["australia"] = [{value:"1", text:"Мельбурн"},
                          {value:"2", text:"Сидней"}];
regiondb["europe"] = [{value:"1", text:"СПб"},
                      {value:"2", text:"Лондон"},
                      {value:"3", text:"Афины"},
                      {value:"4", text:"Барселона"},
                      {value:"5", text:"Париж"},
                      {value:"6", text:"Рим"},
                      {value:"7", text:"Москва"},
                      {value:"69", text:"Бабруйск :)"}];
regiondb["noamer"] = [{value:"1", text:"Нью-Йорк"},
                      {value:"2", text:"Вашингтон"},
                      {value:"3", text:"Лос Анджелес"},
                      {value:"4", text:"Оттава"}];
regiondb["soamer"] = [{value:"1", text:"Рио дэ Жанейро"},
                      {value:"2", text:"Лима"},
                      {value:"3", text:"Каракас"}];

function setCities(chooser) {
    var cityChooser = chooser.form.elements["city"];
    // обнуляем список
    cityChooser.options.length = 0;
    // получаем value для массива regiondb
    var choice = chooser.options[chooser.selectedIndex].value;
    var db = regiondb[choice];
    // вставляем первый элемент
    cityChooser.options[0] = new Option("Город: ", "", true, false);
    if (choice != "") {
        for (var i = 0; i < db.length; i++) {
            cityChooser.options[i + 1] = new Option(db[i].text, db[i].value);
        }
    }
}

</script>
</head>
<body>
<form name="dealers" action="">
<select name="continent" onchange="setCities(this)">
    <option value="" selected>Континент: </option>
    <option value="africa">Африка</option>
    <option value="asia">Азия</option>
    <option value="australia">Австралия</option>
    <option value="europe">Европа</option>
    <option value="noamer">С. Америка</option>
    <option value="soamer">Ю. Америка</option>
</select>&nbsp;
<select name="city">
    <option value="" selected>Город: </option>
</select>
</form>
</body>
</html>


Обсуждение:
Имеем 2 элемента select, предоставляющий объекты HTMLSelectElement.
По событию onchange вызываем функцию setCities(), принимающую аргумент chooser, являющийся ссылкой на этот самый объект HTMLSelectElement первого элемента select (this).
Далее читаем выбранное значение:
Код

var choice = chooser.options[chooser.selectedIndex].value;

Далее вставляем первый неизменный дочерний элемент option:
Код

cityChooser.options[0] = new Option("Город: ", "", true, false);


А далее из массива regiondb["выбранный_континент"] читаем значение, в виде объекта с 2 полями - value и text, и соответственно в цикле for их подставляем.

Все.

Автор: Sardar 21.9.2005, 00:31
Очень хорошо. Следующим шагом будет неограниченное количество цепочек, а не два селекта. Также динамическая подзагрузка XML с данными конкретной цепочки, а не цельный массив.

В целом классно smile



Автор: Tangash 29.10.2006, 12:09
А как теперь выбранные РЕГИОН и ГОРОД передать в PHP???

Автор: 12345c 30.10.2006, 19:00
Нажать на кнопку "Отправить" формы.
(???)

Автор: tolik777 21.12.2006, 10:37
Цитата

Очень хорошо. Следующим шагом будет неограниченное количество цепочек, а не два селекта. Также динамическая подзагрузка XML с данными конкретной цепочки, а не цельный массив.


А этот шаг уже есть? А то встала такая вот задача, а как реализовать не пойму

Автор: Aliance 24.12.2006, 02:14
Какой именно шаг: два селекта или XML?

Автор: KonstRuctor 13.12.2007, 02:32
Цитата(Aliance @  19.9.2005,  17:39 Найти цитируемый пост)
Имеем 2 элемента select, предоставляющий объекты HTMLSelectElement.
По событию onchange вызываем функцию setCities(), принимающую аргумент chooser, являющийся ссылкой на этот самый объект HTMLSelectElement первого элемента select (this).

Возник вопрос. Когда мы вставляем в базу новую запись, все понятно.
Но когда мы редактируем уже имеющуюся запись, мы читаем из базы данных значения и показываем их на экран админу, чтобы он мог их изменить (или оставить так). 
Как показать существующее значение в первом селекте -- понятно. Допустим, это Азия.
Код

<select name="continent" onchange="setCities(this)">
    <option value="">Континент: </option>
    <option value="africa">Африка</option>
    <option value="asia" <?php if($name =="asia") echo" selected";?>>Азия</option>
    <option value="australia">Австралия</option>
    <option value="europe">Европа</option>
    <option value="noamer">С. Америка</option>
    <option value="soamer">Ю. Америка</option>
</select>&nbsp;

Как сделать так, чтобы сразу экране показывался готовый выбор второго селекта?
И с подсвеченным значением "Улан-Батор"?
И при этом сохранить функциональность работы двух селектов.
Спасибо.

Автор: bars80080 13.12.2007, 11:34
если выбираются значения по-умолчанию в пхп, то в пхп, это и можно сделать, просто во второй селект слить список азиатских значений и также выбрать пункт по-умолчанию по тому же принципу:
Код

$name_sel1 = 'asia'; $name_sel2 = 'улан-батор';
if($name_sel1 == 'asia') $mv = array('бангкок','улан-батор','пекин');
echo '<select name="">';
for($i = 0; isset($mv[$i]); $i++) {
if($mv[$i] == $name_sel2) $sel = 'selected'; else $sel = '';
echo '<option '.$sel.'>'.$mv[$i].'</option>';
}
echo '</select>';


Автор: KonstRuctor 14.12.2007, 03:33
Цитата(bars80080 @  13.12.2007,  11:34 Найти цитируемый пост)
если выбираются значения по-умолчанию в пхп, то в пхп, это и можно сделать, просто во второй селект слить список азиатских значений и также выбрать пункт по-умолчанию по тому же принципу:

Я не совсем то имел в виду. Таким образом, действительно, удобно получить выделенное значение селекта.
Однако я пытаюсь сделать нечто другое.
Вот смотрите, рассмотрим данный пример с континентами и городами.
У меня большая форма ввода данных, и кроме этих двух связанных селектов есть еще несколько обычных полей ввода информации: <input type="text">.
Если я добавляю новую запись, все понятно. Просто заполняю форму и отсылаю данные на сервер --  у меня связанные селекты работают изумительно.
НО!
если я хочу отредактировать имеющуюся запись, мне на экран показываются все данные об этой записи, то есть все поля ввода <input type="text"> заполнены данными, которые я хочу редактировать, прочитанными из базы.
Так вот, и эти два связанных селекта должны быть в "заполненном" положении, то есть в первом должен быть выбран континент, во втором - город.
* * *
Это очень принципиально, так как иначе редактирование записи сделать невозможно, или надо его производить в два этапа. Предположим, админ захотел поменять континент, он его поменял, потом в новом окне ему уже предлагают поменять город для вновь выбранного континента.... Иначе нарушается логика связей между двумя селектами.
* * *
ВОПРОС. Кто знает, как реализовать даную функцию для данного примера?
Спасибо.

Автор: bars80080 14.12.2007, 10:32
всё равно не вижу проблем, либо просто не понял

имхо: всё чем оперирует js уже есть в браузере

допустим мы формируем два селекта, по выбору в первом у нас обновляется список значений во втором,
стало быть данные для этих селектов уже были выбраны со всей бд и они находятся на клиентской стороне,
то есть данные для второго селекта составляют список всех возможных городов мира, а мы просто сужаем поиск выбирая континент
собственно я уже делал это здесь http://turne-trans.ru/service/hotelsearch/

если мы хотим, чтобы при выборе второго селект заполнялись все элементы text в форме, то:
1. либо нам нужно, чтобы вся бд уже присутствовала здесь, но для большой бд это загнёт трафик
2. либо при выборе второго селект у нас происходил запрос на сервер и он выдавал страницу с заполненными полями,
что собственно все и делают

в этом случае не видно совершенно никакой проблемы, просто нужно грамотно написать вставку значений по умолчанию

Автор: KonstRuctor 14.12.2007, 12:10
Цитата(bars80080 @  14.12.2007,  10:32 Найти цитируемый пост)
в этом случае не видно совершенно никакой проблемы, просто нужно грамотно написать вставку значений по умолчанию

Мне не понятно, как сделать так, чтобы при редактировании записи второй селект также был заполнен, при этом функциональность двух связанных селктов была бы сохранена.
Дело в том, что фунция по событию onchange срабатывает, а при загрузке значений из базы, видимо, не срабатывает.
* * *
То есть при загрузке из базы для редактирования первый селект у меня выбран верно, а во втором красуется одинокое "Выберите город" и под ним пусто. Если поменять континент на какой-то другой, функциональность работы двух селектов восстанавливается, но идея безопасного редактирования теряется, так как администратор уже забыл, какие ДОЛЖНЫ быть значения изначально.
* * *
Поэтому я хочу сделать так, чтобы при редактировании записи администратор ВИДЕЛ на экране два связанных селекта с высвеченными на них значениями.
* * *
Не знаю, какими еще словами мне описать проблему.
Я нашел "тупое" решение: выводить все данные о записи в полях формы, а данные, которые надо было бы выводить в селектах, показывать просто текстом и рядом ссылку "редактировать континенты/страны". И попадать в другое окно, где уже редактируем с чистого листа, потом возврат к основной форме, где уже будут указаны новые, только что отредактированные значения.
Вот только так выходит.

Автор: bars80080 14.12.2007, 14:41
решение проблемы всегда есть

посмотрите пожалуйста на эту страницу http://turne-trans.ru/motortrans/transfer/
там находится форма заказа, на которой сопряжены между собой пять селектов
город, откуда, куда, вокзал и аэропорт
изменяя город, мы изменяем и список вокзалов и аэропортов

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

принцип тот же: сохранить функциональность и выставить введённые ранее значения

если вас это устроит (если я правильно понял что вы хотите), могу выложить код, уверен разберётесь

Автор: KonstRuctor 14.12.2007, 19:11
Воистину, оно! Действительно, все работает как вы говорите.
У меня задача гораздо проще: увязать три таблицы:

Страна: country_id, country_name

Город: city_id, country_id, city_name

Товар: tovar_id, country_id, city_id, tovar_name

Предположим, все таблицы заполнены данными.
Далее я хочу редактировать товар, имеющийся в базе.
На экране вижу:

Наименование товара: tovar_name

и два связанных селекта, в одном из них показан список стран с активной country_id, в другом -- список городов для этой страны с активным городом city_id. При этом админ легко может щелкать любую другую страну, город и т.д., то есть связанность селектов сохранятся.
* * *
Что я умею делать? Я умею выводить список стран с активной страной данного товара, рядом у меня выводится пустой список городов с предложением выбрать город.
* * *
Сегодня часов 5 искал решение по разным форумам. Ничего не нашел.
Если вам не жалко показать ваш код, буду очень благодарен. Попробую разобраться, хотя у вас там все гораздо сложнее!
Можно мне на почту -- как вам удобнее.

Автор: KonstRuctor 16.12.2007, 04:46
Я нашел решение проблемы. Решается с помощью библиотек jQuery 1.2.1 или prototype.js.
В head вставляется
Код

        <script src="jquery.js" type="text/javascript"></script>
        <script type="text/javascript">
          $(function(){
             $('#firstlist select').change(function(){
                $.post('sublist.php',{first: $(this).val()},function(data){
                   $('#sublist').html(data);
                });
             });
          });
         </script>

И далее
Код

  <span id="firstlist">
    <select name="first" onchange="getSecond(this.value);">
      <option value="1">Names starting with A</option>
..... // здесь лгко можно вынуть данные из базы, проблем нет
      <option value="5">Names starting with E</option>
    </select>
  </span>
  <span id="sublist"><?php include 'sublist.php'; ?></span>

А вся работа с базой данных происходит в файле sublist.php
Код

<?php
// Здесь также легко вынимаются данные из базы
$sublist=array(1=>array('Anna','Andrew','Andrea','Annakin'),
.......
               5=>array('Edmund','Edgar','Elisabeth','Eugene','Emma','Emily'));
$value=1;
if (!empty($_POST['first'])) {
    if (isset($sublist[$_POST['first']])) $value=$_POST['first'];
}
$name_list='';
foreach ($sublist[$value] as $name) {
    $name_list.="<option value=\"{$name}\">{$name}</option>\n";
}
echo '<select name="second">'.$name_list.'</select>';
?>

В принципе я заставил это все работать как мне надо.
НО! У меня во втором связанном селекте появляются квадратики вместо русских букв.
Никак не могу понять, откуда это хрень вылезает и как ее побороть.
Никто не сталкивался с этим?

Автор: bars80080 17.12.2007, 12:04
сорри, меня по выходным не бывает
код следующий:
http://interes.uzelok.net/files/transf.rar
здесь не выкладываю, потому как русский текст в кракозябры превращается,
кстати, как этого избежать?, всё время забываю спросить

извиняюсь за код, тяжеловесен, пришлось перемалывать предыдущую структуру, написанную не мной
понятное дело это только кусок, но весь js там

что касается
Цитата
НО! У меня во втором связанном селекте появляются квадратики вместо русских букв

на лицо проблемы с кодировкой,
товарищи здесь говорят о том, что js работает в utf, а вывод вы навеняка планировали в cp-1251,
но это уже другой вопрос и на эту тему вам могут ответить более компетентные люди

Автор: CTAzz 18.12.2007, 23:53
А как вывернуть значения второго селекта из мискула?
Код

regiondb["africa"] = [{value:"1", text:"Каир"},
                      {value:"2", text:"Триполи"},
                      {value:"3", text:"Алжир"},
                      {value:"4", text:"Претория"}];


Автор: KonstRuctor 19.12.2007, 00:38
Вот мой код. Может, он и не совсем красивый, но работает.
Код

       <script type="text/javascript">
       var regiondb = new Object()
       <?
          $res1 = $sql->query( "SELECT * FROM table1" );
          while ( $row = mysql_fetch_array($res1) )
          {
              echo "regiondb[\"". $row["catid"] ."\"] = [";

                    $res3 = $sql->query("SELECT * FROM table2 WHERE catid = '". $row["catid"] ."'");
                    $num_results = mysql_num_rows($res3);
                    for ( $i=0; $i < $num_results; $i++ )
                    {
                        $kow = mysql_fetch_array($res3);
                        echo "{value:\"". $kow["chapter_id"] ."\", text:\"". $kow["chapter"] ."\"}";
                        if ( $i != ( $num_results - 1) ) echo ",";
                    }

              echo "];\n";
          }

       ?>

       function setCities(chooser) {
           var cityChooser = chooser.form.elements["city"];
           // обнуляем список
           cityChooser.options.length = 0;
           // получаем value для массива regiondb
           var choice = chooser.options[chooser.selectedIndex].value;
           var db = regiondb[choice];
           // вставляем первый элемент
           cityChooser.options[0] = new Option("Выберите раздел: ", "", true, false);
           if (choice != "") {
               for (var i = 0; i < db.length; i++) {
                   cityChooser.options[i + 1] = new Option(db[i].text, db[i].value);
               }
           }
       }
       </script>

У меня небольшая путаница с названиями переменных, надеюсь, разберетесь что к чему

Автор: CTAzz 19.12.2007, 12:49
Что-то у меня не хочет показывать значения, страница становится пустой.
Вот так переделал 
Код

<?php
include "connect.php";
?>
<script type="text/javascript">
var regiondb = new Object()
<?
          $res1 = $sql->query( "SELECT * FROM marks" );
          while ( $row = mysql_fetch_array($res1) )
          {
              echo "regiondb[\"". $row["id"] ."\"] = [";

                    $res3 = $sql->query("SELECT * FROM models_acura");
                    $num_results = mysql_num_rows($res3);
                    for ( $i=0; $i < $num_results; $i++ )
                    {
                        $kow = mysql_fetch_array($res3);
                        echo "{value:\"". $kow["id"] ."\", text:\"". $kow["model"] ."\"}";
                        if ( $i != ( $num_results - 1) ) echo ",";
                    }

              echo "];\n";
          }

       ?>

Поясню. В таблице marks находятся поля id, name( хранит значения первого списка), tablemodel( хранит значения таблицы, в котором лежит список 2, на примере models_acura, в поле хранится значение acura)
В таблице models_acura 2 поля id, model( хранит значения второго списка 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)