Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Динамический список не динамический. (https://javascript.ru/forum/dom-window/56008-dinamicheskijj-spisok-ne-dinamicheskijj.html)

oneplus 25.05.2015 13:51

Динамический список не динамический.
 
Доброго дня, друзья!
Делаю простенький калькулятор, точнее не могу сделать:) В JS новенький, не могу разобраться в чем дело:
Краткое пояснение:
При выборе "Пластиковый "Квадро"" в первом списке, должен пропадать "Транслюцентный баннер" во втором списке.
Отдельно "document.light_box.surface.options[2]=null;" - удаляется, а вот вместе с "if", что бы задать условие не работает.
<body>
<table width="600" align="center" class="light_box">
<colgroup><col width="210"><col width="390"></colgroup>
<tbody>
<form name="light_box">
<tr><td class="left">Профиль:</td>
<td><select id="profile" name="profile">
      <option selected="selected">Металлический</option>
      <option>Пластиковый "Квадро"</option>
      </select></td></tr>  
<tr><td align="left">Лицевая поверхность:</td>
<td><select name="surface">
      <option selected="selected">Акрил молочный (пленки)</option>
      <option>Акрил молочный (полноцветная печать)</option>
      <option>Транслюцентный баннер</option>
      <option>Сотовый поликорбанат (пленки)</option>
      <option>Сотовый поликорбанат (полноцветная печать)</option>
      </select></td></tr>
</form>
</tbody>
</body>


if (document.light_box.profile.options.selected==1) {
document.light_box.surface.options[2]=null;
}


Перепробовал и другие варианты, ничего не получается:
var objPro=document.light_box.profile;
var objSel=document.light_box.surface;
if (objPro.selectedIndex==objPro.options[1]) {
objSel.options[2]=null;
}


if (document.light_box.profile.options[1].selected==true) {
  document.light_box.surface.options[2]=null;
}


Друзья, если не затруднит подсказать правильный вариант или "где копать" пожалуйста ответьте. Заранее спасибо.

Продолжаю экспериментировать:
var objPro = document.getElementById("profile_id");
var objSel = document.getElementById("surface_id");
if (objPro.selectedIndex == 1) {
  objSel.options[2]=null;  
}

не работает.

ksa 25.05.2015 15:54

Цитата:

Сообщение от oneplus
подсказать правильный вариант или "где копать"

Как вариант, сделать зависимую структуру из массивов и объектов... На основе этого создавать содержимое второго "зависимого" селекта...

oneplus 25.05.2015 23:54

Дополнение к первому посту
 
Спасибо, попробую разобраться с массивами и объектами. Если не трудно буду благодарен за похожие примеры, поскольку плохо представляю нужные массивы и объекты. Второй день гуглю, не могу найти ответа.:help:
В дополнение к первому посту:
Заметил следующее, код
var objPro = document.getElementById("profile_id");
var objSel = document.getElementById("surface_id");
if (objPro.selectedIndex == 1) {
objSel.options[2]=null; 
}

работает (на мой взгляд), но значения проверяет при старте страницы, то есть objPro.selectedIndex изначально [0], при последующем выборе уже условие "if" не проверяется.
Как заставить скрипт работать при каждом выборе?
Экспериментировал с "onchange",
<td><select id="profile" name="profile" onchange="this.options[this.selectedIndex]">
      <option selected="selected">Металлический</option>
      <option>Пластиковый "Квадро"</option>
      </select></td></tr>

, так понимаю с onchange скрипт должен срабатывать при каждом изменении (потере фокуса). Вариант также не увенчался успехом.

рони 26.05.2015 01:05

зависимые селекты
 
oneplus,
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">
</head>

<body>
<form name="light_box">
<table width="600" align="center" class="light_box">
<colgroup><col width="210"><col width="390"></colgroup>
<tbody>

<tr><td class="left">Профиль:</td>
<td><select id="profile" name="profile">
      <option selected="selected">Металлический</option>
      <option>Пластиковый "Квадро"</option>
      </select></td></tr>
