От Web Presence до E-commerce (небольшой экскурс в историю)
Создание и подготовка базы данных
Структура нашего Интернет-магазина
Главная страничка — выбор типа заказа (файл index.asp)
Выбор типовой конфигурации компьютера (файл auto.asp)
Выбор дополнительного оборудования (equip.asp)
Подбор комплектующих (файл MainForm.asp)
Подтверждение заказа (файл MainformProc.asp)
Сбор данных о покупателе (файл EmailOrder.asp)
Oтправка заказа по e-mail (файл Done.asp)
В первых статьях серии «ASP на блюдечке» («ASP на блюдечке. Части 1, 2 и 3», ) мы ознакомились с ASP, с принципами построения простейшего интерфейса к базе данных с его помощью (газетный сайт со встроенными возможностями его пополнения новыми статьями, снабжаемыми фотографиями непосредственно с самого сайта и без программирования), основами использования ActiveX-компонентов в ASP, а также с азами разработки собственных компонентов с помощью известных всем Microsoft Visual Basic и Microsoft Visual C++ и возможностями, предоставляемыми ASP в поддержку программирования WAP-сайтов (создание собственной Wap-системы бронирования авиабилетов).
Вопреки данному в предыдущей статье настоящей серии анонсу двух только-только развивающихся технологий, о которых я собирался написать (ASP+ и ADO+), целый ряд пришедших от читателей писем подсказал гораздо более актуальную тему для настоящей статьи.
Итак, в настоящей статье я собираюсь последовательно и подробно рассмотреть собственную систему Интернет-торговли, или, проще говоря, Интернет-магазин.
Оглядываясь назад, в эпоху становления и развития торговли средствами Интернета, следует отметить, что поначалу Интернет-версии газет или магазинов могли позволить себе лишь очень немногие и весьма состоятельные компании. А все началось с небольших статичных сайтов (без какого бы то ни было интерактива), единственной целью которых являлось привести потенциальных покупателей в существующий физический магазин. Этот первый шаг, предпринятый для привлечения клиентов с помощью Интернета, впоследствии был озаглавлен теоретиками сайтостроительства как Web Presence, или «Веб-присутствие». Под «присутствием» тогда понимались лишь контактные телефоны, адрес, схема проезда и в лучшем случае электронный адрес.
Постепенно, с развитием систем управления базами данных и увеличением пропускных способностей каналов передачи, начали появляться периодически обновляемые Интернет-версии прайс-листов на товары или услуги компаний.
Как правило, под Интернет-магазином тогда понимали именно Интернет-интерпретацию реально существующего магазина, позволяющую просматривать прайс-листы этого магазина посредством Интернета. Так появились on-line-каталоги.
Далее последовали три серьезных шага, обеспечивших полноценное существование Интернет-магазинов как полностью самостоятельных организаций, а именно:
E-commerce открывает новые возможности для бизнеса с помощью Интернета благодаря большей оперативности Интернет-магазинов (реакции на мнения покупателей), отличающей их от физических аналогов, оданако Интернет-магазины пока еще несколько уступают по уровню демонстрации товаров или услуг. И хотя в последнее время получили широкое развитие Интернет-магазины, в которых можно в буквальном смысле слова покрутить товар во всевозможных плоскостях (благодаря средствам Macromedia Flash), пока, к сожалению, Интернет-магазины не могут помочь сомневающимся покупателям получить ответы на вопросы типа «а подойдет ли мне это?». Но все впереди, и за этим будущее E-commerce.
Предполагается, что читатель знаком с основами ASP- и SQL-программирования (первых трех частей настоящей статьи для этого будет вполне достаточно).
По сути дела, мы хотим организовать базу данных всего перечня товаров гипотетического магазина (выберем для этого магазин компьютеров и комплектующих), реализовать средства демонстрации товаров, позволить покупателю выбирать и добавлять товары в «корзину» и посылать заказ по электронной почте.
Но это еще не все. Давайте попытаемся несколько интеллектуализировать нашу систему, ведь не все покупатели точно знают, что именно хотят приобрести, да и многие товары таковы (например, бытовая техника или компьютеры), что во всех их параметрах обыватель разобраться не может — зачастую требуется консультация эксперта.
Попытаемся реализовать такого эксперта программно. Создадим несколько шаблонов типовых конфигураций персональных компьютеров, к примеру «Графическая станция», «Мультимедийный компьютер для дома с Интернет-возможностями», «Сервер баз данных» и т.д. Далее будем предлагать покупателям выбор наиболее подходящего шаблона, избавляя его тем самым от необходимости подбора комплектующих, в ходе которого им могут быть выбраны, например, два несовместимых устройства.
Ясное дело, что если шаблоны будут меняться достаточно часто и если их много, то процесс их подготовки необходимо автоматизировать (для этого проще всего написать небольшую программу — построитель шаблонов при помощи Borland C++ Builder).
Согласитесь, что предложенная задача весьма актуальна и с первого взгляда может показаться более сложной, чем на самом деле.
Для начала давайте представим себе процесс покупки компьютера и попытаемся формализовать его. Приведенная ниже последовательность шагов описывает этот процесс следующим образом:
Для некомпетентных покупателей:
Для компетентных покупателей:
Как видно, последовательность выполняемых действий по взаимодействию клиента с системой крайне проста, и в нашем случае каждый из перечисленных шагов будет представлен отдельным ASP-файлом.
Для создания базы данных (назовем ее Ishop) нам понадобится Microsoft Access 2000. От процесса проектирования базы данных будет зависеть дальнейший объем программной логики нашего приложения, поэтому этот этап крайне ответственен. И еще один совет: при проектировании Интернет-магазина стремитесь к тому, чтобы ваши странички содержали как можно меньше строк и констант, выведите все, что можно, за их пределы, вплоть до наименований позиций, так как последние могут меняться довольно часто. Иными словами, добейтесь от своего кода универсальности и независимости от данных. Однако, поскольку принципы проектирования баз данных выходят за рамки настоящей статьи, не будем задерживаться на них и представим структуру нашей базы данных так, как показано на рис. 1.
Создадим три управляющие таблицы для хранения информации о наименованиях всех
категорий и их соответствия таблицам с позициями, ценами и условиями гарантий
(таблицу _Components (рис. 2),

таблицы с перечнем дополнительных категорий (таблицу _Equipment (рис. 3)
для компетентных покупателей и таблицу _PCType (рис. 4) для некомпетентных
покупателей, желающих приобрести компьютер с определенной целью (к примеру, для
дома или для офиса).
Следует отметить, что поле IsPCComponent в таблице _Components, имеющее булево значение, позволяет определить, является ли данный компонент обязательным составляющим персонального компьютера или нет (это понадобится нам в дальнейшем).
Все остальные таблицы создадим по одному и тому же шаблону с наименованием позиции (поле Title), розничной ценой (поле Price1), мелкооптовой ценой (поле Price2) и крупнооптовой ценой (поле Price 3), а также с условиями гарантии на товар (поле Description) (рис. 5).

Как видите, таблица _PCType осуществляет взаимосвязь всех остальных таблиц и позволяет организовать системы предложения оптимальной конфигурации компьютера. Пример такой взаимосвязи представлен на рис. 6.

Итак, каждая строка таблицы _PCType содержит номера ключевых полей всех таблиц с позициями комплектующих.
Далее необходимо прописать нашу базу данных в соответствующем разделе источников данных системы, для этого:
Вы увидите появившуюся строку в списке источников данных в вашей системе (рис. 7)

Теперь, когда база данных готова, можно приступать к созданию самого Интернет-магазина.
Для того чтобы вам было легче понять дальнейшее изложение, давайте представим себе структуру нашего будущего Интернет-магазина, причем формы и действия при выборе конфигурации компьютера автоматически представим синим цветом, при выборе конфигурации самостоятельно — зеленым, при выборе дополнительного оборудования — сиреневым, а начало и конец алгоритма-схемы — красным (рис. 8):

Из схемы видно, что и при при автоматическом (по типовым шаблонам), и при самостоятельном подборе конфигурации загружается одна и та же форма MainForm.asp, однако если пользователь выбирал какую-нибудь типовую конфигурацию, то в последующей форме по умолчанию будут загружены позиции, соответствующие выбранной типовой конфигурации (из таблицы _PCtype), в противном случае — первые позиции (в которых рекомендуется написать «Выберите позицию»). При выборе раздела «Подбор дополнительного оборудования» загружается отдельная форма, но во всех остальных случаях ход дальнейшего «развития событий» одинаков: производится подтверждение заказа, сбор информации о покупателе и отправка заказа по электронной почте.
Уяснив структуру проектируемого приложения, можно приступать к написанию кода.
Для начала создадим страничку, в которой пользователь сможет выбрать один из трех режимов дальнейшего взаимодействия с сайтом, а именно: покупка компьютера с помощью эксперта, самостоятельный выбор или приобретение дополнительного оборудования.
<html> <head> <title>Виртуальный магазин </title> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> </head> <body bgcolor="#006767" text="#FFFFFF" link="#FFFF00" vlink="#FFFF00"> <div align="center"> <p>Добро пожаловать в наш виртуальный магазин </p> <p><a href="auto.asp">Подбор компьютера автоматически (с нашей помощью)</a></p> <p><a href="MainForm.asp?ID=2">Подбор компьютера самостоятельно</a></p> <p><a href="equip.asp">Покупка комплектующих</a></p> <p> </p> </div> </body> </html>
Как видите, пока все просто, и параметр ID, равный 2, передается в форму MainForm.asp, где будет свидетельствовать о том, что пользователь решил выбирать состав компьютера самостоятельно.
Теперь надлежит предложить пользователю выбор типовой конфигурации персонального компьютера (все данные берутся из таблицы _PCType).
<html>
<head>
<title>Виртуальный магазин </title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
</head>
<body bgcolor="#006767" text="#FFFFFF" link="#CCFFCC" vlink="#FFFF00">
<div align="center">
<p>Подбор компьютера автоматически (с нашей помощью)</p>
<p>Выберите шаблон конфигурации, максимально соответствующий вашим требованиям:</p>
<form method="POST" action="MainForm.asp?ID=1">
<select name="PCType" size="1">
<%
Set db = Server.CreateObject("ADODB.Connection")
db.Open "DSN=IShop;UID=sa;PWD=;"
SQLQuery = "Select * From _PCType ORDER BY PCType"
Set rs = db.Execute(SQLQuery)
Do While NOT Rs.EOF
Response.Write "<option value='" & rs.Fields("ID").value & _
"'>" & rs.Fields("PCType").value & "</option>"
Rs.MoveNext
Loop
‘ в качестве элементов списка загрузим элементы поля PCType
‘ таблицы _PCType базы данных Ishop в цикле
db.Close
Set db = Nothing
%>
</select>
<input type="submit" name="Submit" value=">>">
</form>
</div>
</body>
</html>
<html>
<head>
<title>Виртуальный магазин </title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
</head>
<body bgcolor="#006767" text="#FFFFFF" link="#CCFFCC" vlink="#FFFF00">
<div align="center">
<p>Покупка комплектующих</p>
<p>Выберите тип комплектующих</p>
<form method="get" action="EquipForm.asp">
<select name="select" size="1">
<%
Set db = Server.CreateObject("ADODB.Connection")
db.Open "DSN=IShop;UID=sa;PWD=;"
SQLQuery = "Select * From _Equipment ORDER BY Type"
Set rs = db.Execute(SQLQuery)
Do While NOT Rs.EOF
Response.Write "<option value='" & rs.Fields("ID").value & _
"'>" & rs.Fields("Type").value & "</option>"
Rs.MoveNext
Loop
‘ в качестве элементов списка загрузим элементы поля Type
‘ таблицы _Equipment базы данных IShop в цикле
db.Close
Set db = Nothing
%>
<input type="submit" name="Submit" value=">>">
</form>
</div>
</body>
</html>
Прежде чем приступить к выбору комплектующих, необходимо уяснить следующее. Дело в том, что нам предстоит организовать средство просмотра и выбора позиций, соответствующих именам таблиц из соответствующего поля таблицы _Components, где параметр IsPCComponent равен 1, с возможностью указания количества единиц комплектующих каждой категории и просмотра цены за единицу, и суммарной цены (за весь набор), причем в интерактивном режиме. Это означает, что, выбрав из списка ту или иную позицию, пользователь должен сразу же увидеть справа цену за ее единицу и обновленную цену за весь набор с учетом последнего изменения. То же самое должно происходить при изменении количества единиц каждой позиции.
Для технической реализации вышеизложенного визуально в пределах одной формы придется воспользоваться HTML-тэгом iframe, причем скрытым, а в нужных местах в телеформы использовать тэг SPAN, например, «<SPAN id=”Message1”></SPAN>», где в переменную Message1 с помощью JavaScript-функций будет загружаться требуемое знчение.
Для этого необходимо загрузить значения цены и ее извлечения, причем для каждой категории комплектующих, как, к примеру:
…
function OnLoadMess1()
{
Message1.innerText = FrmPrice.document.all.Message1.innerText;
// Загрузка в переменную Message1 текста из фрейма FrmPrice
}
…
function GetPrice1 ()
{
var content =”ifrsrc/ifrsrc1.asp?mess=” + document.forms.MainForm.elements.select1.value;
// Формирование строки — ссылки на скрипт, извлекающий значение цены данной позиции
// заданной категории комплектующих
FrmPrice1.document.URL=content;
// Передача управления (переход к) скрипту
OnLodTotalPrice();
// Пересчет суммарной стоимости всего набора
}
…
Сам же скрипт, извлекающий значение цены, выглядит, например, следующим образом:
<%@ Language=VBScript
<html>
<head>
<SCRIPT Language=JavaScript>
function OnLoad()
{
window.parent.OnLoadMess1();
}
</SCRIPT>
</head>
<body onload="OnLoad()">
<SPAN id=Message1>
<%
Set dbo = Server.CreateObject("ADODB.Connection")
dbo.Open "DSN=IShop;UID=sa;PWD=;"
' Получим значение, переданное в скрипт формой «MainForm.asp»
Title = Request.QueryString("mess")
' Выберем ту позицию из необходимой таблицы,
' где значение наименования позиции совпадает с переданным значением
SQLQuery = "Select * From SCSI WHERE Title = '" & Title & "'"
Set rso = dbo.Execute(SQLQuery)
Response.Write rso.Fields("Price1").value
dbo.Close
Set dbo = Nothing
</SPAN>
</body>
</html>
Как видно, скрипт содержит в себе единственную JavaScript-функцию, вызываемую при его загрузке и вызывающую соответствующую функцию скрипта родителя (то есть MainForm.asp) соответственно. Здесь важно понимать, что JavaScript-функция срабатывает у клиента, а не на сервере и, следовательно, в этот момент значение цены выбранной позиции (переданной скрипту в переменной mess) уже извлечено из соответствующей таблицы (в данном случае таблицы «SCSI») и выведено на экран. Ясно, что эти действия должны быть проделаны над всем множеством категорий и для каждой категории должен быть написан свой скрипт — загрузчик цены за единицу выбранной позиции.
Теперь настало время подготовить главную форму, в которой и будет осуществляться основная часть взаимодействия магазина с покупателем. Как было сказано выше, в эту форму передается вся «предыстория», по которой потенциальный покупатель «добрался» до нее. Напомним, что делается это посредством переменной ID, передаваемой форме в качестве параметра.
<html>
<head>
<title>Виртуальный магазин </title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<SCRIPT>
<%
Set db = Server.CreateObject("ADODB.Connection")
db.Open "DSN=IShop;UID=sa;PWD=;"
SQLQuery = "Select * From _Components WHERE IsPCComponent = 1" & _
" ORDER BY CategoryName ASC"
Set rs = db.Execute(SQLQuery)
CurrentCategory = 0
Do While NOT rs.EOF
CurrentCategory = CurrentCategory + 1
Response.Write "function OnLoadMess" & CurrentCategory & "(){"
Response.Write "Message" & CurrentCategory & ".innerText=FrmPrice" & CurrentCategory & _
".document.all.Message" & CurrentCategory & ".innerText;}"
Response.Write "function GetPrice" & CurrentCategory & "(){"
Response.Write "var content = 'ifrsrc/ifrsrc" & CurrentCategory &".asp?mess='" & _
"+document.forms.MainForm.elements.select" & CurrentCategory & ".value;"
Response.Write "FrmPrice" & CurrentCategory & ".document.URL=content;"
Response.Write "OnLodTotalPrice();}"
rs.MoveNext
Loop
db.Close
Set db = Nothing
%>
function OnLodTotalPrice() // Вычисление суммарной цены
{
var Total;
Total = 0;
// Вычисление суммарной цены производится суммированием
// всех цен, умноженных на количество выбранных единиц каждой позиции соответственно
Total = Total + parseInt(Message1.innerText) * (document.forms.MainForm.elements.quant1.value);
Total = Total + parseInt(Message2.innerText) * (document.forms.MainForm.elements.quant2.value);
Total = Total + parseInt(Message3.innerText) * (document.forms.MainForm.elements.quant3.value);
Total = Total + parseInt(Message4.innerText) * (document.forms.MainForm.elements.quant4.value);
Total = Total + parseInt(Message5.innerText) * (document.forms.MainForm.elements.quant5.value);
Total = Total + parseInt(Message6.innerText) * (document.forms.MainForm.elements.quant6.value);
Total = Total + parseInt(Message7.innerText) * (document.forms.MainForm.elements.quant7.value);
Total = Total + parseInt(Message8.innerText) * (document.forms.MainForm.elements.quant8.value);
Total = Total + parseInt(Message9.innerText) * (document.forms.MainForm.elements.quant9.value);
Total = Total + parseInt(Message10.innerText) * (document.forms.MainForm.elements.quant10.value);
Total = Total + parseInt(Message11.innerText) * (document.forms.MainForm.elements.quant11.value);
Total = Total + parseInt(Message12.innerText) * (document.forms.MainForm.elements.quant12.value);
Total = Total + parseInt(Message13.innerText) * (document.forms.MainForm.elements.quant13.value);
Total = Total + parseInt(Message14.innerText) * (document.forms.MainForm.elements.quant14.value);
Total = Total + parseInt(Message15.innerText) * (document.forms.MainForm.elements.quant15.value);
TMessage.innerText = String(Total);
}
function Set() // Установка значений по умолчанию при загрузке страницы
{
GetPrice1(); GetPrice2(); GetPrice3(); GetPrice4(); GetPrice5();
GetPrice6(); GetPrice7(); GetPrice8(); GetPrice9(); GetPrice10();
GetPrice11(); GetPrice12(); GetPrice13(); GetPrice14(); GetPrice15();
SetQuantity();
OnLodTotalPrice();
}
function SetQuantity() // Реакция на изменение селекторов количества
{
TotalPrice.document.URL = "tprice.asp?mess=aaa";
}
</SCRIPT>
</head>
<body bgcolor="#006767" text="#FFFFFF" link="#FFFF00" vlink="#FFFF00" onLoad="Set();">
<div align="center">
<%
'Соединяемся с базой данных «Ishop»
Set db = Server.CreateObject("ADODB.Connection")
db.Open "DSN=IShop;UID=sa;PWD=;"
TheID = Request.QueryString("ID")
If TheID = 1 Then
Response.Write "<p>Подбор компьютера автоматически (с нашей помощью)</p>"
PCType = Request.Form("PCType")
ASQLQery = "Select * From _PCType WHERE ID = " & PCType
Set result = db.Execute(ASQLQery)
'Инициализация переменных, которые будут загружены
' в списки выбора по умолчанию (извлекаются из предыдущей формы)
' в случае автоматического подбора конфигурации
CPUID = result.Fields("CPUID")
MainBoardId = result.Fields("MainBoardId")
SVGAID = result.Fields("SVGAID")
HDDID = result.Fields("HDDID")
FDDID = result.Fields("FDDID")
CdromID = result.Fields("CdromID")
SoundID = result.Fields("SoundID")
ModemID = result.Fields("ModemID")
KeybordID = result.Fields("KeyboardID")
MouseID = result.Fields("MouseID")
MonitorID = result.Fields("MonitorID")
PadID = result.Fields("PadID")
SCSIID = result.Fields("SCSIID")
SpeakerID = result.Fields("SpeakerID")
D = Date()
D = FormatDateTime(D,2)
str = "<p>Рекомендуемая конфигурация компьютера типа <br>''"
str = str & result.Fields("PCType").value & "''"
str = str & " по состоянию на: " & D & "</p>"
Response.Write str
result.Close
Set result = Nothing
Else
Response.Write "<p>Подбор компьютера самостоятельно</p>"
'Инициализация переменных, которые будут загружены
' в списки выбора по умолчанию (извлекаются из предыдущей формы)
' в случае самостоятельного подбора конфигурации
CPUID = 1
MainBoardId = 1
SVGAID = 1
HDDID = 1
FDDID = 1
CdromID = 1
SoundID = 1
ModemID = 1
KeybordID = 1
MouseID = 1
MonitorID = 1
PadID = 1
SCSIID = 1
SpeakerID = 1
End If
%>
<form method="get" name= "MainForm" action="MainFormProc.asp">
<table width="457" border="2" cellspacing="0" cellpadding="0">
<tr>
<td width="223"><b>Наименование позиции</b></td>
<td width="80"><b>Позиция</b></td>
<td width="97"><b>Количество</b></td>
<td width="63"><b>Цена</b></td>
</tr>
<%
' Формируем SQL-запрос — все категории, являющиеся обязательными
' компонентами персонального компьютера, упорядоченные по алфавиту
SQLQuery = "Select * From _Components WHERE IsPCComponent = 1 ORDER BY CategoryName ASC"
Set rs = db.Execute(SQLQuery)
CurrentCategory = 0
TotalPrice = 0
' В цикле по всем категориям
Do While NOT rs.EOF
CurrentCategory = CurrentCategory + 1 ' счетчик категорий
Response.Write "<tr><td>"
Response.Write "" & rs.Fields("CategoryName").value & ": "
Response.Write "</td><td>"
' Создаем селектор «select#»
' и определяем функцию-реакцию на его изменение «GetPrice#»
' где # — значение счетчика категорий для каждой категории
Response.Write "<select id=" & "'select" & CurrentCategory & "' name='select" & CurrentCategory & _
"' onchange='GetPrice" & CurrentCategory & "()'"
Response.Write " style='WIDTH: 400px'>"
CurTableName = rs.Fields("CategoryTableName").value
' Зафиксируем имя текущей таблицы — переменная «CurTableName»
' Определим, какая позиция должна быть сделана активной (по умолчанию)
If CurTableName = "CPU" Then
CurTemplateSelectID = CPUID
End If
If CurTableName = "Mainboard" Then
CurTemplateSelectID = MainboardID
End If
If CurTableName = "SVGA" Then
CurTemplateSelectID = SVGAID
End If
If CurTableName = "HDD" Then
CurTemplateSelectID = HDDID
End If
If CurTableName = "FDD" Then
CurTemplateSelectID = FDDID
End If
If CurTableName = "Cdrom" Then
CurTemplateSelectID = CdromID
End If
If CurTableName = "Sound" Then
CurTemplateSelectID = SoundID
End If
If CurTableName = "Modem" Then
CurTemplateSelectID = ModemID
End If
If CurTableName = "Keyboard" Then
CurTemplateSelectID = KeyboardID
End If
If CurTableName = "Mouse" Then
CurTemplateSelectID = MouseID
End If
If CurTableName = "Monitor" Then
CurTemplateSelectID = MonitorID
End If
If CurTableName = "Pad" Then
CurTemplateSelectID = PadID
End If
If CurTableName = "SCSI" Then
CurTemplateSelectID = SCSIID
End If
If CurTableName = "Speaker" Then
CurTemplateSelectID = SpeakerID
End If
' Создадим список позиций для каждой категории, упорядоченный по алфавиту
' Извлечение будем производить из текущей таблицы — переменная «CurTableName»
ISQLQuery = "Select * From " & CStr (CurTableName) & " ORDER BY Title ASC"
Response.Write ISQLQuery
Set res = db.Execute(ISQLQuery)
CurrentItem = 0
Do While NOT res.EOF
CurrentItem = CurrentItem + 1
' Заполним в цикле каждый селектор значениями позиций из соответствующей таблицы
str = "<option"
' Если текущая позиция должна быть позицией по умолчанию — сделаем это
If CurrentItem = CurTemplateSelectID Then
str = str & " selected"
TemplatePriceValue = res.Fields("Price1").value
End If
str = str & " value='" & res.Fields("Title").value & _
"'>" & res.Fields("Title").value & "</option>"
Response.Write str
res.MoveNext
Loop
Response.Write "</select>"
res.Close
Set res = Nothing
Response.Write "</td><td>"
' Реализуем селектор количества и заполним его числами от 1 до 50
' При изменении будет вызываться функция «SetQuantity()»
Response.Write "<select id='quant" & CurrentCategory & "' name='quant" & CurrentCategory & _
"' style='WIDTH: 50px' OnChange = 'SetQuantity()'>"
I = 1
Do While I <> 50
Response.Write "<option value = " & I & ">" & I & "</option>"
I = I + 1
Loop
Response.Write "</select>"
' Определим невидимый фрейм типа «Iframe» с именем «FrmPrice#» для вычисления значений цен
' где # — значение счетчика категорий для каждой категории
Response.Write "</td><td><IFRAME id='FrmPrice" & CurrentCategory & _
"' style='WIDTH: 80px' style='HEIGHT: 40px' style='display: none' name='FrmPrice" & CurrentCategory & _
"'></IFRAME>"
Response.Write "<SPAN id='Message" & CurrentCategory &"'></SPAN></td></tr>"
' Определим скрытое поле для передачи значений цен
' в последующие скрипты
Response.Write "<input type='hidden' name='price" & CurrentCategory & "' value='" & TemplatePriceValue &
"'>"
Rs.MoveNex
' Суммируем цены для вычисления цены за весь набор
TotalPrice = TotalPrice + TemplatePriceValue
Loop
db.Close
Set db = Nothing
Response.Write "<tr><td><b><i>Итого:</b></i></td><td> — </td><td> — </td>"
Response.Write "<td><b><i>"
' Определим невидимый фрейм типа «Iframe» с именем «TotalPrice» для вычисления суммы цен
Response.Write "<IFRAME id='TotalPrice' style='WIDTH: 80px' style='HEIGHT: 40px" & _
"' style='display: none' name='TotalPrice'></IFRAME>"
Response.Write "<SPAN id='TMessage'></SPAN></b></i></td></tr>"
%>
</table>
<p>
<input type="submit" name="Submit" value="Продолжить">
<input type="reset" name="Reset" value="Очистить форму">
</p>
</form>
</div>
</body>
</html>
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> </head> <body bgcolor="#006767" text="#FFFFFF" link="#FFFF00" vlink="#FFFF00"> <div align="center"> <form method="get" action="EmailOrder.asp"> <p>Вы заказываете:</p> <table width="457" border="2" cellspacing="0" cellpadding="0"> <tr> <td width="25"><b>#</b></td> <td width="350"><b>Позиция</b></td> <td width="25"><b>Количество</b></td> <td width="40"><b>Цена</b></td> </tr> <% I = 1 Do While I <= 15 Response.Write "<tr><td>" & CStr(I) ' Прочитаем в цикле значения селекторов «select#» ' и сгенерируем скрытые элементы формы ' для передачи выбранных значений в последующие скрипты Str = "select" Str = Str & CStr(I) Res = Request.QueryString(Str) Response.Write "</td><td>" & Res Response.Write "<input type='hidden' name='" & Str & "' value='" & Res & "'>" ' Прочитаем в цикле значения селекторов «quant#» ' и сгенерируем скрытые элементы формы ' для передачи выбранных значений в последующие скрипты Str = "quant" Str = Str & CStr(I) Res = Request.QueryString(Str) Response.Write "</td><td>" & Res Response.Write "<input type='hidden' name='" & Str & "' value='" & Res & "'>" ' Прочитаем в цикле значения скрытых полей «pricet#» ' и сгенерируем скрытые элементы формы ' для передачи выбранных значений в последующие скрипты Str = "price" Str = Str & CStr(I) Res = Request.QueryString(Str) Response.Write "</td><td>" & Res Response.Write "<input type='hidden' name='" & Str & "' value='" & Res & "'>" Response.Write "</td></tr>" I = I + 1 Loop </table> <br> <input type="submit" name="Submit" value="Заказать"> <input type="reset" name="Reset" value="Очистить форму"> </form> </div> </body> </html>
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> </head> <body bgcolor="#006767" text="#FFFFFF" link="#FFFF00" vlink="#FFFF00"> <div align="center"> <p>Отправка заказа по электронной почте:</p> <p>Как с вами связаться</p> <Form Method="get" Action = "Done.asp"> <table> <tr> <td>Ваше имя:</td> <td><Input Type="text" Name="Name" Size="30"></Input></td> </tr> <tr> <td>Ваш телефон:</td> <td><Input Type="text" Name="Phone" Size="30"></Input></td> </tr> <tr> <td>Ваш адрес:</td> <td><Input Type="text" Name="Address" Size="30"></Input></td> </tr> <tr> <td>Ваш электронный адрес:</td> <td><Input Type="text" Name="Email" Size="30"></Input></td> </tr> <tr> <td>Ваш UIN:</td> <td><Input Type="text" Name="UIN" Size="30"></Input></td> </tr> <tr> <td align = center><Input Type="submit" Value="Отправить заказ"></Input></td> </tr> </table> <% I = 1 Do While I <= 15 ' Прочитаем в цикле значения скрытых полей «select#» ' и сгенерируем скрытые элементы формы ' для передачи выбранных значений в последующие скрипты Str = "select" Str = Str & CStr(I) Res = Request.QueryString(Str) Response.Write "<input type='hidden' name='" & Str & "' value='" & Res & "'>" ' Прочитаем в цикле значения скрытых полей «quant#» ' и сгенерируем скрытые элементы формы ' для передачи выбранных значений в последующие скрипты Str = " quant" Str = Str & CStr(I) Res = Request.QueryString(Str) Response.Write "<input type='hidden' name='" & Str & "' value='" & Res & "'>" ' Прочитаем в цикле значения скрытых полей «price#» ' и сгенерируем скрытые элементы формы ' для передачи выбранных значений в последующие скрипты Str = "price" Str = Str & CStr(I) Res = Request.QueryString(Str) Response.Write "<input type='hidden' name='" & Str & "' value='" & Res & "'>" I = I + 1 Loop %> </Form> <br> </div> </body> </html>
После того как все действия выполнены успешно, необходимо сформировать электронное письмо, которое должно быть послано в подтверждение выполненного заказа гипотетическому менеджеру по продажам или доставке нашего виртуального магазина и самому пользователю одновременно. Для этого воспользуемся бесплатно поставляемым ActiveX-компонентом ASP E-mail 4.4 компании Persist Software, Inc..
<html>
<head>
<title>Виртуальный магазин </title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
</head>
<body bgcolor="#006767" text="#FFFFFF" link="#FFFF00" vlink="#FFFF00">
<%
' Запросим значения, введенные пользователем
Name = Request.QueryString("Name")
Phone = Request.QueryString("Phone")
Address = Request.QueryString("Address")
Email = Request.QueryString("Email")
UIN = Request.QueryString("UIN")
' Создадим экземпляр объекта «Persits.MailSender»
Set Mail = Server.CreateObject("Persits.MailSender")
Mail.Host = "mail.compress.ru" 'Адрес SMTP сервера
Mail.From = rouben@iname.com ' Адрес «от кого»
Mail.FromName = "Rouben Sadoyan" 'Имя «от кого»
Mail.AddAddress "rouben@grcom.ru", "Rouben E. Sadoyan" ' Адрес и имя кому
Mail.AddAddress Email, Name ' Адрес и имя кому
Mail.IsHTML = True ' Посылка почты в формате HTML
Mail.Subject = "PC Order!" ' Поле Subject
' Формируем HTML-документ — тело нашего письма
Body = "<HTML><HEAD>"
Body = Body & "<meta http-equiv='Content-Type' content='text/html; charset=windows-1251'>"
Body = Body & "</HEAD><BODY>"
Body = Body & "Уважаемый " & Name & "!<br><br>"
Body = Body & "*************************************************<br>"
Body = Body & "Имя: " & Name & "<br>"
Body = Body & "Телефон: " & Phone & "<br>"
Body = Body & "Адрес: " & Address & "<br>"
Body = Body & "E-mail: " & Email & "<br>"
Body = Body & "UIN: " & UIN & "<br>"
Body = Body & "*************************************************" & "<br>"
Body = Body & "Вы заказали: " & "<br>"
I = 1
Do While I <= 15
Body = Body & I & ". "
Str = "select"
Str = Str & CStr(I)
Res = Request.QueryString(Str)
Body = Body & Res & " — "
Str = "quant"
Str = Str & CStr(I)
Res = Request.QueryString(Str)
Body = Body & Res & " — "
Str = "price"
Str = Str & CStr(I)
Res = Request.QueryString(Str)
Body = Body & Res & "<br>"
I = I + 1
Loop
Body = Body & "*************************************************" & "<br>"
Body = Body & "Наши менеджеры свяжутся с вами в ближайшее время по оставленным вами координатам."
Body = Body & "<br>С наилучшими пожеланиями<br>"
Body = Body & "<br>Сервер 'Виртуального магазина'"
Body = Body & "</BODY></HTML>"
Mail.Body = Body
'Response.Write Mail.Body
' Попытаемся послать наше письмо
On Error Resume Next
Mail.Send
If Err <> 0 Then
Response.Write "Ошибка передачи: " & Err.Description
End If
Response.Write "<center>Уважаемый " & Name & "!<br>"
Response.Write "Ваш заказ был успешно отправлен на сервер виртуального магазина.<br>"
Response.Write "Спасибо!</center>"
%>
</body>
</html>
Мир Интернет-магазинов огромен. Но несмотря на такое разнообразие, их подавляющее большинство представлены структурной схемой, изложенной в настоящей статье. Конечно, некоторые из них умеют принимать оплату с помощью кредитных карточек, но сути дела это не меняет, каждый Интернет-магазин представляет информацию, позволяет «набрать корзину», заказать, а иногда и оплатить товар. Имеются разные варианты и с доставкой. Прежде чем приступать к созданию своего собственного Интернет-магазина, советую для начала «побродить» по чужим. И еще очень многое зависит от работы дизайнеров. С одной стороны, такое утверждение может показаться дилетантским, дескать, а где это от работы дизайнеров мало что зависит, но поверьте, в данном случае особенно важно, чтобы покупатель чувствовал себя уютно и в привычной обстановке. Для каждой конкретной категории товара должен быть создан соответствующий дизайн, подходящий к конкретному товару и конкретному покупателю.
Полный архив исходных скриптов и базы данных к настоящей статье лежит здесь.