Во время обучения в колледже я в течение нескольких лет изучал испанский язык. В начале второго года обучения я спросил профессора: "Что мы будем проходить в этом году?" Профессор ответил: "То же самое, что и в прошлом, но я надеюсь, что на этот раз на другом уровне". Несмотря на то, что второй год курса обучения охватывал большую часть материала, изученного ранее, он был качественно другим. Мы стали тоньше чувствовать нюансы, свободнее выражать свои мысли, то есть усваивать язык.
То же самое происходит и с приложениями, создаваемыми в уроках 11 и 12. Большинство действий покажутся знакомыми, но на этот раз следует более глубоко проработать представленные в упражнении материалы, а, возможно, и восполнить и отдельные пробелы в знаниях. Работа с динамическими данными, извлеченными из баз данных, проводилась на протяжении трех предшествующих уроков, так что процесс создания наборов записей и динамического добавления полученных из этих наборов записей значений на страницы не должен показаться чем-то сложным. Помимо вывода простого текста, в выполненных упражнениях производился динамический вывод изображений и описывался способ отображения чисел в формате валюты. Более того, в конце урока 10 производился поиск данных из одной таблицы на основе критерия, заданного для другой. Из выполнения и многократного создания кода для решения подобных задач и складывается процесс разработки динамических сайтов.
(рис 11.1) У языка SQL гораздо больше возможностей, чем простое извлечение данных из одной таблицы. В этом уроке будет вручную написан SQL код, объединяющий несколько таблиц при помощи предложения JOINТак, уроки 11 и 12 построены на основе указанных выше ключевых моментов. Как и в случае с приложением для поиска и отображения информации о странах, будет создано мини-приложение, состоящее из двух страниц, позволяющее пользователям найти и вывести на страницу описания выбранных ими путешествий. Но путешествия – они, в конце концов, являются главной особенностью сайта Newland Tours – требуют более сложного набора возможностей. Будет реализовано три различных подхода для доступа к турпоездкам (отображать все туры, показать туры по конкретному региону или отобразить путешествия в одной из стран). Помимо этого будет показано, как переслать оперативные данные из данного приложения в приложения с информацией по стране и калькулятором для расчета стоимости путешествия с тем, чтобы эти отдельные приложения заработали на более высоком интеллектуальном уровне.
Для создания SQL-кода вместо панели Recordset (Набор записей) в уроках будет применяться ручное кодирование. Такой подход значительно усовершенствует навыки работы с SQL. При этом SQL-код значительно усложнится. Для совместного использования динамических данных, серверных сценариев и SQL-запросов потребуется стратегическое мышление. В то же время без особых усилий будут использоваться уже изученные способы пересылки данных: формы, строки запроса/URL-адреса, локально и запрос. Наконец, статический HTML-код нередко будет комбинироваться с динамическим кодом ASP, ColdFusion или PHP самыми разнообразными способами и с применением навыков креативного мышления.
Что будет изучаться:
Время выполнения
На выполнение этого урока потребуется приблизительно два часа.
Файлы урока
Исходные файлы:
iLesson11/Start/newland/generic_template.asp
Lesson11/Start/newland/tourprice.asp
Lesson11/Start/newland/tourprice_processor.asp
Итоговые файлы:
Lesson11/Complete/newland/tours_detail.asp
Lesson11/Complete/newland/tourprice.asp
Lesson11/Complete/newland/tourprice_processor.asp
Перед разработкой любого приложения следует подробно разобраться в том, как оно должно работать. В процессе создания непременно потребуется что-либо усовершенствовать и принять новые решения, и идея будет развиваться дальше. Но прежде, чем начинать, следует точно знать, что именно будет построено. Нередко я рисую блок-схемы как с помощью программы Freehand MX, так и на бумаге.
В случае с этим приложением рекомендуется снова посетить онлайновую версию сайта и посмотреть окончательную версию приложения. После того, как станет ясно, к чему следует стремиться, все шаги станут намного понятнее.
Процедура регистрации для входа в систему будет реализована через несколько уроков.
Cтраница содержит три различных способа для доступа к описаниям путешествий. Во-первых, туры отображаются по выбранному региону. Во-вторых, можно показать все путешествия для выбранной страны. Если щелкнуть на ссылке View all tours, то на странице будут представлены все путешествия (без всякой фильтрации).
При наведении указателя мыши на ссылки, regionID=1 (или другое значение). Неудивительно, что SQL-оператор на странице с описаниями (tours_details.asp) использует для фильтрации именно этот параметр. Но при наведении указателя на ссылку View all tours к адресу не добавляются параметры. Поскольку при переходе по этой ссылке данные не фильтруются, нет необходимости пересылать на следующую страницу какие-то переменные.
Если выбрать в меню отдельную страну и нажать кнопку Submit, данные будут отправлены в качестве переменной формы и использованы для фильтрации выбранных записей на следующей странице. Конечно, список стран в этом меню формируется динамически, поэтому список всегда отображает самые последние изменения (см. рис. вверху следующей страницы).
Особое внимание следует уделить URL-адресу. Он содержит параметры только при щелчке на одной из ссылок с названием региона. При переходе на страницу при помощи формы или ссылки View all tours параметры URL-адреса не передаются. Также следует обратить внимание, что все три способа позволяют просмотреть информацию о путешествиях в любой из выбранных стран (см. рис. внизу следующей страницы).

Следует обратить внимание на то, что в раскрывающемся списке с названиями путешествий, отображается именно тот тур, описание которого было на экране во время перехода по ссылке. Так, например, если щелкнуть на ссылке Tour Price Calculator, расположенной в разделе с описанием путешествия "Highlights of Morocco" ("Достопримечательности Марокко"), то в списке окажется выбранным именно это название. Отчасти, это возможно благодаря параметру URL-адреса (в случае с "Highlights of Morocco" — это tourID=17).
Во введении к уроку говорилось, что приложение для поиска и отображения разделов с описанием путешествий будет настроено на совместную работу с приложением для расчета стоимости путешествий. Настройка будет произведена позднее в этом уроке.
И еще, как говорилось ранее, сайт показывает все путешествия, предоставляемые Newland Tours на данный момент, даже при внесении изменений в базу данных. При этом, отображение соответствует критерию отбора нужной записи, который выбирает пользователь для поиска нужной информации.
Завершив изучение приложения, следует закрыть браузер и вернуться в Dreamweaver.
В этом упражнении будет создана страница, на которой показаны путешествия. Поскольку это новая страница, то ее разработку следует начать с шаблона generic_template.asp. На странице используется довольно много SQL-запросов (не меньше трех), и самый простой из них будет создан в этом уроке. Этот запрос извлечет из базы всю информацию обо всех путешествиях, без применения фильтрации.
После создания запроса будет использована инструкция SQL, которая называется объединением. Как известно, реляционная база данных разбита на несколько таблиц, связанных между собой. Иногда требуется использовать данные одновременно из двух связанных таблиц. Для получения этой информации применяется операция объединения. Как ни странно, объединение уже создавалось в предыдущем уроке, на странице с информацией о стране при изменении SQL-инструкции так, чтобы кроме идентификатора (кода) региона она извлекала из таблицы еще и его название (с помощью предложения WHERE ).
Cинтаксическая конструкция, использованная в уроке 10, была записана на основе предложения WHERE, на сегодняшний день это не самый удобный способ для создания объединений, однако он самый простой для понимания и будет поддерживаться в большинстве СУБД (например, Access и MySQL) в ближайшем будущем, так что ее использование вполне уместно. Но существует более эффективный способ объединения таблиц. Мы рассмотрим его в этом упражнении.
В этих двух шагах создается статическая часть страницы. Информация с описанием путешествий будет помещена между двумя ссылками Find Tours, чтобы пользователи могли без труда вернуться с подчиненной страницы с детальной информацией на страницу поиска.