<tr><td align="left">Лицевая поверхность:</td>
<td><select name="surface" size="5">
      <option selected="selected">Акрил молочный (пленки)</option>
      <option>Акрил молочный (полноцветная печать)</option>
      <option>Транслюцентный баннер</option>
      <option>Сотовый поликорбанат (пленки)</option>
      <option>Сотовый поликорбанат (полноцветная печать)</option>
      </select></td></tr>

</tbody>
</table>
</form>
<script>
var s = document.querySelectorAll("select"),
    o = s[1].options,
    op = o[2];

function foo() {
    this.selectedIndex ? o.remove(2) : o.add(op, 2)
}
s[0].onchange = foo;
</script>



</body>


</html>

oneplus 26.05.2015 10:11

Огромное спасибо.
 
Огромное спасибо, работает!
Правильно ли понимаю?
var s = document.querySelectorAll("select"),//все списки
    o = s[1].options,//второй список, где будут происходить изменения
    op = o[2];//оптион, который будет удаляться
//а вот, что происходит дальше?
//"this.selectedIndex" - расшифруйте пожалуйста условие
//true - удаляем третий оптион, false - добавляем третий оптион во второй список
function foo() {
    this.selectedIndex ? o.remove(2) : o.add(op, 2)
}
//первый список при каждом изменении проверяется по функции?
s[0].onchange = foo;

Вообщем не хотелось бы вставлять безглядно код, прошу расшифровать обычном языком, что произошло, особенно в функции не понимаю \ не вижу условия "при выборе селект0 оптион1".
И второй вопрос, на странице, да и в самом калькуляторе будут еще селекты, а если добавить селектов (например селект перед), скрипт перестает работать корректно, можно ли привязать этот скрипт только к этим двум селектам, например по id?

Что не правильного в этом условии? Почему не возвращает оптион 2.
var objPro = document.getElementById("profile_id");
var objSel = document.getElementById("surface_id");
function foo() {
  (objPro.selectedIndex == 1) ? objSel.options.remove(2) : objSel.options.add(objSel.options[2],2)
}
objPro.onchange = foo;

Скрипт по началу работает как надо, но при обратном выборе оптион 2 не возвращает.
В html все id прописаны.

рони 26.05.2015 11:16

Цитата:

Сообщение от oneplus
//все списки

все селекты
Цитата:

Сообщение от oneplus
//второй список, где будут происходить изменения

NodeList опционов второго селекта
Пластиковый "Квадро this.selectedIndex == 1
Металлический - this.selectedIndex == 0 => this.selectedIndex уже ноль что даст false, сравнение с нулём и единицей опускаем, так как всего 2 опциона для выбора.
Цитата:

Сообщение от oneplus
Что не правильного в этом условии?

objSel.options.add(objSel.options[2],2) в этой строке нет опциона Транслюцентный баннер, потому что он уже отсутствует в селекте , а есть Сотовый поликорбанат (пленки) который благополучно вставляется на своё же место.
в моём случае он никуда не изчез, потому-то на него ссылается отдельная переменная.
var objPro = document.getElementById("profile_id");
var objSel = document.getElementById("surface_id");
var ops = objSel.options[2];
function foo() {
  (objPro.selectedIndex == 1) ? objSel.options.remove(2) : objSel.options.add(ops,2)
}
objPro.onchange = foo;

oneplus 26.05.2015 14:08

Благодарю, все понятно и доступно!
Сегодня открыл для себя новые горизонты:)
:thanks:

kostyanet 26.05.2015 14:20

Сделайте еще одно открытие - транслюцентный это калька для дебилов, а по-русски говорят "просвечивающий". Это будет единственное, потому что ваш хардкор будет работать пока все условия в хардкоде совпадают с данными. Как только данные поменяются, добавится еще Трансцендентный баннер - пиндец, вам придется править свой хардкор. Уровень абстрации ниже плинтуса и самое печальное что некоторые профессора ничтоже сумняще его там и удерживают.

рони 26.05.2015 14:44

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

kostyanet 26.05.2015 15:25

А я о чем написал? Добавится кубический конь к сферическому и полезет наш счастливый аффтар добавлять

o11 = s[11].options,
op22 = o[22];

