<% ASP на блюдечке %>.
Выбор аэропорта назначения (index.asp)
Для облегчения организации программного доступа к нашей базе данных, вынесем его в отдельный ASP-скрипт и будем «включать» его в тело каждого из последующих скриптов по мере необходимости:
<%
Option explicit
Dim conn
Set conn = Server.CreateObject("ADODB.Connection")
conn.open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" & Server.Mappath("AirTickets.mdb") & ";"
%>
Соединение с базой данных выполним наиболее простым и компактным образом (не забудьте разместить файл базы данных "AirTickets.mdb" в корневом каталоге сайта, так как Server.Mappath будет возвращать именно этот путь).
Теперь можно приступить к опросу нашего клиента. Согласитесь, что для начала неплохо было бы его поприветствовать:
… <card id="splash" ontimer="#card1" title="Welcome to"> <timer value="20"/> <p align="center"><br /> <img src="logo.wbmp" alt="WAP AirLines"/> </p> </card> …
Данная карта и будет приветствовать наших клиентов, показывая заставку из файла logo.wbmp, а если ей это не удастся, то заменит иллюстрацию альтернативной надписью "WAP AirLines", поле чего (по истечении двух секунд) будет загружаться карта «card1» палубы:
…
<card id="card1" title="Flight to:">
<%
SQLquery = "SELECT * FROM Destinations" ‘ Выборка всех строк таблицы Destinations
set rsDestinations = conn.Execute(SQLquery)
if rsDestinations.eof then ‘ Если таблица не содержит ни одной
rsDestinations.close ‘ строки
set rsDestinations = nothing ‘ то закрыть соединение с базой данных
Response.write("<p>Sorry, this flight is not available now!")
Response.write("<br /><anchor title='") ‘ и выдать сообщение о невозможности
Response.write("ReStart'") ‘бронирования авиабилетов
Response.write(">Go Home to Restart-><go href='")
Response.write("index.asp'")
Response.write("/></anchor>")
Response.write("</p></card></wml>")
Response.end
end if
%>
<p><br />
<select name='TheCity'>
<%
Do while not rsDestinations.eof
‘В цикле отобразить в качестве элементов списка все аэропорты назначения
response.write("<option value='" & rsDestinations("CityID") & "'>" & rsDestinations("City") & "</option>" & vbcrlf)
rsDestinations.MoveNext
Loop
%>
</select>
<anchor title="Proceed!">Proceed->
<go href="Date.asp" method="get"> <!-- Обеспечить переход к следующему этапу опроса —- >
<postfield name="TheCity" value="$(TheCity)" /> <!—Передав идентификатор выбранного пользователем города из списка-- >
</go>
</anchor>
</p>
<%
rsDestinations.close
set rsDestinations = nothing
%>
</card>
…
Как видите, WML-страница формируется из базы данных в основном посредством ASP-метода response.write, отображающего список городов (значение полей rsDestinations("City") таблицы). Заметьте, что в качестве возвращаемого значения списка выбора select фигурирует значение именно ключевого поля первой таблицы — rsDestinations("CityID").
Далее выбранное пользователем значение передается в следующий скрипт (Date.asp) с помощью якоря Proceed.
Выбор даты и времени вылета (Dates.asp)
Скрипт Date.asp, в свою очередь, организует список из всех возможных значений дат и времени вылета рейсов, соответствующий значению выбранного города на основании полученного значения.
Для этого в первую очередь необходимо считать значение, введенное пользователем на предыдущем этапе:
<%
…
City = Request("TheCity")
…
%>
Затем считать из первой таблицы название выбранного города в переменную, с тем чтобы показать его клиенту в дальнейшем:
<%
…
SQLQuery = "SELECT * FROM Destinations WHERE CityID = " & Request("TheCity")
set rsCity = conn.Execute(SQLQuery)
Set CityName = rsCity("City")
…
%>
После этого необходимо считать из второй таблицы все соответствующие значения и сформировать список из них:
<%
…
SQLQuery = "SELECT * FROM Dates WHERE CityID = " & Request("TheCity")
set rsDates = conn.Execute(SQLQuery)
…
%>
Аналогично предыдущему случаю здесь и во всех последующих скриптах следует подумать о возможном отсутствии значений в таблице:
<%
…
if rsDates.eof then
rsDates.close
set rsDates = nothing
Response.write("<p>Sorry, this flight is not available now!")
Response.write("<br /><anchor title='")
Response.write("ReStart'")
Response.write(">Go Home to Restart-><go href='")
Response.write("index.asp'")
Response.write("/></anchor>")
Response.write("</p></card></wml>")
Response.end
end if
…
%>
Теперь покажем клиенту название города, который он выбрал, и предоставим ему возможность выбрать дату и время вылета:
<p><br />Flight to:<%=CityName%>
<br />At:
<select name='DateTime'>
<%
Do while not rsDates.eof
response.write("<option value='" & rsDates("DatesID") & "'>" & rsDates("FlightDate") & ", "
& rsDates("FlightTime") & "</option>" & vbcrlf)
rsDates.MoveNext
Loop
%>
</select>
Как видно, поля списка формируются из сочетаний дат и времени полей второй таблицы. Здесь, так же как и в первом случае, фигурирует значение ключевого поля таблицы «Dates»:
rsDates("DatesID").
Передадим в следующий скрипт (Flight.asp) два значения: название города назначения и ключевое значение, соответствующее выбранному пользователем значению времени вместе с датой во второй таблице:
<anchor title="Proceed!">Proceed-> <go href="Flight.asp" method="get"> <postfield name="City" value="<%=CityName%>" /> <postfield name="DateTime" value="$(DateTime)" /> </go> </anchor>
Покажем надпись перехода к предыдущему экрану с помощью следующего элемента:
<do type="prev" label="Previous"> <prev/> </do>
Выбор атрибутов рейса (Flight.asp)
Теперь пришло время выяснить, имеются ли билеты на выбранный клиентом рейс. Конечно, данный момент — не самый удачный для этого (по-хорошему это необходимо делать на каждом этапе регистрации выбранных пользователем значений, что потребует ввода полей с количеством оставшихся билетов во все таблицы), но для лучшего усвоения материала настоящей статьи мы не будем загромождать наши скрипты дополнительными проверками, а таблицы — дополнительными полями.
Получим значения, переданные предыдущим скриптом, и считаем их:
…
<%
…
Dim TheDateTime
Set TheCity = Request("City")
Set TheDateTime = Request("DateTime")
…
%>
Выберем из таблицы дат и времени рейсов значение, соответствующее номеру выбранного пользователем поля, и считаем в переменные соответствующие значения даты и времени:
…
<%
SQLQuery = "SELECT * FROM Dates WHERE DatesID = " & Request("DateTime")
set rsDateTime = conn.Execute(SQLQuery)
Set FDate = rsDateTime("FlightDate")
Set FTime = rsDateTime("FlightTime")
…
%>
Теперь из третьей таблицы выберем строки, соответствующее значениям времени и дате, выбранным клиентом на предыдущем этапе:
…
<%
SQLQuery = "SELECT * FROM Flights WHERE TimesID = " & Request("DateTime")
set rsFlights = conn.Execute(SQLQuery)
…
%>
Покажем пользователю выбранные им значения и огранизуем список выбора класса и цены авиабилетов:
…
<p><br />Flight to:<%=TheCity%>
<br />At: <%=FDate%>, <%=FTime%><br />
<select name='FlightID'>
<%
Do while not rsFlights.eof
response.write("<option value='" & rsFlights("FlightsID")+900 & "'>" & "A-" & rsFlights("Company") & "-" & rsFlights("Price2") & "USD" & "</option>" & vbcrlf)
response.write("<option value='" & rsFlights("FlightsID") & "'>" & "B-" & rsFlights("Company") & "-" & rsFlights("Price1") & "USD" & "</option>" & vbcrlf)
rsFlights.MoveNext
Loop
%>
</select>
Элементы списка формируются из аббревиатуры названия авиакомпании rsFlights("Company"), цен билетов rsFlights("Price1") и rsFlights("Price2") для и первого второго классов соответственно. Однако здесь имеется один нюанс: поскольку здесь, как и в предыдущих случаях, значение, введенное пользователем, определяется по номеру строки в таблице, то невозможно определить, какое из двух значений класса и цены билета выбрал пользователь — эти значения являются элементами одной и той же строки. Во избежание этого будем прибавлять заведомо большое число к значению, введенному пользователем в том случае, если был выбран билет класса «A». Например, 900.
И наконец, передадим в последний скрипт проверки подтверждения все ранее введенные пользователем значения:
<anchor title="Proceed!">Proceed-> <go href="Order.asp" method="get"> <postfield name="City" value="<%=TheCity%>" /> <postfield name="Date" value="<%=FDate%>" /> <postfield name="Time" value="<%=FTime%>" /> <postfield name="FlightID" value="$(FlightID)" /> </go> </anchor> …
Подтверждение бронирования (Order.asp)
Покажем пользователю все значения, которые он выбрал, и попросим подтверждения на размещение брони:
Прочитаем значения, переданные скрипту в переменные:
<%
…
Set TheCity = Request("City")
Set TheDate = Request("Date")
Set TheTime = Request("Time")
Set TheFlight = Request("FlightID")
…
%>
Если значение номера строки в таблице атрибутов рейса (третья таблица) больше 900, то от значения следует отнять 900, чтобы получить реальное значение номера выбранной пользователем строки, что, собственно, и означает, что пользователем был выбран билет класса «А».
<% … If TheFlight > 900 Then TheFlight = TheFlight — 900 TheClass = "A" Else TheClass = "B" End If … %>
Выберем те строки из таблицы с атрибутами рейсов, значение поля числа оставшихся билетов которых не отрицательно и идентификационный номер которых соответствует номеру, переданному предыдущим скриптом, затем считаем соответствующие значения (номер рейса, тип воздушного судна, аббревиатура названия авиакомпании, цена) в переменные:
<%
…
SQLQuery = "SELECT * FROM Flights WHERE Tickets > 0 AND FlightsID = " & TheFlight
Set rsFlights = conn.Execute(SQLQuery)
…
Set FNum = rsFlights("FlightNo")
Set PType = rsFlights("PlaneType")
Set Comp = rsFlights("Company")
If TheClass = "A" Then
Set Price = rsFlights("Price2")
Else
Set Price = rsFlights("Price1")
End If
%>
Отобразим полученные значения, запросим имя клиента для последующего внесения в базу данных и передадим их последнему скрипту — скрипту регистрации заказа в системе:
<p> Flight No:<%=FNum%> <br /> To: <%=TheCity%> <br /> At: <%=TheDate%>, <%=TheTime%> <br /> Company: <%=Comp%> <br /> On plane: <%=PType%> <br /> Ticket class: <%=TheClass%> <br /> Ticket price: <%=Price%> USD <br /> …
Запрос ввода имени имеет два ограничения:
имя не может быть пустым, максимальная длина имени — 10 символов.
… Your name (*): <br/> <input name="username" emptyok="false" maxlength="10" /> <anchor title="Order">Order Now!-> <go href="Update.asp" method="get"> <postfield name="City" value="<% =TheCity%>" /> <postfield name="Date" value="<% =TheDate%>" /> <postfield name="Time" value="<% =TheTime%>" /> <postfield name="FNum" value="<% =FNum%>" /> <postfield name="Class" value="<% =TheClass%>" /> <postfield name="PType" value="<% =PType%>" /> <postfield name="Comp" value="<% =Comp%>" /> <postfield name="FID" value="<% =TheFlight%>" /> <postfield name="Price" value="<% =Price%>" /> <postfield name="UserName" value="$(username)" /> </go> </anchor> <do type="prev" label="Back"> <prev/> </do> </p>
Регистрация заказа в системе и выдача клиенту идентификатора (Register.asp)
Наконец можно зарегистрировать бронь клиента в базе данных. Для этого создадим таблицу (назовем ее Orders), в которую будем записывать заказы клиентов.
Теперь считаем значения всех переданных параметров в переменные:
<card id="card1" title="Order Complete:">
<%
Dim SQLUpdate, SQLInsert, SQLQuery, rsOrders
Dim TheFlight, TheCity, TheDate, TheTime, FNum, PType, Comp, TheClass, Price, RegCode, UName
Set TheCity = Request("City")
Set TheDate = Request("Date")
Set TheTime = Request("Time")
Set FNum = Request("FNum")
Set TheClass = Request("Class")
Set PType = Request("PType")
Set Comp = Request("Comp")
Set TheFlight = Request("FID")
Set Price = Request("Price")
Set UName = Request("UserName")
…
%>
Проверим, ввел ли клиент свое имя; если нет, то выдадим предупреждение и перенаправим его в предыдущий скрипт.
<%
…
If UName = "" Then
Response.write("<p>You didn't enter your name!")
Response.write("<br />Press 'Back' and enter it, please.<do type='")
Response.write("prev'")
Response.write(" label='")
Response.write("Back'")
Response.write("><prev/>")
Response.write("</do></p></card></wml>")
Response.end
Else
…
%>
Обновим значение числа оставшихся билетов в таблице атрибутов рейсов, а именно — уменьшим это значение на 1:
<% … SQLUpdate = "UPDATE Flights SET Tickets = Tickets — 1 WHERE FlightsID =" & TheFlight conn.Execute(SQLUpdate) … %>
И добавим новую строку к таблице заказов (Orders):
<%
…
SQLInsert = "INSERT INTO Orders (City, FlightDate, FlightTime, FlightNo, TicketClass,
TicketPrice, PlaneType, Company , UserName )
VALUES ('" & TheCity & "', '" & TheDate & "', '" & TheTime & "',
'" & FNum & "', '" & TheClass & "', '" & Price & "',
'" & PType & "', '" & Comp & "', '" & UName & "')"
conn.Execute(SQLInsert)
…
%>
Выберем из таблицы заказов самый последний элемент (упорядочивание по убыванию значений столбца-счетчика OrderID позволит нам получить указатель на все элементы таблицы, самое первое значение которого укажет на строку, введенную в самую последнюю очередь, то есть введенную только что):
<%
…
SQLQuery = "SELECT * FROM Orders ORDER BY OrderID DESC"
Set rsOrders = conn.Execute(SQLQuery)
Set RegCode = rsOrders("OrderID")
End If
%>
Покажем пользователю его регистрационный код:
… <p> Thank you, <%=UName%> <br /> Your reg. Id: <%=RegCode%> <br /> <do type="prev" label="Previous"> <prev/> </do> <anchor title="Home">Home <go href="index.asp" /> </anchor> …
И предложим перейти к началу:
… </p> <% rsOrders.close set rsOrders = nothing %> </card>
Заключение
В заключение хотелось бы сориентировать разработчиков WAP-приложений и сайтов в Интернете. Дело в том, что автор настоящей статьи провел не один день за Интернетом в поисках всевозможных WAP-сайтов и советует, в частности, посетить:
Много полезных ресурсов (книги, справочная информация, часто задаваемые вопросы, ссылки, статьи …) — http://www.wap-resources.net/
- Сайт поддержки разработчиков компании Ericsson — http://www.ericsson.se/developerszone/index.asp
- Сайт-форум компании Nokia для разработчиков — http://www.forum.nokia.com/main.html
- WAP-новости, дискусcии, программное обеспечение, обучение, справочные материалы — http://www.wirelessdevnet.com
- Сайт знаменит серией довольно популярных online-учебников:
- Один из самых крупных WAP-форумов для разработчиков — http://www.wapforum.org/
- Новостной сайт по WAP — http://wap.net/
- Много теоретических основ WAP — http://www.gsmworld.com/technology/wap.html
- Wap Development Toolkit компании DSR — http://www.wap.net/devkit/
- Полезная вводная лекция по WAP — http://www.iec.org/tutorials/wap/
- Книга знаменитого издательства O’Reilly «Learning WML & WMLScript» — http://www.oreilly.com/catalog/learnwml/
- Online-версия третей главы книги — http://www.oreilly.com/catalog/learnwml/chapter/ch03.html
КомпьютерПресс 11'2000