Name: rs_tourDetail (Имя: rs_tourDetail) Connection: conn_newland (Соединение: conn_newland) Table: tbl_tours (Таблица: tbl_tours) Columns: All (Столбцы: все)
Требуется создать запрос, который будет извлекать из таблицы tbl_tours всю информацию для создания разделов с описанием путешествий. Как и в случае с информацией о странах, одно из полей (country) содержит внешний ключ, что означает, что будет извлечено произвольное число (первичный ключ, соответствующий стране), а не название страны, которое действительно требуется. Для извлечения этой информации будет использоваться объединение таблиц, но средствами программы Dreamweaver сделать это не представляется возможным, – так что на этом шаге создается часть SQL-запроса, которая в дальнейшем послужит основой более сложного запроса.

Этот вариант диалогового окна содержит SQL-код, заданный на предыдущем шаге. Недостающий код будет введен в этом окне.

SELECT * FROM tbl_tours INNER JOIN tbl_country ON tbl_country.countryID=tbl_tours.country ORDER BY tbl_country.countryName
Многим синтаксис, используемый для объединения, покажется сложным. Однако этот код выполняет те же действия, что и приведенный ниже запрос (более легкий для чтения):
SELECT * FROM tbl_tours, tbl_country WHERE tbl_country.countryID=tbl_tours.country ORDER BY tbl_country.countryName
Этот код извлекает из обеих таблиц все записи и поля. При объединении двух таблиц проверяется соответствие значения поля country в таблице tbl_tours значению первичного ключа countryID в таблице tbl_countryName. Благодаря этому к каждому путешествию добавляется правильная информация о стране. Например, Аргентина и все соответствующие ей данные из таблицы tbl_country будут связаны с туром Highlights of Argentina (Достопримечательности Аргентины).
После объединения двух таблиц по общему полю (или полям) country и/или countryID в качестве критерия для объединения, извлеченные записи сортируются по названиям стран.

В диалоговом окне Test SQL-statement (Проверка SQL-инструкции) появится большое число записей. Для того, чтобы увидеть большинство данных, придется прокрутить окно вправо, поскольку изначально они находятся за пределами экрана (см. рис. внизу следующей страницы).
Обратите внимание на два момента. Во-первых, в столбце country (четвертый слева) содержатся только числа. Если не выполнить объединение и попытаться вывести название страны на странице с описанием путешествия, то вместо названия появится соответствующее число из этого столбца. Справа, за пределами окна, расположен столбец countryName. В нем в алфавитном порядке перечислены все страны. Этот столбец был добавлен в набор записей благодаря объединению. Это позволяет выводить на страницу не числа, а названия стран.
В результате проделанная операция ничем не отличается от манипуляций с названием региона, производимых в уроке 10. Единственное различие состоит в том, что для извлечения данных была использована более эффективная синтаксическая конструкция ( INNER JOIN…ON… ).
Новый набор записей отобразится на панели Bindings (Привязки). Как говорилось ранее, несмотря на то, что с помощью простого варианта диалогового окна Recordset (Набор записей) невозможно обработать этот SQL-запрос, в программе Dreamweaver эта проблема вполне разрешима. На панели Bindings (Привязки) данные отображаются правильно.
Данные доступны для использования на странице, – так что пора начинать разметку страницы для создания разделов с описанием путешествий.

В этом упражнении на странице будет подготовлено место для описаний путешествий. Как и в случае с информацией о странах, будет применена комбинация статических и динамических элементов.
Теперь в качестве разделителя фреймов с информацией о путешествиях будет использована горизонтальная линейка.
XX Country Name: Tour Name XX (Название страны: название тура XX)
Tour Description: (Информация о турах)
Number of Nights: (Число ночей)
Meals Per Day Included: (Питание)
Exercise Required:(Обязательные экскурсии)
Itinerary:(Маршрут)
Learn More About XX Country Name XX (Дополнительные сведения о стране)
Price This Tour With the Tour Price Calculator (Расчет стоимости поездки с помощью калькулятора)
All Photographs У Photo Disc (Все фотографии)
Как и прежде, сначала на страницу добавляется статическое содержимое, для того, чтобы наметить приблизительную структуру. В последующих шагах в соответствующие участки страницы добавляется динамическое содержимое.
Для добавления знака авторского права У следует выполнить команды Insert\HTML\Special Characters\Copyright (Вставка\HTML\ Специальные символы\Авторское право).

В этом шаге производится форматирование статического каркаса страницы, созданного в предыдущем шаге.
Поскольку при нажатии кнопки Bold (Полужирный) на панели Property Inspector (Инспектор свойств) вместо тегов <strong> Dreamweaver добавляет на страницу теги <span class="author">, следует добавить теги <strong> вручную (см. рис. вверху следующей страницы).
Dreamweaver заменит введенный ранее текст собственным псевдокодом, указывающим на источник динамического текста (см. рис. внизу следующей страницы).

При разработке я нередко включаю и выключаю опцию tbl_country, а название путешествия – из таблицы tbl_tours. То, что страна (Argentina) оказалась правильно связана с описанием тура (Highlights of Argentina) служит подтверждением успешного выполнения запроса.

Tour Description: description Number of Nights: numNights Meals Per Day Included: meals_per_day Exercise Required: exerciseReqd Itinerary: itinerary
Это ключевой шаг, в котором на страницу добавляется большая часть динамического содержимого. Подобные действия производились и раньше (см. рис. вверху следующей страницы).
Теперь, в основном, все выглядит замечательно. Однако часть с расписанием маршрута (Itinerary) выглядит несколько неряшливо, поскольку данные содержатся в двух строках, а вторая строка не выровнена относительно первой. Чтобы это исправить, достаточно простой таблицы.

