from types import DictionaryType, ListType
from sys import stderr
import string
try:
from WebUtils.Funcs import htmlEncode
except ImportError:
from Webware.WebUtils.Funcs import htmlEncode
from BaseTagClasses import HTMLElement
class Choice(HTMLElement):
'''Base class for a single choice in a choice list'''
def __init__( self, value, label, type='select',languageStandard='XHTML'):
HTMLElement.__init__(self,label=label,attributes={},languageStandard=languageStandard)
self._value = value
self._type = type
self._selected = None
self._parentID = None
def _setType(self,type):
self._type = type
def _setSelected(self):
self._selected = 1
def _setUnSelected(self):
self._selected = None
def _setName(self, name):
self._name = name
def _setParentID(self,id):
'''private utility method to set the id of the parent field; useful in deriving ids for each choice tag'''
self._parentID = id
def _generateID(self):
'''Private utility method for generating id attributes for tags'''
parentID = self._parentID
if not parentID:
parentID = "orphanChoice"
return '%s_%s' % ( parentID, htmlEncode( str( self.value() ) ).replace(' ','_') )
def tag(self):
'''Public method to return the HTML tag for the choice'''
if self._type == 'select':
return self._tagSelect()
elif self._type == 'checkbox':
return self._tagCheckbox()
else:
return self._tagRadio()
def _tagSelect(self):
'''Private method responsible for returning the <option> tags used by select boxes'''
tagAttributes = self._tagAttributes()
if tagAttributes and tagAttributes[0] != " ":
tagAttributes = " %s" % tagAttributes
if self._selected:
if self._languageStandard == 'XHTML':
selectedStr = ' selected="selected"'
else:
selectedStr = ' SELECTED'
else:
selectedStr = ''
return '\n\t<option id="%s" value="%s"%s%s>%s</option>' % (
self.id(),
self.value(),
selectedStr,
tagAttributes,
htmlEncode(self.label()) )
def _tagCheckbox(self):
'''Private method responsible for returning checkbox-type <input> tags'''
tagAttributes = self._tagAttributes()
if tagAttributes and tagAttributes[0] != " ":
tagAttributes = " %s" % tagAttributes
if self._languageStandard != 'XHTML':
slashStr = ''
else:
slashStr = ' /'
if self._selected:
if self._languageStandard == 'XHTML':
selectedStr = ' checked="checked"'
else:
selectedStr = ' CHECKED'
else:
selectedStr = ''
return '''<input type="checkbox" id="%s" name="%s" value="%s"%s%s%s>''' % (
self.id(),
self._name,
self.value(),
selectedStr,
tagAttributes,
slashStr,)
def _tagRadio(self):
'''Private method responsible for returning radio-type <input> tags'''
tagAttributes = self._tagAttributes()
if tagAttributes and tagAttributes[0] != " ":
tagAttributes = " %s" % tagAttributes
if self._languageStandard != 'XHTML':
slashStr = ''
else:
slashStr = ' /'
if self._selected:
if self._languageStandard == 'XHTML':
selectedStr = ' checked="checked"'
else:
selectedStr = ' SELECTED'
else:
selectedStr = ''
return '<input type="radio" id="%s" name="%s" value="%s"%s%s%s>' % (
self.id(),
self._name,
self.value(),
selectedStr,
tagAttributes,
slashStr,)
class ChoiceList:
'''This is an abstract class for handling finite lists of options for use in SelectField, CheckboxSet, RadioSet
and related FormKit fields'''
def __init__(self, type='select', languageStandard='XHTML'):
''' '''
assert languageStandard.upper() in ('HTML','XHTML'), "You can only use HTML or XHTML for languageStandard."
self._type = type
self._languageStandard = languageStandard
self._choices = []
self._name = ''
self._parentID = None
def addChoice(self, value, label):
'''Public method: pass in a value, and text label to add a selection to this ChoiceList'''
if value in self.values():
stderr.write('ChoiceList "%s" already contains a value of "%s"' % (self._name or '(unnamed)', value))
return None
else:
tmpChoice = Choice( value, label, self._type, self._languageStandard )
tmpChoice._setParentID( self._parentID )
tmpChoice._setName( self._name )
self._choices.append( tmpChoice )
return tmpChoice
def _setParentID(self,id):
'''Method to set the base id for the choices -- this is normally set automatically
but you can override it on a choice-by-choice basis with the public setID'''
self._parentID = id
for choice in self._choices:
choice._setParentID(id)
def setType(self,type):
'''Public method to set the type of choices you're making: select | radio | checkbox'''
type = type.lower()
assert type in ('select','radio','checkbox'), "You must use one of these types: select, radio, checkbox"
self._type = type
for choice in self.choices():
choice._setType(type)
def _reset(self):
'''clears any selected choice to unselected'''
self.setSelected("")
def setSelected(self,value):
'''Public method to attempt to set this choice list to the choice represented by value'''
for choice in self.choices():
choice._setUnSelected()
if type(value) != ListType:
value = [value]
for v in map(str,value):
try:
strValues = map(str,self.values())
location = strValues.index(v)
self.choices()[location]._setSelected()
except ValueError:
pass
def clear(self):
'''Public method to clear out all the choices'''
self._choices = []
def _setName(self,name):
'''Private method to set the base name for the choices -- this is normally set automatically'''
self._name = name
for choice in self._choices:
choice._setName(name)
def choices(self):
'''Public method to return list of choice objects'''
return self._choices
def values(self):
'''Public convenience method to return a list of possible values'''
tmp = []
for choice in self.choices():
tmp.append( choice.value() )
return tmp
def labels(self):
'''Public convenience method to return a list of possible choice labels'''
tmp = []
for choice in self.choices():
tmp.append( choice.label() )
return tmp