Короче, все делается не так, но как делается - не делается долбоящерами. Они хардкодят.

Sigizmund2012 27.05.2015 17:43

Цитата:

Сообщение от рони (Сообщение 372452)
kostyanet,
вечно ты выдумываешь коня в вакуме, когда есть решение для одного обьекта, решить задачу с десятком можно без труда, распространив метод на нужные обьекты.

По-моему вы пользователю оказали медвежью услугу, у него проект коммерческий, а вы ему код написали с методом remove(), который не поддерживается Internet Explorer https://developer.mozilla.org/en-US/...ildNode/remove

рони 27.05.2015 18:09

Sigizmund2012,
если вас не затруднит проверьте

рони 27.05.2015 18:17

Sigizmund2012,
единственное ограничение в том коде querySelectorAll для ie ниже 8 , которое легко исправить
s = document.getElementsByTagName('select')

и код будет работать во всех версиях ie

kostyanet 27.05.2015 18:26

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

рони 27.05.2015 18:29

kostyanet,
видимо вы не программист если вам один метод сложно применить к массиву элементов и вы делаите отдельную функцию для каждого элемента

kostyanet 27.05.2015 18:47

Цитата:

Сообщение от рони
видимо вы не программист

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

рони 27.05.2015 18:50

kostyanet,
напишите свой вариант для вашего реляционного коня в вакууме.

kostyanet 28.05.2015 05:36

Кстати если потусоваться на sql.ru то увидите что таких программистов которые запростяк рушат все эти постулаты дофига и больше. Они воспринимают бд как обычный массив или объект, в котором по недоразумению забыли проиндексировать-пронумеровать все данные. Потом когда при ожидании получить одну - им вываливается несколько миллионов записей по условию != они жутко недоумевают.

Чтобы сделать интерактивные деревянные (tree) списки в хтмле, туда надо перенести отношения. Самое очевидное решение - в каждом дочернем элементе лежит атрибут указывающий на родителя. Тогда взяв родителя за уши можно вытрясти с него всех деток по тому же самому ключу или индексу, а чужих деток - стрясти.

Это если уровней как в примере - 2. Если больше, то приходится идти рекурсивно. Все давным давно отработано и известно. Изобретать тут вообще уже нечего.

kostyanet 28.05.2015 06:11

Стандартная таблица для дерева в парадигме adjacent list, то есть обычной "плоской" таблицы минимально состоит из отношений:

id
pid
name

В pid хранится значение родительского id. Нормально получить из бд дерево толком нельзя, или придется join'ить таблицу саму с собой столько раз, сколько там уровней, о числе которых надо знать заранее. Приходится загружать все, а скриптом уже превращать плоский список в деревянный. Получив дерево в массиве можно смотреть как его отрендерить в хтмл со всеми отношениями. Вот и все.

Sigizmund2012 28.05.2015 09:58

Цитата:

Сообщение от kostyanet (Сообщение 372727)
Ну разумеется я не программист, я - дизайнер.

:haha: Ну наконец-то всё встало на свои места. А я всё думал, как программист таким упоротым может быть? :D

Sigizmund2012 28.05.2015 10:01

Цитата:

Сообщение от рони (Сообщение 372719)
Sigizmund2012,
если вас не затруднит проверьте

В IE 9 всё работает, странно. Я как-то привык уже MDN доверять.

рони 28.05.2015 10:34

Sigizmund2012,
вы просто не туда посмотрели -- работа с удалением добавлением options это отдельная песня/api, нечто похожее это api добавления удаления строк в таблице.
и прописано очень давно :) в 4 ie уже было,
где посмотреть таблицу поддержки правда незнаю, но похоже это нечто базовое.

kostyanet 28.05.2015 13:25

Цитата:

Сообщение от Sigizmund2012
А я всё думал, как программист таким упоротым может быть

Это эвфемизм от "покажи свой" код. Х нанэ, не покажу, сами перепишите правильно начиная с этой строки

Цитата:

Сообщение от oneplus
document.light_box.surface.options[2]=null



Часовой пояс GMT +3, время: 00:49.