<% 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