Статьи - ASP на блюдечке. Часть 4. Виртуальный магазин
ASP на блюдечке. Часть 4. Виртуальный магазин
Введение
В первых статьях серии "ASP на блюдечке" мы ознакомились с ASP, с принципами построения простейшего интерфейса к базе данных с его помощью (газетный сайт со встроенными возможностями его пополнения новыми статьями, снабжаемыми фотографиями непосредственно с самого сайта и без программирования), основами использования ActiveX-компонентов в ASP, а также с азами разработки собственных компонентов с помощью известных всем Microsoft Visual Basic и Microsoft Visual C++ и возможностями, предоставляемыми ASP в поддержку программирования WAP-сайтов (создание собственной Wap-системы бронирования авиабилетов).
Вопреки данному в предыдущей статье настоящей серии анонсу двух только-только развивающихся технологий, о которых я собирался написать (ASP+ и ADO+), целый ряд пришедших от читателей писем подсказал гораздо более актуальную тему для настоящей статьи.
Итак, в настоящей статье я собираюсь последовательно и подробно рассмотреть собственную систему Интернет-торговли, или, проще говоря, Интернет-магазин.
От Web Presence до E-commerce (небольшой экскурс в историю)
Оглядываясь назад, в эпоху становления и развития торговли средствами Интернета, следует отметить, что поначалу Интернет-версии газет или магазинов могли позволить себе лишь очень немногие и весьма состоятельные компании. А все началось с небольших статичных сайтов (без какого бы то ни было интерактива), единственной целью которых являлось привести потенциальных покупателей в существующий физический магазин. Этот первый шаг, предпринятый для привлечения клиентов с помощью Интернета, впоследствии был озаглавлен теоретиками сайтостроительства как Web Presence, или "Веб-присутствие". Под "присутствием" тогда понимались лишь контактные телефоны, адрес, схема проезда и в лучшем случае электронный адрес.
Постепенно, с развитием систем управления базами данных и увеличением пропускных способностей каналов передачи, начали появляться периодически обновляемые Интернет-версии прайс-листов на товары или услуги компаний.
Как правило, под Интернет-магазином тогда понимали именно Интернет-интерпретацию реально существующего магазина, позволяющую просматривать прайс-листы этого магазина посредством Интернета. Так появились on-line-каталоги.
Далее последовали три серьезных шага, обеспечивших полноценное существование Интернет-магазинов как полностью самостоятельных организаций, а именно:
обогатились средства взаимодействия с клиентом (он получил возможность не только просматривать, но и заказывать, а впоследствии и оплачивать товары или услуги, не вставая из-за компьютера), что явилось началом эры "Web Shopping" (Интернет-торговли);
произошел разрыв между реальными магазинами и их Интернет-интерпретациями, то есть Интернет-магазин начал существовать без своего физического собрата;
началась поставка товаров или услуг не только конечным потребителям (Business to Client), но и дистрибьюторам (Business to Business).
E-commerce открывает новые возможности для бизнеса с помощью Интернета благодаря большей оперативности Интернет-магазинов (реакции на мнения покупателей), отличающей их от физических аналогов, оданако Интернет-магазины пока еще несколько уступают по уровню демонстрации товаров или услуг. И хотя в последнее время получили широкое развитие Интернет-магазины, в которых можно в буквальном смысле слова покрутить товар во всевозможных плоскостях (благодаря средствам Macromedia Flash), пока, к сожалению, Интернет-магазины не могут помочь сомневающимся покупателям получить ответы на вопросы типа "а подойдет ли мне это?". Но все впереди, и за этим будущее E-commerce.
Что же нам понадобится
Предполагается, что читатель знаком с основами ASP- и SQL-программирования (первых трех частей настоящей статьи для этого будет вполне достаточно).
Постановка задачи
По сути дела, мы хотим организовать базу данных всего перечня товаров гипотетического магазина (выберем для этого магазин компьютеров и комплектующих), реализовать средства демонстрации товаров, позволить покупателю выбирать и добавлять товары в "корзину" и посылать заказ по электронной почте.
Но это еще не все. Давайте попытаемся несколько интеллектуализировать нашу систему, ведь не все покупатели точно знают, что именно хотят приобрести, да и многие товары таковы (например, бытовая техника или компьютеры), что во всех их параметрах обыватель разобраться не может — зачастую требуется консультация эксперта.
Попытаемся реализовать такого эксперта программно. Создадим несколько шаблонов типовых конфигураций персональных компьютеров, к примеру "Графическая станция", "Мультимедийный компьютер для дома с Интернет-возможностями", "Сервер баз данных" и т.д. Далее будем предлагать покупателям выбор наиболее подходящего шаблона, избавляя его тем самым от необходимости подбора комплектующих, в ходе которого им могут быть выбраны, например, два несовместимых устройства.
Ясное дело, что если шаблоны будут меняться достаточно часто и если их много, то процесс их подготовки необходимо автоматизировать (для этого проще всего написать небольшую программу — построитель шаблонов при помощи Borland C++ Builder).
Согласитесь, что предложенная задача весьма актуальна и с первого взгляда может показаться более сложной, чем на самом деле.
Для начала давайте представим себе процесс покупки компьютера и попытаемся формализовать его. Приведенная ниже последовательность шагов описывает этот процесс следующим образом:
Для некомпетентных покупателей:
выбор типовой конфигурации;
просмотр заказа и его подтверждение;
регистрация заказа в системе с посылкой его менеджеру виртуального магазина в отдел продаж или доставки.
Для компетентных покупателей:
выбор комплектующих и их количества;
просмотр заказа и его подтверждение;
регистрация заказа в системе с посылкой его менеджеру виртуального магазина в отдел продаж или доставки.
Как видно, последовательность выполняемых действий по взаимодействию клиента с системой крайне проста, и в нашем случае каждый из перечисленных шагов будет представлен отдельным ASP-файлом.
Создание и подготовка базы данных
Для создания базы данных (назовем ее Ishop) нам понадобится Microsoft Access 2000. От процесса проектирования базы данных будет зависеть дальнейший объем программной логики нашего приложения, поэтому этот этап крайне ответственен. И еще один совет: при проектировании Интернет-магазина стремитесь к тому, чтобы ваши странички содержали как можно меньше строк и констант, выведите все, что можно, за их пределы, вплоть до наименований позиций, так как последние могут меняться довольно часто. Иными словами, добейтесь от своего кода универсальности и независимости от данных. Однако, поскольку принципы проектирования баз данных выходят за рамки настоящей статьи, не будем задерживаться на них и представим структуру нашей базы данных так, как показано на рис.1.
Рис.1.
Создадим три управляющие таблицы для хранения информации о наименованиях всех категорий и их соответствия таблицам с позициями, ценами и условиями гарантий (таблицу _Components (рис.2), таблицы с перечнем дополнительных категорий (таблицу _Equipment (рис.3) для компетентных покупателей и таблицу _PCType (рис.4) для некомпетентных покупателей, желающих приобрести компьютер с определенной целью (к примеру, для дома или для офиса).
Рис.2.
$BREAK$
Рис.3.
Рис.4.
Следует отметить, что поле IsPCComponent в таблице _Components, имеющее булево значение, позволяет определить, является ли данный компонент обязательным составляющим персонального компьютера или нет (это понадобится нам в дальнейшем).
Все остальные таблицы создадим по одному и тому же шаблону с наименованием позиции (поле Title), розничной ценой (поле Price1), мелкооптовой ценой (поле Price2) и крупнооптовой ценой (поле Price 3), а также с условиями гарантии на товар (поле Description) (рис.5)..
Рис.5.
Как видите, таблица _PCType осуществляет взаимосвязь всех остальных таблиц и позволяет организовать системы предложения оптимальной конфигурации компьютера. Пример такой взаимосвязи представлен на рис.6.
Рис.6.
Итак, каждая строка таблицы _PCType содержит номера ключевых полей всех таблиц с позициями комплектующих.
Далее необходимо прописать нашу базу данных в соответствующем разделе источников данных системы, для этого:
запустите программу-конфигуратор источников данных (Data Sources ODBC) — Sart->Settings->Control Panel->Administrative Tools->Data Sources ODBC;
перейдите во вкладку System DSN и создайте новый источник данных, нажав на Add…;
в появившемся списке драйверов выберите драйвер баз данных Microsoft Access — Microsoft Access Driver (*.mdb) и нажмите на Finish;
в строке Data Source Name задайте имя нашей базы данных, в нашем случае IShop (это имя, по которому мы в дальнейшем будем обращаться к ней).
нажмите на Select…, выберите файл базы данных и нажмите OK.
Вы увидите появившуюся строку в списке источников данных в вашей системе (рис.7)
Рис.7.
Теперь, когда база данных готова, можно приступать к созданию самого Интернет-магазина.
Структура нашего Интернет-магазина
Для того чтобы вам было легче понять дальнейшее изложение, давайте представим себе структуру нашего будущего Интернет-магазина, причем формы и действия при выборе конфигурации компьютера автоматически представим синим цветом, при выборе конфигурации самостоятельно — зеленым, при выборе дополнительного оборудования — сиреневым, а начало и конец алгоритма-схемы — красным (рис. 8):
Рис.8.
Из схемы видно, что и при при автоматическом (по типовым шаблонам), и при самостоятельном подборе конфигурации загружается одна и та же форма MainForm.asp, однако если пользователь выбирал какую-нибудь типовую конфигурацию, то в последующей форме по умолчанию будут загружены позиции, соответствующие выбранной типовой конфигурации (из таблицы _PCtype), в противном случае — первые позиции (в которых рекомендуется написать "Выберите позицию"). При выборе раздела "Подбор дополнительного оборудования" загружается отдельная форма, но во всех остальных случаях ход дальнейшего "развития событий" одинаков: производится подтверждение заказа, сбор информации о покупателе и отправка заказа по электронной почте.
Уяснив структуру проектируемого приложения, можно приступать к написанию кода.
Главная страничка — выбор типа заказа (файл index.asp)
Для начала создадим страничку, в которой пользователь сможет выбрать один из трех режимов дальнейшего взаимодействия с сайтом, а именно: покупка компьютера с помощью эксперта, самостоятельный выбор или приобретение дополнительного оборудования.
<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, где будет свидетельствовать о том, что пользователь решил выбирать состав компьютера самостоятельно.
Выбор типовой конфигурации компьютера (файл auto.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>
Выбор дополнительного оборудования (equip.asp)
<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>
$BREAK$
Подбор комплектующих (файл MainForm.asp)
Прежде чем приступить к выбору комплектующих, необходимо уяснить следующее. Дело в том, что нам предстоит организовать средство просмотра и выбора позиций, соответствующих именам таблиц из соответствующего поля таблицы _Components, где параметр IsPCComponent равен 1, с возможностью указания количества единиц комплектующих каждой категории и просмотра цены за единицу, и суммарной цены (за весь набор), причем в интерактивном режиме. Это означает, что, выбрав из списка ту или иную позицию, пользователь должен сразу же увидеть справа цену за ее единицу и обновленную цену за весь набор с учетом последнего изменения. То же самое должно происходить при изменении количества единиц каждой позиции.
Для технической реализации вышеизложенного визуально в пределах одной формы придется воспользоваться HTML-тэгом iframe, причем скрытым, а в нужных местах в телеформы использовать тэг b, например, "<b id=”Message1”></b>", где в переменную 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()"> <b 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 %> </b> </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 "<b id='Message" & CurrentCategory _ &"'></b></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 "<b id='TMessage'></b></b></i></td></tr>" %> </table> <p> <input type="submit" name="Submit" value="Продолжить"> <input type="reset" name="Reset" value="Очистить форму"> </p> </form> </div> </body> </html>
Подтверждение заказа (файл MainformProc.asp)
<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>
$BREAK$
Сбор данных о покупателе (файл EmailOrder.asp)
<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>
Oтправка заказа по e-mail (файл Done.asp)
После того как все действия выполнены успешно, необходимо сформировать электронное письмо, которое должно быть послано в подтверждение выполненного заказа гипотетическому менеджеру по продажам или доставке нашего виртуального магазина и самому пользователю одновременно. Для этого воспользуемся бесплатно поставляемым 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; " Body = Body & "charset=windows-1251'></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 & " время по оставленным вами координатам." 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 "Ваш заказ был успешно отправлен " Response.Write "на сервер виртуального магазина.<br>" Response.Write "Спасибо!</center>" %> </body> </html>
Заключение
Мир Интернет-магазинов огромен. Но несмотря на такое разнообразие, их подавляющее большинство представлены структурной схемой, изложенной в настоящей статье. Конечно, некоторые из них умеют принимать оплату с помощью кредитных карточек, но сути дела это не меняет, каждый Интернет-магазин представляет информацию, позволяет "набрать корзину", заказать, а иногда и оплатить товар. Имеются разные варианты и с доставкой. Прежде чем приступать к созданию своего собственного Интернет-магазина, советую для начала "побродить" по чужим. И еще очень многое зависит от работы дизайнеров. С одной стороны, такое утверждение может показаться дилетантским, дескать, а где это от работы дизайнеров мало что зависит, но поверьте, в данном случае особенно важно, чтобы покупатель чувствовал себя уютно и в привычной обстановке. Для каждой конкретной категории товара должен быть создан соответствующий дизайн, подходящий к конкретному товару и конкретному покупателю.
Полный архив исходных скриптов и базы данных к настоящей статье лежит здесь.