Теперь, если при выводе полученное значение займет несколько строк, все они будут выровнены так, как требуется. Чтобы посмотреть на результат, следует снова включить опцию

После этого на страницу будет добавлено еще одно название страны. В одном из последующих упражнений к этому названию будет прикреплена ссылка на страницу с информацией о стране.

Как и в случае с профилями стран, описанию каждого путешествия соответствует свое изображение. В этом задании изображения будут динамически добавлены на страницу вместе с альтернативным текстом, описывающим изображение на основе информации, содержащейся в базе данных.
{rs_tourDetail.countryName} , содержащимся в заголовке вверху страницы.Изображение будет размещаться в правом верхнем углу описания так же, как в случае с профилями стран.
Как и в прошлый раз, в базе данных содержатся текстовые строки с URL-адресами изображений. Вместо динамических изображений на страницу добавляется динамический текст, содержащий элемент <img>, внутри которого указан адрес изображения.
В том месте, где только что находился курсор, появится значок изображения.
Значок изображения переместится к правому краю.
Для того, чтобы проверить изображение в действии, следует включить опцию
tour_imageURL в диалоговом окне Select Image Source (Выбор источника изображений) было выбрано поле imageURL. В поле imageURL содержатся ссылки на изображения для профилей стран. Для путешествий предназначаются особые картинки, и пути к ним хранятся в поле tour_imageURL.
tour_imageALT.При выборе tour_imageALT в нижней части панели станет доступным меню Bind To (Прикрепить к). Обычно, по умолчанию в нем выбрано значение img.src.

Теперь подпись прикреплена к изображению в качестве альтернативного описания. Для того, чтобы убедиться в этом, следует выделить изображение, а потом на панели Property Inspector (Инспектор свойств) проверить поле Alt. В поле должен содержаться динамический код, в котором будет ссылка rs_tourDetail.tour_imageALT.

К этому моменту в браузере страница выглядит замечательно. В некоторых браузерах при наведении указателя мыши на изображение появится экранная подсказка с альтернативным описанием. Отметим также, что следует внимательно проверить правильность всех динамических полей. Например, под таблицей с расписанием маршрутов должна располагаться надпись "Learn More About Argentina" ("Дополнительные сведения об Аргентине").
Если не считать двух ссылок внизу страницы, каждая из которых ведет к другим приложениям (к приложению с профилями стран и приложению для расчета стоимости путешествий), формирование описания завершено. Единственная заметная проблема заключается в том, что на странице отображается только одно путешествие (в Аргентину). Требуется создать цикл, с помощью которого на страницу будут выводиться информация для всех путешествий, а не только для первого в списке.
Модель поведения сервера Repeat Region (Повторяющаяся область) была задействована в уроке 10 при выводе названий стран на страницу profiles.asp. Эта модель поведения будет использована снова для вывода на страницу нескольких разделов с описанием туров. Сложность заключается в том, что вместо того, чтобы выводить только названия стран, как в случае со страницей profiles.asp, требуется выводить подробные сведения с изображениями. Следствием этого могут стать большие размеры страницы и значительное время загрузки.
Страница станет более функциональной, если ограничить количество показанных записей так, чтобы, например, за один раз отображалось пять записей, а пользователи могли перемещаться между ними. Это возможно, и довольно просто, если использовать набор встроенных в Dreamweaver моделей поведения серверов. Модель поведения Repeat Region (Повторяющаяся область) позволяет ограничить число отображаемых на странице записей (в данном случае, разделов с описанием путешествий). Другая модель поведения Recordset
Выделенная область будет повторяться при выполнении цикла. Информация об авторском праве и вторая ссылка Find Tours (Поиск туров) не входят в повторяющуюся область, поскольку они должны отображаться ниже всех описаний.

Повторяющаяся область будет отмечена границей.
На странице будет показано пять записей, перечисленных в алфавитном порядке по названиям стран. Первый раздел с описанием – это вновь вариант "Highlights of Argentina" ("Достопримечательности Аргентины"), а последний – "Highlights of France" (см. рис. вверху следующей страницы).
Однако в данный момент на странице не существует способа перейти к следующим пяти записям или в самый конец набора. Посетитель ограничен только пятью первыми описаниями.

Добавляемый "объект приложения" на самом деле является группой серверных моделей поведения. Он создает ссылки (или кнопки – на выбор) First (Первая), Previous (Предыдущая), Next (Следующая) и Last (Последняя). При щелчке на каждой из этих ссылок ASP, ColdFusion или PHP получает информацию о том, какие пять наборов записей следует отобразить. Вдобавок, если посетитель просматривает первый набор записей, ссылки/кнопки First и Previous будут скрыты, поскольку в них нет необходимости. Точно так же окажутся невидимыми и ссылки/кнопки Next и Last, если посетитель находится на странице с последним набором записей. Все четыре ссылки/кнопки отображаются на страницах посередине – между первой и последней.
По завершении на страницу будет добавлена новая таблица, содержащая четыре ссылки. Обратите внимание, что в нижней части панели Server Behaviors (Модели поведения серверов), отобразится несколько новых моделей поведения, в том числе несколько начинающихся со слов "Show if not…" ("Показать, если не..."), и несколько "Move to XXX Record" ("Перейти к XХX записи"). Все это отдельные модели поведения, созданные в момент добавления навигационной панели для перемещения между записями.

Существует возможность создать подобную навигационную панель вручную. Все необходимые серверные модели поведения доступны на панели Server Behaviors (Модели поведения серверов) – в опциях Recordset Paging (Постраничный вывод набора записей) и Show Region (Показать область).
По умолчанию сама таблица, в которой содержатся ссылки, не отображается. Обычно требуется именно это. Однако, поскольку в данном случае на странице расположено очень много привлекающих внимание объектов, навигационная панель остается незаметной. Граница позволяет немного выделить ее.
Навигационная панель работает должным образом. Единственная проблема заключается в том, что на первой и последней страницах таблица навигационной панели выглядит не совсем правильно. Причиной такого некорректного отображения является правило HTML, по которому ячейки таблиц обязательно должны что-то содержать. Поскольку на первой и последней страницах отсутствуют соответственно ссылки First/Previous (Первая/Предыдущая) и Next/Last (Следующая/Последняя), то ячейки остаются пустыми. Для решения проблемы следует добавить в каждую пустую ячейку неразрывный пробел.

<td> и </td> , но за пределами блоков <cfif> , расположенных там же, код (в HTML это код символа неразрывного пробела).Хотя пробел останется невидимым, он считается достаточным для заполнения ячейки. Если снова протестировать файл, таблица будет выглядеть должным образом.
Неважно, расположен ли пробел до или после участка кода, содержащего условие. Самое главное, чтобы он находился за пределами этого участка. Если щелкнуть в конце ссылки при использовании ColdFusion, курсор будет помещен внутри области с условием. Именно поэтому пользователям ColdFusion требуется ввести символ неразрывного пробела вручную.


