Заметка сто тридцатая
К ВОПРОСУ О ФОРМАХ
Межконфессиональная разборка получила, наконец, свое запоздалое разрешение. Читатель Сергей Вышенский из страны Восходящего пропутешествовал дальней дорогой в полмира до малоизвестного собрания русских классических МИДИ в Гейдельбергском университете и нашел там Русскую пасхальную увертюру Николая Андреевича Римского-Корсакова, заархивированную в мало кому понятный сегодня формат LHA (71К). Каковую увертюру читатель недрогнувшей рукой развернул в формат МИДИ (287K, 14'04" чистейшего звучания) и прислал все это нам вместе с сопроводительными записками г-на Гари Голдберга <GaryG@ix.netcom.com> о том, как настраивать к этому файлу колокольцы и виолончельное пиццикато с поправкой на разное железо. Фанаты МИДИ и мастера wavetable приглашаются сгружать и причащаться. Для мучеников bandwidth припасен отдельно тот же файл в формате ZIP.
Еще из жизни МИДИ. Прочитав во вчерашней нашей заметке, что на сегодня у нас назначена фоновая публикация бессмертного сочинения Франческо диМилано, читатель Михаил Харшан не поленился и дослал еще два варианта того же произведения. По ссылкам в левой колонке сегодняшней заметки их можно сгружать или прослушивать поштучно, а для отгрузки в архивированном виде (ZIP, 3K) можно воспользоваться этой ссылкой.
К сегодняшней теме. Однажды - довольно, впрочем, давно, - я был занят составлением учебников по разным превратностям HTML. Писал я эти учебники в основном в порядке практикума. Появлялась новая тема, вызывающая интерес - я исследовал, пробовал сам, затем делился опытом, примерами и ссылками с читателем. Так возник, например, учебник Client Side Image Maps, спустя считанные дни после того, как корпорация Netscape впервые поддержала эту спецификацию (к сожалению, с тех незапамятных пор учебник этот ни разу не обновлялся, а потому все местные ссылки в нем ведут на несуществующий сегодня сервер zaraza.netmedia.net.il).
Последним моим экспериментом на этом поприще стал учебник по HTML формам, написанный минувшей осенью. У меня так никогда и не хватило времени довести его до ума, расставив внутренние ссылки по разделам, а потому я не стал подавать его ни в какие поисковые машины, сообщив адрес лишь тем нескольким сотрудникам Шарата, которым пособие в первую очередь предназначалось. Однако жизнь берет свое, и совсем недавно до этого учебника добрались какие-то особо пытливые роботы, занеся его в несколько популярных поисковых машин. С той поры сайт стал культовым, траффик на нем составляет тысячи посещений в день, а я непрерывно получаю корреспонденцию от посетителей с вопросами по различным аспектам создания HTML форм. Судя по этим письмам, тема учебника становится чем дальше, тем актуальнее - и настало время соорудить легкий FAQ по тем вопросам, которые наиболее часто встречаются в читательской почте по этому поводу.
Примечательно, что абсолютное большинство присылаемых мне вопросов посвящено не столько хитростям HTML, сколько приемам написания CGI по обработке пользовательского ввода. Про скрипты CGI и правила их писания в моем учебнике не было сказано ни слова, поскольку сам я настолько далек от программирования, насколько это только возможно. Тем не менее, ответы на вопросы по CGI с конкретными примерами дать несложно - благо все аспекты поднимаемых пользователями проблем уже исследованы на практике, и опыт их решения накоплен сегодня немалый. На сем приступим к делу.
Возможна ли графическая кнопка RESET?
К сожалению, нет. Элемент INPUT TYPE=IMAGE является эквивалентом только для SUBMIT. Причем к основному действию формы (FORM ACTION) графическая кнопка от себя добавляет еще и передачу (в формате x=10 y=20) координат той точки на рисунке, в которую пользователь ткнул. Мне не доводилось встречать скрипты, в которых бы эта добавочная функция была толком использована (для этого пришлось бы превращать кнопку подачи в imagemap специального формата, и всю его цифровую легенду подробно описывать в скрипте, который обслуживает форму). Однако по умолчанию если скрипт не ожидает получить какие-либо переменные, то он и их, и пришедшие с ними значения холодно игнорирует - поэтому никаких неудобств добавление двух дополнительных полей к форме не создает. Примеры можно видеть в поисковых машинах Hotbot и Rambler, где кнопка SUBMIT является рисунком.
Что касается популярного среди любителей ЯваСкрипт элемента BUTTON, то он не приемлет атрибута SRC, так что для рисования графических кнопок он непригоден.
Хороший обходной маневр на эту тему придумал наш старый знакомый Graph для использования в своем перекодировщике. Там вместо SUBMIT используется вообще гипертекстовая ссылка HREF, а не кнопка. Форма в этой ситуации может быть заполнена и подана несколько раз интерактивно с одной и той же отправной страницы (множественный SUBMIT). Параметры ссылки определяются пользователем через поля ввода формы и динамически подставляются в адрес с помощью яваскриптовой функции onChange. Если посетитель трогал мебель - все отпечатки передаются скрипту в форме аргументов, а на выходе стоят парсеры.
При использовании такой технологии можно закатать картинку и в RESET. Только она будет не элементом формы, а гипертекстовой ссылкой на ту же самую страницу с исходными значениями всех переменных (типа RELOAD без repost). Работать будет соответственно медленней из-за принудительного обращения к первоисточнику. Можно еще упростить, но это отдельный разговор.
Существенный недостаток графского способа - ЯваСкрипт, подвижный, как блики на Солнце. Он, как известно, не везде одинаково хорошо понимается. Кстати, даже в Нетскейпе иногда с ним возникают проблемы. И решаются они всегда нетривиально - через последовательный reload, reset, reboot и re-install интерпретатора.
Можно ли послать ответ формы в отдельное окно?
Совершенно запросто. Один из способов описан выше - можно запускать форму через гипертекстовую ссылку. Но гораздо более простой путь - это указать TARGET прямо внутри команды FORM:
<FORM ACTION="http://www.cityline.ru/vi/" TARGET="_blank">
Пример можно видеть в нашей левой колонке, где результат поиска в АльтаВисте возвращается в новое окно.
Отдельное спасибо за эту наводку Сергею Захарову и Олегу М. Строкову.
Как задать обязательные для заполнения поля в форме?
На уровне HTML нужно просто написать словами, что данные поля необходимо заполнить для успешного исполнения скрипта. А на уровне CGI нужно ввести инструкцию примерно такого содержания:
если значение $переменной=="", повторно нарисовать ту же форму с сообщением о том, что обязательные поля остались пустыми
Две маленьких хозяйственных хитрости в этом приеме. Во-первых, не надо заставлять пользователя, если он забыл заполнить одно какое-нибудь поле, повторно отвечать на все вопросы, на которые он уже ответил раньше. Для этого уже существующие ответы можно подставить в заново генерируемую форму через атрибут VALUE=$имя_поля. Во-вторых, если необходимых полей несколько, то можно их все объединить в один array (скажем @mandatory) и проверять длину параметров, входящих в этот набор, одной командой.
Как отменить обязательные для заполнения поля в форме?
Допустим, что скрипт, требующий обязательного заполнения определенных полей (например, HTMAIL.PL или Guestbook Мэтта Райта) написали не мы, и у нас даже нет доступа, чтобы его исправлять (скажем, скрипт - общего пользования и лежит в недоступной нам директории /CGI-BIN/). Как отменить записанное в этом скрипте требование обязательного заполнения отдельных полей?
Здесь можно использовать в качестве рычага интерфейс HTML. Если изначально предлагать пользователю форму с уже заполненными полями (используя VALUE) то даже при отсутствии сознательного пользовательского ввода форма будет успешно обработана.
Дополнительная хитрость состоит здесь в том, что кое-какие сведения о посетителе (такие, которые он сам сообщать о себе поленился) можно брать из настроек его же собственной бродилки и подставлять незаметно в виде ответов формы. Для этого, впрочем, нужно разрешение на использование SSI:
<input type="hidden" name="Host" value="<!--#echo var="REMOTE_HOST" -->">
Естественно, те же значения можно подставлять и в видимые поля формы:
Ваш адрес: <input type="TEXT" name="Host" value="<!--#echo var="REMOTE_HOST" -->" SIZE=20>
|