Създаване на елементи на формуляр с избор на една стойност
ЗадачаФормулярът трябва да съдържа поле, което предлага на потребителя много опции, но позволява да бъде избрана само една от тях.
РешениеИзползвайте елементи от списък с единичен избор. Те включват набори от бутони за избор, изскачащи менюта или списъци с възможност за превъртане.
ДискусияЕлементите на формуляр за единичен избор позволяват да бъдат избрани множество опции, от които може да бъде посочена само една. В нашия пример има няколко набора от такива елементи:
• Списък с цветове от таблицата cow_color. Те могат да бъдат получени чрез следната заявка:
mysql> ИЗБЕРЕТЕ цвят ОТ cow_color ORDER BY цвят;
Имайте предвид, че някои имена на цветове съдържат знака &, който има специално значение в HTML.
Тоест, когато се използват за елементи на списък, такива стойности ще трябва да бъдат кодирани според стандарта HTML. (Всъщност ще кодираме всички елементи от списъка на формуляра, но тези стойности ясно показват, че кодирането е добър навик.)
• Списък с приемливи размери на фигурки от колоната размер на таблицата cow_order.
Колоната е от тип ENUM, така че възможните стойности и стойностите по подразбиране могат да бъдат получени с помощта на клаузата SHOW COLUMNS:
mysql> ПОКАЗВАНЕ НА КОЛОНИ ОТ cow_order КАТО 'size'\G ******************************** 1. ред *************************** Поле: размер Тип: enum('small','medium','large') Null: ДА Ключ: По подразбиране: среден Допълнително:
• Списък с имена на държави и съкращения, съхранени в таблицата със състояния:
mysql> SELECT съкращение, име FROM заявява ORDER BY име;
+--------+--------+ съкратено име +--------+--------------+ AL Алабама AK Аляска AZ Аризона AR Арканзас CA Калифорния CO Колорадо CT Кънектикът .
Броят на стойностите за избор във всички тези списъци е различен: 3 размера, 7 цвята и 50 състояния.
Стойностите на размера са най-добре представени като радио бутони, няма нужда от списък с възможност за превъртане поради малкия брой стойности, от които да избирате. Приемливо е да се представи набор от цветове чрез който и да е от елементите, за да се избере една стойност. Той е достатъчно малък, така че наборът от радио бутони да не заема твърде много място, но също така е достатъчно голям, за да позволи превъртане - особено ако ще се добавят допълнителни цветове. Списъкът със състояния вероятно има твърде много стойности, за да бъде представен като радио бутони, така че изскачащо меню или списък с възможност за превъртане би бил най-разумният дисплей.
Нека да разгледаме синтаксиса за всеки от типовете елементи и след това да се опитаме да ги генерираме от скриптове.
Превключватели. Групата бутони за избор се състои от елементи от тип radio със същия атрибут име. Всеки елемент също има атрибут стойност. Текстът на дисплея може да бъде зададен след етикета.
За да маркирате стойност като първоначален избор по подразбиране, добавете атрибута checked. Следната група радио бутони показва възможните размери на фигурки на крави, като средната стойност (средна) е маркирана като стандартна:
малък среден голям
Изскачащото меню е списък, ограден между тагове, в който всеки елемент от менюто е ограден в тагове. Всеки елемент има \n", htmlspecialchars ($values[$i]), $checked, htmlspecialchars ($labels[$i])); > $str = sprintf ( " \n", htmlspecialchars($name), $str); връщане($str); >
Функцията make_popup_menu() няма $vertical параметър, но иначе се извиква точно като make_radio_group():
print(make_popup_menu("color", $values, $values, ""));
Функцията make_scrolling_list() е подобна на make_popup_menu(), така че не включвам нейната реализация тук. Ако искате да го извикате, за да формира списък с възможност за единичен избор, дайте му същите аргументи като make_popup_menu(), укажете колко реда да се показват наведнъж и добавете множествения аргумент към FALSE:
print(make_scrolling_list("color", $values, $values, "", 3, FALSE));
Списъкът със състояния използва различни набори от данни за стойности и видим текст. Нека ги извлечем така:
$values = масив (); $етикети = масив(); $query = "ИЗБЕРЕТЕ съкращение, име FROM заявява ORDER BY име"; $result_id = mysql_query($query, $conn_id); ако ($result_id) $values[] = $abbrev; $етикети[] = $име; > mysql_free_result($result_id); >
След това използваме видимия текст и стойности, за да формираме необходимия списък:
print(make_popup_menu("state", $values, $labels, "")); print(make_scrolling_list("state", $values, $labels, "", 6, FALSE));
Изпълнението на функциите в Python е подобно на версиите на PHP. Например функцията make_popup_menu() изглежда така:
def make_popup_menu (име, стойности, етикети, подразбиране): ако тип (стойности) не е в (types.ListType, types.TupleType): връщане ("make_popup_group: аргументът на стойностите трябва да е списък") ако тип (етикети) не е в (types.ListType, types.TupleType): връщане ("make_popup _group: аргументът labels трябва да бъде списък") if len (стойност s) != len(labels): return("make_popup_group: value and label list size mismatch") str = "" for i in range (len (values)): value = values[i] label = labels[i] # проверка дали стойностите и видимият текст са низове ако тип (стойност) не е типове.StringType: value = `value` ако типът (етикет) не е типове.Str ingType: label = `lab el` # изберете елемент, ако съответства на стойността по подразбиране ако type (default) не е типове.StringType: default = `default` if value == default: checked = " selected=\"selected\"" else: checked = "" str = str + \ " \n" % (cgi.escape (стойност, 1), отметнато, c gi.escape (етикет, 1)) ако типът (име) не е типове.StringType: name = `name` str = " \n" \ % (cgi.escape (name, 1), str) return (str)За да представите крави в цветна форма, извлечете ги от таблицата: value es = [] query = "SELECT color FROM cow_color ORDER BY color" cursor = conn.cursor() cursor.execute (query) for (color, ) in cursor.fetchall(): values.append (color) cursor.close()
След това преобразуваме списъка в елемент на формуляр:
печат make_radio_group ("цвят", стойности, стойности, "", 1) печат make_popup_menu ("цвят", стойности, стойности, "") печат make_scrolling_list ("цвят", стойности, стойности, "", 3, 0)
За да покажем списък с държави, извличаме техните имена и съкращения:
values = [] labels = [] query = "Изберете Abbrev, Име от състояния Поръчайте по име" Cursor = Conn.Cursor () Cursor.execute (QUERY) за (Abbrev, име) в cursor.fetchall (): values.appens (abbrev) labels.append (име) cursor.
След това го предаваме на подходящата функция:
печат make_popup_menu ("състояние", стойности, етикети, "") печат make_scrolling_list ("състояние", стойности, етикети, "", 6, 0)
ЯжтеЕдно нещо, което функциите на Python правят, което техните PHP аналози не правят: изрично преобразуване на стойностите на аргументите, които са вградени в списък в низов формат. Това е необходимо, защото методът cgi.escape() хвърля изключение, ако се опитате да го използвате за HTML-кодиране на стойност, която не е низ.
Досега говорихме за извличане на редове от таблиците cow_color и states и преобразуването им във формуляри. Онлайн заявка за поръчка на фигурки крави изисква още един елемент от формата - поле за посочване на размера на фигурката. Позволените стойности за това поле се определят от колоната за размер на таблицата cow_order. Тази колона е от тип ENUM, така че за да получите валидни стойности на елемент на формуляр, трябва да получите дефиницията на колоната и да извлечете необходимата информация от нея.
За щастие, по-голямата част от работата по тази задача вече е свършена в Рецепта 9.6, където сте създали функции за отпечатване на метаданни на колони ENUM и SET. Например, в Perl, за да получите метаданните за колоната за размер, извикайте функцията get_enumorset_info():
my $size_info = get_enumorset_info($dbh, "cow_order", "size");
Членът на стойностите е препратка към разрешените стойности на изброения тип, а по подразбиране е стойността по подразбиране на колоната. Форматът на информацията позволява тя да бъде директно преобразувана в елемент на формуляр, като например група бутони за избор или изскачащо меню:
print radio_group (-name => "size", -values => $size_info->, -default => $size_info->, -linebreak => 1); # подредете бутоните вертикално print popup_menu (-name => "size", -values => $size_info->, -default => $size_info->);
Стойността по подразбиране е средна, тази стойност ще бъде избрана, когато браузърът отвори формуляра.
Функция за извличанеметаданните за PHP връщат асоциативен масив. Използваме го, за да генерираме елементи на формуляр въз основа на метаданните на колоната за размер по този начин:
$size_info = get_enumorset_info($conn_id, "cow_order", "size"); печат (make_radio_group ("size", $size_info["values"], $size_info["values"], $size_info["default"], TRUE)); # подредете елементи вертикално печат (make_popup_menu ("size", $size_info["values"], $size_info["values"], $size_info["default"]));
Python версията на функцията връща речник, който се използва по подобен начин:
size_info = get_enumorset_info (conn, "cow_order", "size") print make_radio_group ("size", size_info["values"], size_info["values"], size_info["default"], 1) print make_popup_menu ("size", size_info["values"], size_info["стойности"], size_info["default"])
Ако това е начинът, по който използвате ENUM стойности за създаване на елементи от списък, тогава те се извеждат в реда, в който са посочени в дефиницията на колоната. В дефиницията на колоната за размер стойностите са представени в ред на показване (малък, среден, голям), ако не сте доволни от реда на колоните в дефиницията, сортирайте ги.
За да илюстрирам как да създавам елементи на формуляр за JSP страници въз основа на метаданни на колони, ще използвам функция, вградена в страницата. По-добър начин е да създадете персонализирано действие в библиотеката с етикети, което съответства на класа, който връща информация, но създаването на потребителски етикети е извън обхвата на тази книга. Следователно в примерите ще бъдат използвани следните методи:
• Използвайте JSTL тагове, за да изпълните заявка SHOW COLUMNS, за да получите дефиницията на колоната ENUM, след което преместете дефиницията в контекстастраници.
• Напишете функция, която извлича дефиницията от контекста на страницата, разделя я на масив от отделни стойности и поставя масива обратно в контекста на страницата.
• Достъп до масив с помощта на JSTL итератор, който извежда всяка от стойностите като елемент от списък. Всяка стойност се сравнява със стойността по подразбиране на колоната и, ако има съвпадение, стойността се маркира като първоначално избрана.
Функцията, която извлича разрешените стойности от дефиниция на колона ENUM или SET, се нарича getEnumOrSetValues(). Нека го поставим в JSP страница като тази:
Функцията приема три аргумента:
• Контекстният обект на страницата.
• Името на атрибута на страницата, който съдържа дефиницията на колона. Това е "входът" на функцията.
• Името на атрибута на страницата, в който се поставя полученият масив от разрешени стойности на колони. Това е "изходът" на функцията.
За да формираме елемент от списък въз основа на колоната за размер, нека започнем с получаване на метаданните на колоната: извлечете списъка със стойности на колоните в променливата за стойности на JSTL и стойността по подразбиране в променливата по подразбиране:
ПОКАЗВАНЕ НА КОЛОНИ ОТ cow_order КАТО 'size'
След това използваме списъка със стойности и стойността по подразбиране, за да конструираме елемента на формуляра. Например, нека създадем група бутони за избор:
Или изскачащо меню:
Обсъжданите изброени методи за генериране на списъци не са свързани с конкретна таблица на базата данни, така че могат да се използват за създаване на елементи на формуляри за всеки тип данни, а не само за тези, които обмисляме за производството на фигурки на крави. Например, за да се позволи на потребителя да избере таблица в приложение за администриране на база данни, може да се създаде списък с възможност за превъртане на имената на всички нейни таблици.
Скриптът CGI.pm може да го направи по следния начин:
моя$table_ref = $dbh->selectcol_arrayref("ПОКАЗВАНЕ НА ТАБЛИЦИ"); печат на превъртащ се списък (-име => "таблица", -стойности => $table_ref, -размер => 10); # показват 10 записа едновременно
Резултатите от заявката дори не трябва да са свързани с таблиците на базата данни. Например, ако искате да покажете списък в JSP страница, съдържащ запис за всеки от последните седем дни, можете да получите тези дати със заявка като тази:
ИЗБЕРЕТЕ DATE_SUB(CURDATE(),INTERVAL 5 DAY),DATE_SUB(CURDATE(),INTERVAL 4 DAY), DATE_SUB(CURDATE(),INTERVAL 3 DAY), DATE_SUB(CURDATE(),INTERVAL 2 DAY), DATE_SUB(CURDATE(),INTERVAL 1 DAY), CURDATE()
След това използвайте датите, за да формирате елемента от списъка:
(Разбира се, ако API предоставя лесен начин за изчисляване на дати, може да е по-ефективно да изброите датите от страна на клиента, без да изпращате заявка до MySQL сървъра.)