Теперь посетители имеют возможность просматривать все разделы с информацией о турах, в частности, одновременно пять из них. Все сведения упорядочены и отформатированы, а панель навигации облегчает перемещение между ними. Прежде чем закончить урок, требуется добавить еще две дополнительные функциональные возможности.
Внизу каждого из разделов должны быть две ссылки. Первая ссылка – это название страны, с помощью которой осуществляется переход на страницу profiles_detail.asp, содержащую информацию о стране. Вторая ссылка позволяет перейти к приложению с калькулятором для расчета стоимости путешествий ( tourprice.asp ). Однако недостаточно просто создать ссылки на эти страницы. Требуется также передать им данные, чтобы приложения могли определить, с каким из разделов ознакомился пользователь во время перехода по ссылке.
В случае с профилями стран реализовать этот механизм несложно. Как известно из предшествующего урока, чтобы определить, о какой именно стране следует показывать информацию, приложение использует параметр URL-адреса countryID. Этот параметр появляется в тот момент, когда посетитель переходит по ссылке со страницы profiles.asp. Для получения такого же эффекта следует прикрепить соответствующий параметр URL-адреса к ссылке на странице tours_detail.asp.
Создание ссылки на приложение для расчета стоимости путешествий окажется гораздо сложнее. На этой странице содержится динамически генерируемый список, в котором перечислены все путешествия. Но если посетитель просматривает описание путешествия Highlights of Italy (Достопримечательности Италии), а затем по ссылке Price This Tour With the Tour Price Calculator переходит на страницу с формой для расчета стоимости, он предполагает узнать стоимость тура Highlights of Italy (а не выбранного в списке по умолчанию Biking from Oxford to London). Решение почти такое же, как в случае со ссылкой на профиль страны, когда требуется просто передать на страницу дополнительные данные. Но приложение для расчета стоимости путешествия несколько сложнее, потому что оно не готово к получению и использованию этих данных, в отличие от страницы с профилями стран, которая уже ожидает передачи параметра URL-адреса countryID. В этом задании эта проблема (а также пара других) будет успешно решена.
Во-первых, следует уделить внимание ссылке, ведущей на страницу с профилем страны.
abc.Так же, как в уроке 10, заменитель адреса будет удален сразу после прикрепления к ссылке динамических данных. Но для создания ссылки нужно обязательно указать какое-нибудь значение.

Значение countryID окажется прикрепленным к URL-адресу. На данный момент атрибут ссылки href содержит только число. Следует ввести основной URL-адрес, а также имя переменной для URL-параметра.

Это ссылка на страницу. После того, как сервер обработает весь код, значение поля countryID будет добавлено после знака равенства. Теперь страница profile_details.asp работает правильно. Чтобы убедиться в этом, достаточно протестировать страницу tours_detail.asp в браузере и щелкнуть на одной из ссылок, прикрепленных к названию страны.

abc , чтобы привязать к выделенному тексту ссылку. Так же, как и раньше, на панели Bindings (Привязки) выберите поле tourID, и в списке Bind To (Прикрепить к) прикрепите его к атрибуту a.href. Нажмите Bind (Прикрепить).Текст abc будет заменен значением поля tourID. Осталось вернуться на панель инспектора свойств и ввести остальную часть адреса.

На этом шаге был создан механизм для отправки значения поля tourID на страницу tourprice.asp. К сожалению, на странице tourprice.asp нет кода, способного обработать это значение, – так что ничего не происходит.
После этого переменная, присланная в составе URL-адреса со страницы tours_detail.asp, становится доступной. На следующем шаге эта информация будет прикреплена к списку, после чего нужное путешествие будет выбираться автоматически.
Ранее к этому списку уже прикреплялись динамические данные. Фактически, все опции, перечисленные в списке, динамически добавляются из базы данных. В данный момент целью является не добавление новых элементов (они и так присутствуют в полном составе), а настройка списка таким образом, чтобы по умолчанию выбиралось значение, соответствующее параметру, переданному на страницу в составе URL-адреса.

Как известно из урока 9, объект списка определяется двумя основными видами информации: надписью, которую видят посетители (в качестве надписей в данном случае используются названия путешествий) и ее значениями, которые пересылаются в составе переменных формы (в качестве значений применяются идентификаторы путешествий). В данном шаге выбранное значение (а, следовательно, и надпись) устанавливается равным полученному значению параметра URL-адреса.

При наведении указателя мыши на ссылку Tour Price Calculator (Калькулятор для расчета стоимости тура) в строке состояния отображается адрес страницы с прикрепленным к нему параметром. Механизм работает превосходно, но за одним исключением.

Запускается сценарий для проверки формы, и страница загружается снова – с сообщением об ошибке. Все работает правильно. Но в списке Tour Name (Название тура) вновь выбран пункт Biking from Oxford to London (Байкинг от Оксфорда до Лондона). При повторной загрузке страницы параметр tourID пропадает, поэтому форма не может отобразить нужный тур и выводит первый запись из набора.
В идеале, сценарий проверки правильности заполнения формы, находящийся на странице tourprice_processor.asp, при повторной загрузке страницы tourprice.asp должен отправлять обратно и значение параметра tourID.

