<% ASP на блюдечке %>. Часть 13
Проверка правильности заполнения полей формы
Будем исходить из того, что пользователь ввел все правильно и вместо адреса электронной почты не может оказаться произвольная строка, а вместо значения цены — буквенная последовательность. К тому же, как известно, в определенных случаях форма должна быть заполнена и не может оставаться пустой (по крайней мере ее определенные поля). Для реализации всего этого следует заранее подготовить скрипт-библиотеку «на все случаи жизни», включить ее описание в требуемый модуль, в котором будет осуществляться вызов соответствующих функций проверки, и определить тело функции правильности заполнения полей формы, как примеру:
<SCRIPT TYPE="text/javascript">
<!--
function checkMe() {
with (document.AddEditForm) {
if (isBlank(CustomerFirstName, 'Please enter Customer First Name.')) return false;
if (isBlank(CustomerLastName, 'Please enter Customer Last Name.')) return false;
if (!isQuantity(ProdQuantity, 'Please enter correct Product quantity value.')) return false;
if (!isCardNumber(CardNum, 'Please enter valid, 16 digit card number.')) return false;
if (!isZipCode5(BillingZip5,'Please enter correct 5 digit Billing zip code.')) return false;
if (!isZipCode4(BillingZip4,'Please enter correct 4 digit Billing zip code.')) return false;
if (!isZipCode5(ShipZip5,'Please enter correct 5 digit Shipping zip code.')) return false;
if (!isZipCode4(ShipZip4,'Please enter correct 4 digit Shipping zip code.')) return false;
if (isBlank(Phone, 'Please enter Phone number.')) return false;
if (isBlank(PhoneAC, 'Please enter Phone Area Code number.')) return false;
if (!isPhone(Phone, 'Please enter correct Phone number.')) return false;
if (!isPhoneAC(PhoneAC, 'Please enter correct Phone Area Code number.')) return false;
if (!isPhone(Fax, 'Please enter correct Fax number.')) return false;
if (!isPhoneAC(FaxAC, 'Please enter correct Fax Area Code number.')) return false;
if (isBlank(Email,'Please enter the Email address.')) return false;
if (!isEmail(Email,'Please enter the Email address in the correct format (for instance somebody@domain.com)')) return false;
if (!isFloat(RushCharge, 'Please enter Rush Charge value in the correct format.')) return false;
if (!isFloat(Cost, 'Please enter Cost value in the correct format.')) return false;
if (!isFloat(SalesTax, 'Please enter Sales Tax value in the correct format.')) return false;
if (!isFloat(Total, 'Please enter Total value in the correct format.')) return false;
}
return true;
}
//-->
</SCRIPT>
Как видите, данная функция будет возвращать значение «ложно», а следовательно, препятствовать обработке формы, если какое-либо из условий, поставленных вызовами соответствующих функций, не будет соблюдено.
Далее в тело разрабатываемой странички необходимо включить директиву включения соответствующей библиотеки с имплементацией выше используемых функций:
<SCRIPT TYPE="text/javascript" SRC="script.js">
<!-- // displays only if script file not found
document.write ("JavaScript library not found.");
//-->
</SCRIPT>
Саму же библиотеку надо представить отдельным файлом следующим образом:
//*********************************************************************************
var timerID = null;
var timerRunning = false;
//***********************************************************************************function isZipCode5 (s,message)
{
if (s.value.length == 0) return true;
if ( (s.value.length < 5) || (!isInteger(s,message)) ) {
alert(message);
s.focus();
return false;
}
return true;
}
//***********************************************************************************
function isZipCode4 (s,message)
{
if (s.value.length == 0) return true;
if ( (s.value.length < 4) || (!isInteger(s,message)) ) {
alert(message);
s.focus();
return false;
}
return true;
}
//***********************************************************************************
function isInteger (s,message){
var i;
var ss;
ss = s.value;
for (i = 0; i < ss.length; i++){
var c = ss.charAt(i);
if (c != " ")
if (!isDigit(c)) {
alert(message);
return false;
}
}
return true;
}
//***********************************************************************************function isCardNumber (s,message)
{
var i;
var l;
var ss;
if ((s.value.length <= 0) || (s.value == null) || (s.value == "")) return true;
ss = s.value;
l = 0;
for (i = 0; i < ss.length; i++) {
var c = ss.charAt(i);
if (c != " ") {
if (!isDigit(c)) {
alert(message);
s.focus();
return false;
}
else {
l++;
}
}
}
if (l != 16) {
alert(message);
s.focus();
return false;
}
return true;
}
//***********************************************************************************
function isFloat (s,message)
{
var i;
var ss;
ss = s.value;
if ((ss.length <= 0) || (ss == null) || (ss == "")) return true;
for (i = 0; i < ss.length; i++) {
var c = ss.charAt(i);
if ((c != ',') && (c != '.')) {
if (!isDigit(c)) {
s.focus();
alert(message);
return false;
}
}
else {
if ((i == 0) || (i == ss.length)) {
s.focus();
alert(message);
return false;
}
}
}
return true;
}
//**********************************************************************************
function isQuantity (s,message){
var i;
var ss;
ss = s.value;
for (i = 0; i < ss.length; i++){
var c = ss.charAt(i);
if (!isDigit(c)) {
alert(message);
s.focus();
return false;
}
}
return true;
}
//***********************************************************************************
function isDigit (c){
return ((c >= "0") && (c <= "9"))
}
//***********************************************************************************
function numericize(s){
var i,j;
j = "";
for (i = 0; i < s.value.length; i++) {
if (isDigit(s.value.charAt(i))) {
j = j + s.value.charAt(i);
}
}
return j;
}
//***********************************************************************************
function isBlank(s,message){
if ((s.value.length > 0) && (s.value != null) && (s.value != "")) {
return false;
}
alert(message);
s.focus();
return true;
}
//***********************************************************************************
function isSSN (s,message){
var x,i;
if (isBlank(s,message)){
s.focus();
return false;
}
if (s.value.length == 11){
s.value=numericize(s.value);
}
if (s.value.length == 9){
if (isInteger(s.value,message)){
return true;
}
else{
s.focus();
return false;
}
}
alert(message);
s.focus();
return false;
}
//***********************************************************************************
function isPhone (s,message){
if ((s.value.length <= 0) || (s.value == null) || (s.value == "")) return true;
// Should be 7 digit phone number
if (s.value.length != 7) {
alert(message + "\nPhone number should be 7 digit!");
s.focus();
return false;
}
// Check if first digit is 0. Invalid phone number.
if (s.value.charAt(0) == '0') {
alert(message+"\nFirst digit cannot be 0!");
s.focus();
return false;
}
if (!isInteger(s,message)) {
alert(message + "\nNo other symbols allowed!");
s.focus();
return false;
}
return true;
}
//***********************************************************************************
function isPhoneAC (s,message){
if ((s.value.length <= 0) || (s.value == null) || (s.value == "")) return true;
// Should be 3 digit phone number
if (s.value.length != 3) {
alert(message + "\nPhone area code number should be 3 digit!");
s.focus();
return false;
}
// Check if first digit is 0. Invalid phone number.
if (s.value.charAt(0) == '0') {
alert(message+"\nFirst digit cannot be 0!");
s.focus();
return false;
}
if (!isInteger(s,message)) {
alert(message + "\nNo other symbols allowed!");
s.focus();
return false;
}
return true;
}
//***********************************************************************************function isEmail (s,message)
{
var i,ii;
var j;
var k,kk;
var jj;
var len;
// Check blank
if ((s.value.length <= 0) || (s.value == null) || (s.value == "")) return true;
// Check valid email
// Must have a "@" and a "." to be valid.
// Must have at least 1 character before "@"
// Must have at least 1 character after "@" and before "."
// Must have at least 2 characters after "."
if (s.value.length >0) {
i = s.value.indexOf("@");
ii = s.value.indexOf("@",i+1);
j = s.value.indexOf(".",i);
k = s.value.indexOf(",");
kk = s.value.indexOf(" ");
jj = s.value.lastIndexOf(".")+1;
len = s.value.length;
if ((i>0) && (j>(1+1)) && (k==-1) && (ii==-1) && (kk==-1) &&
(len-jj >=2) && (len-jj<=3)) {}
else {
alert(message)
s.focus();
return false;
}
}
return true;
}
//***********************************************************************************function isSelected (s,message)
{
if (s.selectedIndex==0){
alert(message);
s.focus();
return false;
}
return true;
}
//***********************************************************************************
Разумеется, набор этих функций не полон, однако мы постарались охватить наиболее типичные случаи проверки правильности введенных значений. Данная библиотека полностью оттестирована и может быть использована в любом Web-приложении.
Убедившись в правильности заполнения полей формы, можно приступать к вводу значений в базу данных или к их редактированию.
Обработка введенных значений
Для начала следует объявить переменные:
<% dim useraction dim CustomerFirstName, CustomerLastName, CustomerSalutation, PaymentMethod, BillingAdr, ShipAdr, Phone, Email dim PaymentStatus, ShipType, ShipTypeID, ShipStatus, TrackNum, Cost, Total, CardNum, secure, PagesNum dim id,flag,color, Str, D, ProductID, SourceTypeID, ProdQuantity, CardHolderFName, CardHolderMI, CardHolderLName dim CardExpDate, CardExpMonth, CardExpYear, PhoneAC, RushCharge, FaxAC, Fax dim BillingAdr1, BillingAdr2, BillingAdrType, BillingAdrNum dim BillingCity, BillingState, BillingZip5, BillingZip4, BillingCountry, IsGift dim ShipAdr1, ShipAdr2, ShipAdrType, ShipAdrNum dim ShipCity, ShipState, ShipZip5, ShipZip4, ShipCountry dim GRFirstName, GRLastName, SalesTax %>
Затем необходимо опросить форму и записать полученные значения в переменные (заметьте, что переменные имеют те же имена, что и поля формы и поля базы данных, и это не случайно):
<%
userAction = request("action")
Select Case userAction
Case "add"
CustomerSalutation = request.form("CustomerSalutation")
CustomerFirstName = request.form("CustomerFirstName")
CustomerLastName = request.form("CustomerLastName")
ProdQuantity = request.form("ProdQuantity")
ProductID = request.form("ProductID")
PagesNum = request.form("PagesNum")
PaymentMethod = request.form("PaymentMethod")
CardHolderFName= request.form("CardHolderFName")
CardHolderMI = request.form("CardHolderMI")
CardHolderLName= request.form("CardHolderLName")
CardNum = request.form("CardNum")
BillingAdr1 = request.form("BillingAdr1")
BillingAdr2 = request.form("BillingAdr2")
BillingAdrType = request.form("BillingAdrType")
BillingAdrNum = request.form("BillingAdrNum")
BillingCity = request.form("BillingCity")
BillingState = request.form("BillingState")
BillingZip5 = request.form("BillingZip5")
BillingZip4 = request.form("BillingZip4")
BillingCountry = request.form("BillingCountry")
IsGift = request.form("IsGift")
ShipAdr1 = request.form("ShipAdr1")
ShipAdr2 = request.form("ShipAdr2")
ShipAdrType = request.form("ShipAdrType")
ShipAdrNum = request.form("ShipAdrNum")
ShipCity = request.form("ShipCity")
ShipState = request.form("ShipState")
ShipZip5 = request.form("ShipZip5")
ShipZip4 = request.form("ShipZip4")
ShipCountry = request.form("ShipCountry")
GRFirstName = request.form("GRFirstName")
GRLastName = request.form("GRLastName")
PhoneAC = request.form("PhoneAC")
Phone = request.form("Phone")
FaxAC = request.form("FaxAC")
Fax = request.form("Fax")
Email = request.form("Email")
CardExpDate = request.form("CardExpDate")
CardExpMonth = request.form("CardExpMonth")
CardExpYear = request.form("CardExpYear")
PaymentStatus = request.form("PaymentStatus")
ShipTypeID = request.form("ShipType")
SourceTypeID = request.form("SourceType")
ShipStatus = request.form("ShipStatus")
TrackNum = request.form("TrackNum")
RushCharge = request.form("RushCharge")
Cost = request.form("Cost")
SalesTax = request.form("SalesTax")
Total = request.form("Total")
secure = 0
%>
После этого можно приступать непосредственно к записи в базу данных (активное использование ADO-методов работы с данными позволит значительно облегчить задачу проектирования Web-интерфейса):
<%
Call Connect()
Sql = "select * from Orders"
rs.open sql, Conn, adOpenStatic, adLockOptimistic
rs.addnew
rs("CustomerSalutation") = CustomerSalutation
rs("CustomerFirstName") = CustomerFirstName
rs("CustomerLastName") = CustomerLastName
If ProdQuantity <> 0 Then rs("ProdQuantity") = ProdQuantity End If
If request("OtherProduct") <> "" Then rs("OtherProduct") = request("OtherProduct") End If
rs("ProductID") = ProductID
rs("PagesNum") = PagesNum
If PaymentMethod <> "" Then rs("PaymentMethod") = PaymentMethod End If
If CardHolderFName <> "" Then rs("CardHolderFName") = CardHolderFName End If
If CardHolderMI <> "" Then rs("CardHolderMI") = CardHolderMI End If
If CardHolderLName <> "" Then rs("CardHolderLName") = CardHolderLName End If
If CardNum <> "" Then rs("CardNum") = CardNum End If
If BillingAdr1 <> "" Then rs("BillingAdr1") = BillingAdr1 End If
If BillingAdr2 <> "" Then rs("BillingAdr2") = BillingAdr2 End If
If BillingAdrType <> "" Then rs("BillingAdrType") = BillingAdrType End If
If BillingAdrNum <> "" Then rs("BillingAdrNum") = BillingAdrNum End If
If BillingCity <> "" Then rs("BillingCity") = BillingCity End If
If BillingState <> "" Then rs("BillingState") = BillingState End If
If BillingZip5 <> "" Then rs("BillingZip5") = BillingZip5 End If
If BillingZip4 <> "" Then rs("BillingZip4") = BillingZip4 End If
If BillingCountry <> "" Then rs("BillingCountry") = BillingCountry End If
rs("IsGift") = IsGift
If ShipAdr1 <> "" Then rs("ShipAdr1") = ShipAdr1 End If
If ShipAdr2 <> "" Then rs("ShipAdr2") = ShipAdr2 End If
If ShipAdrType <> "" Then rs("ShipAdrType") = ShipAdrType End If
If ShipAdrNum <> "" Then rs("ShipAdrNum") = ShipAdrNum End If
If ShipCity <> "" Then rs("ShipCity") = ShipCity End If
If ShipState <> "" Then rs("ShipState") = ShipState End If
If ShipZip5 <> "" Then rs("ShipZip5") = ShipZip5 End If
If ShipZip4 <> "" Then rs("ShipZip4") = ShipZip4 End If
If ShipCountry <> "" Then rs("ShipCountry") = ShipCountry End If
If GRFirstName <> "" Then rs("GRFirstName") = GRFirstName End If
If GRLastName <> "" Then rs("GRLastName") = GRLastName End If
rs("PhoneAC") = PhoneAC
rs("Phone") = Phone
If FaxAC <> "" Then rs("FaxAC") = FaxAC End If
If Fax <> "" Then rs("Fax") = Fax End If
If Email <> "" Then rs("Email") = Email End If
If CardExpDate <> "" Then rs("CardExpDate") = CardExpDate End If
If CardExpMonth <> "" Then rs("CardExpMonth") = CardExpMonth End If
If CardExpYear <> "" Then rs("CardExpYear") = CardExpYear End If
rs("PaymentStatus") = PaymentStatus
rs("ShipTypeID") = ShipTypeID
rs("ShipStatus") = ShipStatus
rs("SourceTypeID") = SourceTypeID
If TrackNum <> "" Then rs("TrackNum") = TrackNum End If
If RushCharge <> "" Then rs("RushCharge") = RushCharge End If
If Cost <> "" Then rs("Cost") = Cost End If
If SalesTax <> "" Then rs("SalesTax") = SalesTax End If
If Total <> "" Then rs("Total") = Total End If
rs("DateTime") = Now()
rs.update
Call Close()
End Select
%>
Как вы наверняка заметили, в вышеприведенном фрагменте кода присутствуют проверки на ненулевое значение полей формы. Сделано это для тех из них, которые в силу своей специфики могут иметь нулевые значения. Разумеется, в этом случае нет необходимости производить запись соответствующих значений в базу данных.
Заключение
В заключение еще раз напомним особенности применения вышеизложенного подхода к проектированию Web-интерфейсов к базам данных. Во-первых, это очевидное преимущество использования нотации как при проектировании базы данных, так и при разработке приложения (поля базы данных, поля формы и переменные, служащие для ввода значений в базу данных, имеют одинаковые имена). Во-вторых, использование замыкания формы на самой себе позволяет разрабатывать переносимые модули, которые с успехом могут быть использованы и в других Web-приложениях. Далее использование ADO-компонентов позволяет существенно повысить читабельность и эффективность тех частей кода, в которых производится обращение к базе данных, а использование скрипт-функций проверки правильности заполнения формы позволит существенным образом разгрузить сервер от выполнения операций по проверке корректности введенных значений. В целом рассмотренная методика позволит разрабатывать сложные Web-интерфейсы к базам данных в кратчайшие сроки, избежать ненужных тестирований и снизить вероятность возникновения ошибок при программировании.
С автором статьи можно связаться по адресу rouben@iname.com.
КомпьютерПресс 9'2001








