Guzei.com / www / JavaScript

© 2006 Игорь Гузей (Guzei.com)

Это не точная и окончательная инструкция к действию использующая правильные термины и оптимальные варианты. Это скорее лог начинающего JS-программиста. Буду благодарен за любые замечания.

Задача:
Добавить один новый элемент в уже существующий список из нового окна.
Когда может пригодиться?
Клиенту предлагается заполнить большую форму один из элементов которой - список. Алгоритм предусматривает вариант, что список не полный и должен давать клиенту возможность его пополнить. Например, в большой форме клиент должен выбрать свой город, но иметь абсолютно полный список городов очень сложно и клиенту предлагается добавить свой город в базу городов. Открыть новое окно, добавить запись в базу, вернуться в родительское окно и обновить всю форму - неудобно. Удобнее добавить в новом окошке данные в базу, получить ID и вставить полученные значения в список, находящейся в родительском окне, да ещё и сразу поставить фокус на только что введённый элемент.
Решение:
  1. Новое окно надо открывать с помощью JavaScript window.open. В этом случае новое окно будет знать своего родителя и сможет вернуть в него данные.
    Совет: не стоит использовать новую форму для этого, т.к. её конечный элемент </form> закроет и основную форму.
    Пример: <P STYLE='cursor: pointer; text-decoration: underline; color: #00f; margin: 0' onClick=window.open('./add_city.html','_blank','width=500,height=200')>Добавить город</P>
  2. В новом окне надо определить данные для возврата в основное окно. Наиболее логично определить информацию для атрибута VALUE тега OPTION и текст для этого же тега.
    Совет: занесите название города в базу данных, получите его ID и этот ID верните в качестве значения для атрибута VALUE.
  3. Присвоим новые значения самому первому (порядковый номер - ноль) элементу OPTION, который был вставлен в SELECT так:
    <OPTION VALUE=0>Выбери город:
    таким образом будут убиты сразу два зайца - и элемент вставится в самое заметно место и нулевое значение будет заменено тем, что захотел клиент.
    В новом окне надо сделать примерно так:
    window.opener.document.form1.city_id.options[0].value = city_id;
    window.opener.document.form1.city_id.options[0].text = city_name;
    window.opener.document.form1.city_id.options[0].selected = true;
    Здесь нулевому пункту списка options[0] поля SELECT по имени city_id формы с именем form1 из старого окна window.opener.document присваиваем новые значения.
  4. Добавим новый элемент. Казалось бы надо:
    window.opener.document.form1.city_id.options.add(new Option("city_name",city_id,true,true));
    Но это не срабатывает. Как можно прочитать в этом обсуждении подобная проблема известна - "IE, в отличие от Mozilla/Firefox и Opera не признаёт элементы, созданные в другом окне".
    А вот точно такое же добавление прямо из этого окна работает нормально:
    document.form1.city_id.options.add(new Option(this.form.city_name.value,this.form.city_id.value,true,true))
    Добавить элемент в список:
    ID: Name:
    Т.е. функцию создания нового элемента OPTION надо написать в родительском окне, а из дочернего окна только передать параметры.
    В родительском окне пишем:
    function ins_city(city_id,city_name){
     document.form1.city_id.options.add(new Option(city_name,city_id,true,true));
    }
    А в кнопке popup окна:
    onClick="if (window.opener){window.opener.ins_city(this.form.city_id.value,this.form.city_name.value)}"
Пример JavaScript:
Большая форма Форма по имени form1 среди прочего содержит список по имени city_id с элементами обращение к которым возможно по их порядковым номерам.

... множество элементов формы ...

Добавить город


... множество элементов формы ...


После посылки формы будет передано значение VALUE выбранного элемента OPTION. Нажмите на кнопку и посмотрите адресную строку.
Ключевые слова по теме:
JavaScript, JS, window.open, opener, new Option, select, options, value, text, selected, список, элемент, вставка, окно, родительское, свойства, методы, события.
Сайты по теме:
xpoint.ru/forums/programming/javascript/misc/thread/25382.xhtml - обсуждение этой же проблемы.