Для ASP:
Response.Redirect("tourprice.asp?error=notnumeric")
Для ColdFusion:
<cflocation url="tourprice.cfm?error=notnumeric">
Для PHP:
header("Location: tourprice.php?error=notnumeric"
Этот участок кода отвечает за перенаправление на страницу tourprice.asp. Как видно из кода, здесь уже задан один параметр URL-адреса. Для улучшения работы приложения достаточно добавить еще один параметр.
Для ASP:
Response.Redirect("tourprice.asp?error=notnumerictourID=" Request.Form("tourName"))
Для ColdFusion:
<cflocation url="tourprice.cfm?error=notnumerictourID=#form.tourName#">
Для PHP:
header("Location: tourprice.php?error=notnumerictourID=".$_POST['tourName']);
Несложно догадаться, для чего предназначен добавленный код. При перенаправлении на страницу tourprice он прикрепляет к запросу переменную URL-адреса tourID. Значение этой переменной равно значению переменной формы form.tourName, которое было выбрано в списке к моменту нажатия кнопки Submit. Как известно из шагов 6, 7 и 8, при загрузке страницы tourprice.asp значение в списке по умолчанию выбирается на основе переменной URL-адреса tourID.
На этот раз все должно работать без сбоев. Данные незаметно передаются от одного приложения другому, и страница реагирует соответствующим образом благодаря простым операциям по пересылке и подготовке данных.
В этом уроке вы узнали о:
Во время обучения в колледже я в течение нескольких лет изучал испанский язык. В начале второго года обучения я спросил профессора: "Что мы будем проходить в этом году?" Профессор ответил: "То же самое, что и в прошлом, но я надеюсь, что на этот раз на другом уровне". Несмотря на то, что второй год курса обучения охватывал большую часть материала, изученного ранее, он был качественно другим. Мы стали тоньше чувствовать нюансы, свободнее выражать свои мысли, то есть усваивать язык.
То же самое происходит и с приложениями, создаваемыми в уроках 11 и 12. Большинство действий покажутся знакомыми, но на этот раз следует более глубоко проработать представленные в упражнении материалы, а, возможно, и восполнить и отдельные пробелы в знаниях. Работа с динамическими данными, извлеченными из баз данных, проводилась на протяжении трех предшествующих уроков, так что процесс создания наборов записей и динамического добавления полученных из этих наборов записей значений на страницы не должен показаться чем-то сложным. Помимо вывода простого текста, в выполненных упражнениях производился динамический вывод изображений и описывался способ отображения чисел в формате валюты. Более того, в конце урока 10 производился поиск данных из одной таблицы на основе критерия, заданного для другой. Из выполнения и многократного создания кода для решения подобных задач и складывается процесс разработки динамических сайтов.
(рис 11.1) У языка SQL гораздо больше возможностей, чем простое извлечение данных из одной таблицы. В этом уроке будет вручную написан SQL код, объединяющий несколько таблиц при помощи предложения JOINТак, уроки 11 и 12 построены на основе указанных выше ключевых моментов. Как и в случае с приложением для поиска и отображения информации о странах, будет создано мини-приложение, состоящее из двух страниц, позволяющее пользователям найти и вывести на страницу описания выбранных ими путешествий. Но путешествия – они, в конце концов, являются главной особенностью сайта Newland Tours – требуют более сложного набора возможностей. Будет реализовано три различных подхода для доступа к турпоездкам (отображать все туры, показать туры по конкретному региону или отобразить путешествия в одной из стран). Помимо этого будет показано, как переслать оперативные данные из данного приложения в приложения с информацией по стране и калькулятором для расчета стоимости путешествия с тем, чтобы эти отдельные приложения заработали на более высоком интеллектуальном уровне.
Для создания SQL-кода вместо панели Recordset (Набор записей) в уроках будет применяться ручное кодирование. Такой подход значительно усовершенствует навыки работы с SQL. При этом SQL-код значительно усложнится. Для совместного использования динамических данных, серверных сценариев и SQL-запросов потребуется стратегическое мышление. В то же время без особых усилий будут использоваться уже изученные способы пересылки данных: формы, строки запроса/URL-адреса, локально и запрос. Наконец, статический HTML-код нередко будет комбинироваться с динамическим кодом ASP, ColdFusion или PHP самыми разнообразными способами и с применением навыков креативного мышления.
Что будет изучаться:
Время выполнения
На выполнение этого урока потребуется приблизительно два часа.
Файлы урока
Исходные файлы:
iLesson11/Start/newland/generic_template.asp
Lesson11/Start/newland/tourprice.asp
Lesson11/Start/newland/tourprice_processor.asp
Итоговые файлы:
Lesson11/Complete/newland/tours_detail.asp
Lesson11/Complete/newland/tourprice.asp
Lesson11/Complete/newland/tourprice_processor.asp
Перед разработкой любого приложения следует подробно разобраться в том, как оно должно работать. В процессе создания непременно потребуется что-либо усовершенствовать и принять новые решения, и идея будет развиваться дальше. Но прежде, чем начинать, следует точно знать, что именно будет построено. Нередко я рисую блок-схемы как с помощью программы Freehand MX, так и на бумаге.
В случае с этим приложением рекомендуется снова посетить онлайновую версию сайта и посмотреть окончательную версию приложения. После того, как станет ясно, к чему следует стремиться, все шаги станут намного понятнее.
Процедура регистрации для входа в систему будет реализована через несколько уроков.
Cтраница содержит три различных способа для доступа к описаниям путешествий. Во-первых, туры отображаются по выбранному региону. Во-вторых, можно показать все путешествия для выбранной страны. Если щелкнуть на ссылке View all tours, то на странице будут представлены все путешествия (без всякой фильтрации).
При наведении указателя мыши на ссылки, regionID=1 (или другое значение). Неудивительно, что SQL-оператор на странице с описаниями (tours_details.asp) использует для фильтрации именно этот параметр. Но при наведении указателя на ссылку View all tours к адресу не добавляются параметры. Поскольку при переходе по этой ссылке данные не фильтруются, нет необходимости пересылать на следующую страницу какие-то переменные.
Если выбрать в меню отдельную страну и нажать кнопку Submit, данные будут отправлены в качестве переменной формы и использованы для фильтрации выбранных записей на следующей странице. Конечно, список стран в этом меню формируется динамически, поэтому список всегда отображает самые последние изменения (см. рис. вверху следующей страницы).
Особое внимание следует уделить URL-адресу. Он содержит параметры только при щелчке на одной из ссылок с названием региона. При переходе на страницу при помощи формы или ссылки View all tours параметры URL-адреса не передаются. Также следует обратить внимание, что все три способа позволяют просмотреть информацию о путешествиях в любой из выбранных стран (см. рис. внизу следующей страницы).

Следует обратить внимание на то, что в раскрывающемся списке с названиями путешествий, отображается именно тот тур, описание которого было на экране во время перехода по ссылке. Так, например, если щелкнуть на ссылке Tour Price Calculator, расположенной в разделе с описанием путешествия "Highlights of Morocco" ("Достопримечательности Марокко"), то в списке окажется выбранным именно это название. Отчасти, это возможно благодаря параметру URL-адреса (в случае с "Highlights of Morocco" — это tourID=17).
Во введении к уроку говорилось, что приложение для поиска и отображения разделов с описанием путешествий будет настроено на совместную работу с приложением для расчета стоимости путешествий. Настройка будет произведена позднее в этом уроке.
И еще, как говорилось ранее, сайт показывает все путешествия, предоставляемые Newland Tours на данный момент, даже при внесении изменений в базу данных. При этом, отображение соответствует критерию отбора нужной записи, который выбирает пользователь для поиска нужной информации.
Завершив изучение приложения, следует закрыть браузер и вернуться в Dreamweaver.
В этом упражнении будет создана страница, на которой показаны путешествия. Поскольку это новая страница, то ее разработку следует начать с шаблона generic_template.asp. На странице используется довольно много SQL-запросов (не меньше трех), и самый простой из них будет создан в этом уроке. Этот запрос извлечет из базы всю информацию обо всех путешествиях, без применения фильтрации.
После создания запроса будет использована инструкция SQL, которая называется объединением. Как известно, реляционная база данных разбита на несколько таблиц, связанных между собой. Иногда требуется использовать данные одновременно из двух связанных таблиц. Для получения этой информации применяется операция объединения. Как ни странно, объединение уже создавалось в предыдущем уроке, на странице с информацией о стране при изменении SQL-инструкции так, чтобы кроме идентификатора (кода) региона она извлекала из таблицы еще и его название (с помощью предложения WHERE ).
Cинтаксическая конструкция, использованная в уроке 10, была записана на основе предложения WHERE, на сегодняшний день это не самый удобный способ для создания объединений, однако он самый простой для понимания и будет поддерживаться в большинстве СУБД (например, Access и MySQL) в ближайшем будущем, так что ее использование вполне уместно. Но существует более эффективный способ объединения таблиц. Мы рассмотрим его в этом упражнении.
В этих двух шагах создается статическая часть страницы. Информация с описанием путешествий будет помещена между двумя ссылками Find Tours, чтобы пользователи могли без труда вернуться с подчиненной страницы с детальной информацией на страницу поиска.

Name: rs_tourDetail (Имя: rs_tourDetail) Connection: conn_newland (Соединение: conn_newland) Table: tbl_tours (Таблица: tbl_tours) Columns: All (Столбцы: все)
Требуется создать запрос, который будет извлекать из таблицы tbl_tours всю информацию для создания разделов с описанием путешествий. Как и в случае с информацией о странах, одно из полей (country) содержит внешний ключ, что означает, что будет извлечено произвольное число (первичный ключ, соответствующий стране), а не название страны, которое действительно требуется. Для извлечения этой информации будет использоваться объединение таблиц, но средствами программы Dreamweaver сделать это не представляется возможным, – так что на этом шаге создается часть SQL-запроса, которая в дальнейшем послужит основой более сложного запроса.

Этот вариант диалогового окна содержит SQL-код, заданный на предыдущем шаге. Недостающий код будет введен в этом окне.

SELECT * FROM tbl_tours INNER JOIN tbl_country ON tbl_country.countryID=tbl_tours.country ORDER BY tbl_country.countryName
Многим синтаксис, используемый для объединения, покажется сложным. Однако этот код выполняет те же действия, что и приведенный ниже запрос (более легкий для чтения):
SELECT * FROM tbl_tours, tbl_country WHERE tbl_country.countryID=tbl_tours.country ORDER BY tbl_country.countryName
Этот код извлекает из обеих таблиц все записи и поля. При объединении двух таблиц проверяется соответствие значения поля country в таблице tbl_tours значению первичного ключа countryID в таблице tbl_countryName. Благодаря этому к каждому путешествию добавляется правильная информация о стране. Например, Аргентина и все соответствующие ей данные из таблицы tbl_country будут связаны с туром Highlights of Argentina (Достопримечательности Аргентины).
После объединения двух таблиц по общему полю (или полям) country и/или countryID в качестве критерия для объединения, извлеченные записи сортируются по названиям стран.

В диалоговом окне Test SQL-statement (Проверка SQL-инструкции) появится большое число записей. Для того, чтобы увидеть большинство данных, придется прокрутить окно вправо, поскольку изначально они находятся за пределами экрана (см. рис. внизу следующей страницы).
Обратите внимание на два момента. Во-первых, в столбце country (четвертый слева) содержатся только числа. Если не выполнить объединение и попытаться вывести название страны на странице с описанием путешествия, то вместо названия появится соответствующее число из этого столбца. Справа, за пределами окна, расположен столбец countryName. В нем в алфавитном порядке перечислены все страны. Этот столбец был добавлен в набор записей благодаря объединению. Это позволяет выводить на страницу не числа, а названия стран.
В результате проделанная операция ничем не отличается от манипуляций с названием региона, производимых в уроке 10. Единственное различие состоит в том, что для извлечения данных была использована более эффективная синтаксическая конструкция ( INNER JOIN…ON… ).
Новый набор записей отобразится на панели Bindings (Привязки). Как говорилось ранее, несмотря на то, что с помощью простого варианта диалогового окна Recordset (Набор записей) невозможно обработать этот SQL-запрос, в программе Dreamweaver эта проблема вполне разрешима. На панели Bindings (Привязки) данные отображаются правильно.
Данные доступны для использования на странице, – так что пора начинать разметку страницы для создания разделов с описанием путешествий.

В этом упражнении на странице будет подготовлено место для описаний путешествий. Как и в случае с информацией о странах, будет применена комбинация статических и динамических элементов.
Теперь в качестве разделителя фреймов с информацией о путешествиях будет использована горизонтальная линейка.
XX Country Name: Tour Name XX (Название страны: название тура XX)
Tour Description: (Информация о турах)
Number of Nights: (Число ночей)
Meals Per Day Included: (Питание)
Exercise Required:(Обязательные экскурсии)
Itinerary:(Маршрут)
Learn More About XX Country Name XX (Дополнительные сведения о стране)
Price This Tour With the Tour Price Calculator (Расчет стоимости поездки с помощью калькулятора)
All Photographs У Photo Disc (Все фотографии)
Как и прежде, сначала на страницу добавляется статическое содержимое, для того, чтобы наметить приблизительную структуру. В последующих шагах в соответствующие участки страницы добавляется динамическое содержимое.
Для добавления знака авторского права У следует выполнить команды Insert\HTML\Special Characters\Copyright (Вставка\HTML\ Специальные символы\Авторское право).

В этом шаге производится форматирование статического каркаса страницы, созданного в предыдущем шаге.
Поскольку при нажатии кнопки Bold (Полужирный) на панели Property Inspector (Инспектор свойств) вместо тегов <strong> Dreamweaver добавляет на страницу теги <span class="author">, следует добавить теги <strong> вручную (см. рис. вверху следующей страницы).
Dreamweaver заменит введенный ранее текст собственным псевдокодом, указывающим на источник динамического текста (см. рис. внизу следующей страницы).

При разработке я нередко включаю и выключаю опцию tbl_country, а название путешествия – из таблицы tbl_tours. То, что страна (Argentina) оказалась правильно связана с описанием тура (Highlights of Argentina) служит подтверждением успешного выполнения запроса.

Tour Description: description Number of Nights: numNights Meals Per Day Included: meals_per_day Exercise Required: exerciseReqd Itinerary: itinerary
Это ключевой шаг, в котором на страницу добавляется большая часть динамического содержимого. Подобные действия производились и раньше (см. рис. вверху следующей страницы).
Теперь, в основном, все выглядит замечательно. Однако часть с расписанием маршрута (Itinerary) выглядит несколько неряшливо, поскольку данные содержатся в двух строках, а вторая строка не выровнена относительно первой. Чтобы это исправить, достаточно простой таблицы.

Теперь, если при выводе полученное значение займет несколько строк, все они будут выровнены так, как требуется. Чтобы посмотреть на результат, следует снова включить опцию

После этого на страницу будет добавлено еще одно название страны. В одном из последующих упражнений к этому названию будет прикреплена ссылка на страницу с информацией о стране.

Как и в случае с профилями стран, описанию каждого путешествия соответствует свое изображение. В этом задании изображения будут динамически добавлены на страницу вместе с альтернативным текстом, описывающим изображение на основе информации, содержащейся в базе данных.
{rs_tourDetail.countryName} , содержащимся в заголовке вверху страницы.Изображение будет размещаться в правом верхнем углу описания так же, как в случае с профилями стран.
Как и в прошлый раз, в базе данных содержатся текстовые строки с URL-адресами изображений. Вместо динамических изображений на страницу добавляется динамический текст, содержащий элемент <img>, внутри которого указан адрес изображения.
В том месте, где только что находился курсор, появится значок изображения.
Значок изображения переместится к правому краю.
Для того, чтобы проверить изображение в действии, следует включить опцию
tour_imageURL в диалоговом окне Select Image Source (Выбор источника изображений) было выбрано поле imageURL. В поле imageURL содержатся ссылки на изображения для профилей стран. Для путешествий предназначаются особые картинки, и пути к ним хранятся в поле tour_imageURL.
tour_imageALT.При выборе tour_imageALT в нижней части панели станет доступным меню Bind To (Прикрепить к). Обычно, по умолчанию в нем выбрано значение img.src.

Теперь подпись прикреплена к изображению в качестве альтернативного описания. Для того, чтобы убедиться в этом, следует выделить изображение, а потом на панели Property Inspector (Инспектор свойств) проверить поле Alt. В поле должен содержаться динамический код, в котором будет ссылка rs_tourDetail.tour_imageALT.

К этому моменту в браузере страница выглядит замечательно. В некоторых браузерах при наведении указателя мыши на изображение появится экранная подсказка с альтернативным описанием. Отметим также, что следует внимательно проверить правильность всех динамических полей. Например, под таблицей с расписанием маршрутов должна располагаться надпись "Learn More About Argentina" ("Дополнительные сведения об Аргентине").
Если не считать двух ссылок внизу страницы, каждая из которых ведет к другим приложениям (к приложению с профилями стран и приложению для расчета стоимости путешествий), формирование описания завершено. Единственная заметная проблема заключается в том, что на странице отображается только одно путешествие (в Аргентину). Требуется создать цикл, с помощью которого на страницу будут выводиться информация для всех путешествий, а не только для первого в списке.
Модель поведения сервера Repeat Region (Повторяющаяся область) была задействована в уроке 10 при выводе названий стран на страницу profiles.asp. Эта модель поведения будет использована снова для вывода на страницу нескольких разделов с описанием туров. Сложность заключается в том, что вместо того, чтобы выводить только названия стран, как в случае со страницей profiles.asp, требуется выводить подробные сведения с изображениями. Следствием этого могут стать большие размеры страницы и значительное время загрузки.
Страница станет более функциональной, если ограничить количество показанных записей так, чтобы, например, за один раз отображалось пять записей, а пользователи могли перемещаться между ними. Это возможно, и довольно просто, если использовать набор встроенных в Dreamweaver моделей поведения серверов. Модель поведения Repeat Region (Повторяющаяся область) позволяет ограничить число отображаемых на странице записей (в данном случае, разделов с описанием путешествий). Другая модель поведения Recordset
Выделенная область будет повторяться при выполнении цикла. Информация об авторском праве и вторая ссылка Find Tours (Поиск туров) не входят в повторяющуюся область, поскольку они должны отображаться ниже всех описаний.

Повторяющаяся область будет отмечена границей.
На странице будет показано пять записей, перечисленных в алфавитном порядке по названиям стран. Первый раздел с описанием – это вновь вариант "Highlights of Argentina" ("Достопримечательности Аргентины"), а последний – "Highlights of France" (см. рис. вверху следующей страницы).
Однако в данный момент на странице не существует способа перейти к следующим пяти записям или в самый конец набора. Посетитель ограничен только пятью первыми описаниями.

Добавляемый "объект приложения" на самом деле является группой серверных моделей поведения. Он создает ссылки (или кнопки – на выбор) First (Первая), Previous (Предыдущая), Next (Следующая) и Last (Последняя). При щелчке на каждой из этих ссылок ASP, ColdFusion или PHP получает информацию о том, какие пять наборов записей следует отобразить. Вдобавок, если посетитель просматривает первый набор записей, ссылки/кнопки First и Previous будут скрыты, поскольку в них нет необходимости. Точно так же окажутся невидимыми и ссылки/кнопки Next и Last, если посетитель находится на странице с последним набором записей. Все четыре ссылки/кнопки отображаются на страницах посередине – между первой и последней.
По завершении на страницу будет добавлена новая таблица, содержащая четыре ссылки. Обратите внимание, что в нижней части панели Server Behaviors (Модели поведения серверов), отобразится несколько новых моделей поведения, в том числе несколько начинающихся со слов "Show if not…" ("Показать, если не..."), и несколько "Move to XXX Record" ("Перейти к XХX записи"). Все это отдельные модели поведения, созданные в момент добавления навигационной панели для перемещения между записями.

Существует возможность создать подобную навигационную панель вручную. Все необходимые серверные модели поведения доступны на панели Server Behaviors (Модели поведения серверов) – в опциях Recordset Paging (Постраничный вывод набора записей) и Show Region (Показать область).
По умолчанию сама таблица, в которой содержатся ссылки, не отображается. Обычно требуется именно это. Однако, поскольку в данном случае на странице расположено очень много привлекающих внимание объектов, навигационная панель остается незаметной. Граница позволяет немного выделить ее.
Навигационная панель работает должным образом. Единственная проблема заключается в том, что на первой и последней страницах таблица навигационной панели выглядит не совсем правильно. Причиной такого некорректного отображения является правило HTML, по которому ячейки таблиц обязательно должны что-то содержать. Поскольку на первой и последней страницах отсутствуют соответственно ссылки First/Previous (Первая/Предыдущая) и Next/Last (Следующая/Последняя), то ячейки остаются пустыми. Для решения проблемы следует добавить в каждую пустую ячейку неразрывный пробел.

<td> и </td> , но за пределами блоков <cfif> , расположенных там же, код (в HTML это код символа неразрывного пробела).Хотя пробел останется невидимым, он считается достаточным для заполнения ячейки. Если снова протестировать файл, таблица будет выглядеть должным образом.
Неважно, расположен ли пробел до или после участка кода, содержащего условие. Самое главное, чтобы он находился за пределами этого участка. Если щелкнуть в конце ссылки при использовании ColdFusion, курсор будет помещен внутри области с условием. Именно поэтому пользователям ColdFusion требуется ввести символ неразрывного пробела вручную.


Теперь посетители имеют возможность просматривать все разделы с информацией о турах, в частности, одновременно пять из них. Все сведения упорядочены и отформатированы, а панель навигации облегчает перемещение между ними. Прежде чем закончить урок, требуется добавить еще две дополнительные функциональные возможности.
Внизу каждого из разделов должны быть две ссылки. Первая ссылка – это название страны, с помощью которой осуществляется переход на страницу profiles_detail.asp, содержащую информацию о стране. Вторая ссылка позволяет перейти к приложению с калькулятором для расчета стоимости путешествий ( tourprice.asp ). Однако недостаточно просто создать ссылки на эти страницы. Требуется также передать им данные, чтобы приложения могли определить, с каким из разделов ознакомился пользователь во время перехода по ссылке.
В случае с профилями стран реализовать этот механизм несложно. Как известно из предшествующего урока, чтобы определить, о какой именно стране следует показывать информацию, приложение использует параметр URL-адреса countryID. Этот параметр появляется в тот момент, когда посетитель переходит по ссылке со страницы profiles.asp. Для получения такого же эффекта следует прикрепить соответствующий параметр URL-адреса к ссылке на странице tours_detail.asp.
Создание ссылки на приложение для расчета стоимости путешествий окажется гораздо сложнее. На этой странице содержится динамически генерируемый список, в котором перечислены все путешествия. Но если посетитель просматривает описание путешествия Highlights of Italy (Достопримечательности Италии), а затем по ссылке Price This Tour With the Tour Price Calculator переходит на страницу с формой для расчета стоимости, он предполагает узнать стоимость тура Highlights of Italy (а не выбранного в списке по умолчанию Biking from Oxford to London). Решение почти такое же, как в случае со ссылкой на профиль страны, когда требуется просто передать на страницу дополнительные данные. Но приложение для расчета стоимости путешествия несколько сложнее, потому что оно не готово к получению и использованию этих данных, в отличие от страницы с профилями стран, которая уже ожидает передачи параметра URL-адреса countryID. В этом задании эта проблема (а также пара других) будет успешно решена.
Во-первых, следует уделить внимание ссылке, ведущей на страницу с профилем страны.
abc.Так же, как в уроке 10, заменитель адреса будет удален сразу после прикрепления к ссылке динамических данных. Но для создания ссылки нужно обязательно указать какое-нибудь значение.

Значение countryID окажется прикрепленным к URL-адресу. На данный момент атрибут ссылки href содержит только число. Следует ввести основной URL-адрес, а также имя переменной для URL-параметра.

Это ссылка на страницу. После того, как сервер обработает весь код, значение поля countryID будет добавлено после знака равенства. Теперь страница profile_details.asp работает правильно. Чтобы убедиться в этом, достаточно протестировать страницу tours_detail.asp в браузере и щелкнуть на одной из ссылок, прикрепленных к названию страны.

abc , чтобы привязать к выделенному тексту ссылку. Так же, как и раньше, на панели Bindings (Привязки) выберите поле tourID, и в списке Bind To (Прикрепить к) прикрепите его к атрибуту a.href. Нажмите Bind (Прикрепить).Текст abc будет заменен значением поля tourID. Осталось вернуться на панель инспектора свойств и ввести остальную часть адреса.

На этом шаге был создан механизм для отправки значения поля tourID на страницу tourprice.asp. К сожалению, на странице tourprice.asp нет кода, способного обработать это значение, – так что ничего не происходит.
После этого переменная, присланная в составе URL-адреса со страницы tours_detail.asp, становится доступной. На следующем шаге эта информация будет прикреплена к списку, после чего нужное путешествие будет выбираться автоматически.
Ранее к этому списку уже прикреплялись динамические данные. Фактически, все опции, перечисленные в списке, динамически добавляются из базы данных. В данный момент целью является не добавление новых элементов (они и так присутствуют в полном составе), а настройка списка таким образом, чтобы по умолчанию выбиралось значение, соответствующее параметру, переданному на страницу в составе URL-адреса.

Как известно из урока 9, объект списка определяется двумя основными видами информации: надписью, которую видят посетители (в качестве надписей в данном случае используются названия путешествий) и ее значениями, которые пересылаются в составе переменных формы (в качестве значений применяются идентификаторы путешествий). В данном шаге выбранное значение (а, следовательно, и надпись) устанавливается равным полученному значению параметра URL-адреса.

При наведении указателя мыши на ссылку Tour Price Calculator (Калькулятор для расчета стоимости тура) в строке состояния отображается адрес страницы с прикрепленным к нему параметром. Механизм работает превосходно, но за одним исключением.

Запускается сценарий для проверки формы, и страница загружается снова – с сообщением об ошибке. Все работает правильно. Но в списке Tour Name (Название тура) вновь выбран пункт Biking from Oxford to London (Байкинг от Оксфорда до Лондона). При повторной загрузке страницы параметр tourID пропадает, поэтому форма не может отобразить нужный тур и выводит первый запись из набора.
В идеале, сценарий проверки правильности заполнения формы, находящийся на странице tourprice_processor.asp, при повторной загрузке страницы tourprice.asp должен отправлять обратно и значение параметра tourID.

Для ASP:
Response.Redirect("tourprice.asp?error=notnumeric")
Для ColdFusion:
<cflocation url="tourprice.cfm?error=notnumeric">
Для PHP:
header("Location: tourprice.php?error=notnumeric"
Этот участок кода отвечает за перенаправление на страницу tourprice.asp. Как видно из кода, здесь уже задан один параметр URL-адреса. Для улучшения работы приложения достаточно добавить еще один параметр.
Для ASP:
Response.Redirect("tourprice.asp?error=notnumerictourID=" Request.Form("tourName"))
Для ColdFusion:
<cflocation url="tourprice.cfm?error=notnumerictourID=#form.tourName#">
Для PHP:
header("Location: tourprice.php?error=notnumerictourID=".$_POST['tourName']);
Несложно догадаться, для чего предназначен добавленный код. При перенаправлении на страницу tourprice он прикрепляет к запросу переменную URL-адреса tourID. Значение этой переменной равно значению переменной формы form.tourName, которое было выбрано в списке к моменту нажатия кнопки Submit. Как известно из шагов 6, 7 и 8, при загрузке страницы tourprice.asp значение в списке по умолчанию выбирается на основе переменной URL-адреса tourID.
На этот раз все должно работать без сбоев. Данные незаметно передаются от одного приложения другому, и страница реагирует соответствующим образом благодаря простым операциям по пересылке и подготовке данных.
В этом уроке вы узнали о:
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.