这是一个使用z3c.form创建多页向导的库。值在向导完成前存储在会话中。
项目描述
简介
该库实现了一个简单的基于z3c.form的向导。向导由多个步骤组成。每个步骤都是一个表单。数据在用户点击最后一个步骤上的完成按钮之前存储在会话中。
为了充分利用这个库,您首先需要对z3c.form有合理的了解。以下是一些开始的地方
Stephan Richter在Plone Conference 2008上的教程幻灯片:http://svn.zope.org/*checkout*/z3c.talk/trunk/Z3CForms/Z3CForms.html?rev=92118
向导步骤
向导步骤是一个带有一些额外功能的正常z3c.form表单。
默认情况下,此表单访问的内容将是向导会话中的一个字典,其键等于步骤的前缀。
其他属性
- wizard
此步骤正在使用的向导。
- available
布尔值,表示当前步骤是否可以通过向导导航链接访问。默认情况下,只有已经存储在会话中的数据的步骤可以访问。(无论此属性的值如何,都可以通过相应的按钮访问下一个和上一个步骤。)
- completed
布尔值,表示是否允许用户进入下一个步骤。默认为True。如果为False,则“继续”按钮将被禁用。
- cssid
字符串。为表单标签提供的用户定义的CSS id。
其他方法
- applyChanges(data)
将此步骤的更改保存到其内容(通常是向导会话中的PersistentDict)。
- load(context)
根据上下文加载此步骤的会话数据。
- apply(context)
根据此步骤的会话数据更新上下文。
向导组步骤
与向导步骤相同;它只是像z3c.form GroupForm一样处理一组组。
其他属性
- groups
您希望以单独的字段集显示在表单中的组列表。
向导
向导也是一个表单,其中包含步骤列表和在这些步骤之间移动的内置逻辑。
类属性。重写这些属性以影响向导的行为
- steps
当调用向导的更新方法时将实例化的步骤类序列。
- sessionKey
返回此向导实例使用的唯一会话键。默认情况下,这是“collective.z3cform.wizard”和向导的URL路径的元组。
在更新方法期间设置的属性
- activeSteps
一系列向导步骤实例。
- currentStep
当前正在显示的向导步骤实例。
- currentIndex
当前步骤在activeSteps序列中的(基于0)索引。
- session
在此向导中持久化数据会话。
- onFirstStep
布尔值。如果是向导的第一个步骤正在显示,则为True。
- onLastStep
布尔值。如果是向导的最后一个步骤正在显示,则为True。
- allStepsFinished
布尔值。如果每个向导步骤的“available”属性为True,则为True。
- finished
布尔值。如果向导已经完成,则为True。
- absolute_url
向导的URL。
- validate_back
布尔值。如果您想当用户在步骤上使用“后退”按钮时验证向导的输入,则为True。如果不这样做,则放弃所有用户输入(数据)。默认行为是True。[Spanky]
方法
- initialize()
在给定会话中第一次查看向导时调用。
此方法可以用于将数据从某些来源填充到会话中。
默认实现调用loadSteps方法。
- loadSteps(context)
从上下文加载向导会话数据。
默认实现调用每个向导步骤的“load”方法。
- finish()
在成功完成向导并在验证最后一个步骤之后调用。
使用此方法执行一些基于在完成向导期间填写的数据的操作。
默认实现调用applySteps方法。
- applySteps(context)
根据向导会话数据更新上下文。
默认实现调用每个向导步骤的“apply”方法。
- sync()
将会话标记为已更改,以确保更改得到持久化。这是必需的,因为我们没有使用持久化感知字典类来处理我们的会话变量。
兼容性
此包已在Zope 2.10与Plone 3.3,以及Zope 2.12与Plone 4中进行测试。
在其他由z3c.form支持的平台上使用它应该相当简单,例如Zope 3,但需要熟悉这些环境的人告诉我如何处理会话,例如。
致谢
此包受到了集体.singing包中包含的基于非会话的z3c.form向导的启发,该向导由Daniel Nouri实现。
会话支持、其他改进和重新打包由David Glick完成。
还要感谢Nathan van Gheem、Laurence Rowe和Tom “Spanky” Kapanka。
变更日志
1.4.8 (2013-04-18)
修复了适用于Plone 4.3的pagetemplate导入。[jone]
添加了中文翻译。[jianaijun]
现在清除操作会更新活动步骤(需要覆盖动态向导)[gotcha, schminitz]
修复了动态向导中步骤数据的初始加载情况(例如,当步骤依赖于用户数据时)[gotcha, schminitz]
在子类中启用覆盖按钮条件。[gotcha]
在wizard.Wizard中,如果self.__name__为None,则absolute_url属性将抛出TypeError。不再是这样了!现在的问题是在那种情况下absolute_url将不准确。待办事项[spanky]
添加了法语翻译。[mpeeters]
1.4.7 (2012-01-05)
添加了使用Back按钮跳过当前输入验证的能力。默认设置保持不变。[spanky]
将“id”作为表单标签的属性。[spanky]
1.4.6 (2011-10-19)
添加了西班牙语翻译。[davisagli]
1.4.5 (2011-10-19)
确保向导步骤标签已翻译。[davisagli]
1.4.4 (2011-10-17)
避免使用any()以恢复与Python 2.4的兼容性。[davisagli]
1.4.3 (2011-07-13)
在确定用户是否已离开向导时,不计入浏览器视图。[davisagli]
1.4.2 (2011-05-04)
修复了AutoWizard小部件遍历器的注册。[elro]
1.4.1 (2011-05-04)
添加了与plone.autoform一起使用的AutoWizard。[elro]
添加了一个清除按钮,该按钮清除会话并返回到步骤1。[elro]
重新排序按钮,使完成和继续都出现在后退之前。[elro]
1.4 (2011-05-04)
删除<hr />[elro]
使用Products.statusmessages。[elro]
调整wizard-buttons以符合标准plone formControls。[elro]
从wizard-step.pt中删除div.row。[elro]
1.3.3 (2011-03-22)
在比较URL时标准化@@视图前缀。[davisagli]
1.3.2 (2010-07-27)
删除多余的调试语句。[khink]
1.3.1 (2010-06-28)
避免在plone.app.z3cform的行内验证期间破坏会话。[davisagli]
1.3 (2010-06-23)
避免在安装plone.app.z3cform的行内验证时出错。[davisagli]
1.2 (2010-04-08)
添加了一个GroupStep,用于类似于GroupForm的集成。[vangheem]
1.1 (2010-03-01)
确保如果步骤通过按Enter键提交,则下一步按钮是默认的。
1.0 (2010-01-19)
在表单标签中包含表单的enctype。
在遍历表单到其他事物(如小部件)时不要清除会话。
1.0b2(2009-06-25)
将默认向导CSS移动到浏览器资源,该资源可用但默认情况下不会引入。
调整完成按钮的可见性标准,以便在所有步骤的数据都存储在会话中时,它将显示在任何步骤上。以前它只显示在最终步骤上。
添加了向导导航,列出了向导的步骤,并链接到可用的步骤。
在Wizard类中添加了对基于请求中传递的索引跳转到特定步骤的支持(但只有当该步骤可用时)。
调整触发会话无效化的URL检查,以便不关注查询字符串或片段。
将Wizard类的updateCurrentStep方法(不是公共API的一部分)更改为接受单个参数,即目标步骤索引。
向Wizard类添加了‘allStepsFinished’属性。
向Step类添加了‘available’属性。
向Wizard类添加了‘absolute_url’属性。
如果您在完成之前离开,请重置向导会话。
1.0b1 (2009-05-12)
初始发布
示例和测试
定义包含三个步骤的向导
要定义一个使用向导的表单,我们需要定义步骤。这些步骤代表被顺序处理的单个表单。只有当最后一个步骤完成后,数据将通过用户定义的方法提交。
>>> from zope import schema >>> from z3c.form import field, form >>> from collective.z3cform.wizard import wizard >>> from plone.z3cform.fieldsets import group >>> from Products.statusmessages.interfaces import IStatusMessage >>> from Products.statusmessages.adapter import _decodeCookieValue>>> class StepOne(wizard.Step): ... prefix = 'one' ... fields = field.Fields( ... schema.Int(__name__='age', title=u"Age"))
默认情况下,步骤将在会话中获取/设置值。如果我们想在向导完成后初始化这些值或对它们进行某些操作,我们需要为我们的步骤实现加载和应用方法。
>>> from pprint import pprint >>> class StepTwo(wizard.Step): ... prefix = 'two' ... fields = field.Fields( ... schema.TextLine(__name__='name', title=u"Name", required=True), ... schema.TextLine(__name__='beer', title=u'Favorite Beer', required=True)) ... ... def load(self, context): ... data = self.getContent() ... data['name'] = 'David' ... ... def apply(self, context): ... data = self.getContent() ... pprint('Name from step 2: %s' % data['name'])
我们还可以进行分组步骤
>>> class AddressGroup(group.Group): ... fields = field.Fields( ... schema.TextLine(__name__='address', title=u'Address', required=False), ... schema.TextLine(__name__='city', title=u'City', required=False), ... schema.TextLine(__name__='state', title=u'State', required=False)) ... label = u"Address Information" ... prefix = 'address'>>> class StepThree(wizard.GroupStep): ... prefix = 'three' ... fields = field.Fields() ... groups = [AddressGroup]
现在我们可以定义我们的最小向导
>>> class Wizard(wizard.Wizard): ... label = u"My silly wizard" ... steps = StepOne, StepTwo, StepThree
渲染表单
现在让我们第一次渲染表单
>>> request = TestRequest() >>> wizard = Wizard(None, request) >>> print wizard() <... <div class="form" id="wizard-step-one"> <form action="http://127.0.0.1" method="post" class="rowlike enableUnloadProtection kssattr-formname-127.0.0.1" id="one" enctype="multipart/form-data"> <p class="discreet"></p> <div class="field"> <label for="one-widgets-age"> <span>Age</span> </label>... <span class="fieldRequired" title="Required"> (Required) </span> <div class="widget"> <input id="one-widgets-age" name="one.widgets.age" class="text-widget required int-field" value="" type="text" /> </div> </div> <div class="formControls wizard-buttons"> <input id="form-buttons-continue" name="form.buttons.continue" class="submit-widget button-field" value="Continue" type="submit" /> <input id="form-buttons-clear" name="form.buttons.clear" class="submit-widget button-field" value="Clear" type="submit" /> </div> </form> </div>
提交时出现错误
请记住,我们的第一步需要年龄。
>>> request.form = { ... 'form.buttons.continue': u'Continue', ... } >>> wizard = Wizard(None, request)>>> print wizard() <... ...Required input is missing...>>> messages = _decodeCookieValue(request.__annotations__.pop('statusmessages')) >>> [(m.message, m.type) for m in messages] [(u'There were errors.', u'error')]
成功提交第一步
>>> request.form['one.widgets.age'] = u'27' >>> wizard = Wizard(None, request) >>> print wizard() <... <div class="form" id="wizard-step-two"> <form action="http://127.0.0.1" method="post" class="rowlike enableUnloadProtection kssattr-formname-127.0.0.1" id="two" enctype="multipart/form-data"> <p class="discreet"></p> <div class="field"> <label for="two-widgets-name"> <span>Name</span> </label> <span class="fieldRequired" title="Required"> (Required) </span> <div class="widget"> <input id="two-widgets-name" name="two.widgets.name" class="text-widget required textline-field" value="David" type="text" /> </div> </div> <div class="field"> <label for="two-widgets-beer"> <span>Favorite Beer</span> </label> <span class="fieldRequired" title="Required"> (Required) </span> <div class="widget"> <input id="two-widgets-beer" name="two.widgets.beer" class="text-widget required textline-field" value="" type="text" /> </div> </div> <div class="formControls wizard-buttons"> <input id="form-buttons-continue" name="form.buttons.continue" class="submit-widget button-field" value="Continue" type="submit" /> <input id="form-buttons-back" name="form.buttons.back" class="submit-widget button-field" value="Back" type="submit" /> <input id="form-buttons-clear" name="form.buttons.clear" class="submit-widget button-field" value="Clear" type="submit" /> </div> </form> </div>
后退
当我们后退时,我们应该得到验证错误,因为我们留下了一个字段为空
>>> del request.form['form.buttons.continue'] >>> request.form['form.buttons.back'] = u'Back' >>> wizard = Wizard(None, request) >>> print wizard() <... ...Required input is missing...>>> messages = _decodeCookieValue(request.__annotations__.pop('statusmessages')) >>> [(m.message, m.type) for m in messages] [(u'There were errors.', u'error')]
现在如果我们把 validate_back 设置为 False,应该可以无错误地后退
>>> request.form['form.buttons.back'] = u'Back' >>> wizard = Wizard(None, request) >>> wizard.validate_back = False >>> html = wizard() >>> 'wizard-step-one' in html True
确保我们回到第二步(再次)
>>> del request.form['form.buttons.back'] >>> request.form['form.buttons.continue'] = u'Continue' >>> wizard = Wizard(None, request) >>> html = wizard() >>> 'wizard-step-two' in html True
提交第二步
填写缺失的值
>>> request.form['two.widgets.beer'] = u'Boont Amber'
第二步工作方式类似
>>> request.form['two.widgets.name'] = u'David' >>> wizard = Wizard(None, request) >>> html = wizard() >>> 'three' in html, 'Address' in html, 'City' in html, 'State' in html, 'Finish' in html (True, True, True, True, True)
第三步:击败巨龙
现在让我们点击完成按钮。我们希望这会打印出第二步的值,归功于我们为该步骤实现的“应用”方法。
记住,在我们的向导中,我们实现了 finish 来打印接收到的数据。这里是终结技
>>> request.form['form.buttons.finish'] = u'Finish' >>> wizard = Wizard(None, request) >>> html = wizard() 'Name from step 2: David'>>> messages = _decodeCookieValue(request.__annotations__.pop('statusmessages')) >>> [(m.message, m.type) for m in messages] [(u'Information submitted successfully.', u'info')]
示例
有关此库在使用的示例,请参阅 collective.megaphone 软件包。
AutoWizard
AutoWizard 从 plone.autoform 字段集创建步骤(包括 plone.supermodel xml 模式中定义的步骤)。
首先,我们定义我们的模式
>>> from plone.supermodel.interfaces import FIELDSETS_KEY >>> from plone.supermodel.model import Fieldset >>> from zope.interface import Interface, taggedValue >>> class IMySchema(Interface): ... age = schema.Int(title=u"Age") ... name = schema.Int(title=u"Name") ... taggedValue(FIELDSETS_KEY, [ ... Fieldset('one', label=u"One from fieldset", fields=['age']), ... Fieldset('two', fields=['name']), ... ])
然后创建 AutoWizard 类
>>> from collective.z3cform.wizard import autowizard >>> class AutoWizard(autowizard.AutoWizard): ... label = u"Automatically silly wizard." ... schema = IMySchema
现在我们可以渲染表单
>>> request = TestRequest() >>> wizard = AutoWizard(None, request) >>> print wizard() <... <div class="form" id="wizard-step-form-one"> <form action="http://127.0.0.1" method="post" class="rowlike enableUnloadProtection kssattr-formname-127.0.0.1" id="form-one" enctype="multipart/form-data"> <h2>One from fieldset</h2> <p class="discreet"></p> <div class="field"> <label for="form-one-widgets-age"> <span>Age</span> </label>... <span class="fieldRequired" title="Required"> (Required) </span> <div class="widget"> <input id="form-one-widgets-age" name="form.one.widgets.age" class="text-widget required int-field" value="" type="text" /> </div> </div> <div class="formControls wizard-buttons"> <input id="form-buttons-continue" name="form.buttons.continue" class="submit-widget button-field" value="Continue" type="submit" /> </div> </form> </div>
否则它的工作方式与标准向导完全相同。
动态向导支持
在某些情况下,根据用户对向导早期步骤的答案,后续步骤将显示或不显示给用户。
>>> from zope import schema >>> from z3c.form import field, form >>> from collective.z3cform.wizard import wizard >>> from plone.z3cform.fieldsets import group >>> from Products.statusmessages.interfaces import IStatusMessage >>> from Products.statusmessages.adapter import _decodeCookieValue
我们定义字段。
>>> choiceField = schema.Choice( ... __name__ = 'choice', ... title=u'Choice', ... values=(u'first', u'second'), ... default=u'first' ... )>>> firstField = schema.TextLine( ... __name__ = 'first', ... title=u'First', ... required=False, ... missing_value=u'', ... )>>> secondField = schema.Bool( ... __name__ = 'second', ... title=u'Second', ... required=False, ... )
然后定义向导步骤。
>>> class FirstStep(wizard.Step): ... label = u'First' ... prefix = 'one' ... fields = field.Fields(firstField) ... ... def load(self, context): ... data = self.getContent() ... data.setdefault('first', u'initial first')>>> class SecondStep(wizard.Step): ... label = u'Second' ... prefix = 'two' ... fields = field.Fields(secondField) ... ... def load(self, context): ... data = self.getContent() ... data['second'] = True>>> class ChoiceStep(wizard.Step): ... label = u'Choice' ... prefix = 'choice' ... fields = field.Fields(choiceField)>>> class SecondChoiceStep(wizard.Step): ... label = u'Second Choice' ... prefix = 'second_choice' ... fields = field.Fields(choiceField)
现在我们可以定义我们的动态向导。向导的后续步骤取决于在初始 ChoiceStep 和 SecondChoiceStep 中提交的值。
steps 是一个计算属性,而不是硬编码的序列。
该类还实现了 showFinish 方法,用于控制显示(或不显示)完成按钮。
>>> class DynamicWizard(wizard.Wizard): ... label = u"My dynamic wizard" ... ... @property ... def choice(self): ... choice_data = self.session.get('choice', {}) ... choice = choice_data.get('choice', None) ... if 'choice.widgets.choice' in self.request.form: ... choice = unicode(self.request.form['choice.widgets.choice'][0]) ... return choice ... ... @property ... def second_choice(self): ... choice_data = self.session.get('second_choice', {}) ... choice = choice_data.get('choice', None) ... if 'second_choice.widgets.choice' in self.request.form: ... choice = unicode(self.request.form['second_choice.widgets.choice'][0]) ... return choice ... ... @property ... def steps(self): ... if self.choice == u'second': ... if not self.second_choice: ... return [ChoiceStep, SecondChoiceStep, FirstStep] ... elif self.second_choice == u'second': ... return [ChoiceStep, SecondChoiceStep, SecondStep] ... else: ... return [ChoiceStep, SecondChoiceStep, FirstStep] ... else: ... return [ChoiceStep, FirstStep] ... ... def showFinish(self): ... return (self.choice == u'first' or self.second_choice) and self.allStepsFinished
渲染表单
现在让我们第一次渲染表单
>>> request = TestRequest() >>> wizard = DynamicWizard(None, request) >>> wizard.update() >>> wizard.currentIndex 0 >>> print wizard.render() <ul class="wizard-steps"> <li class="wizard-step-link selected"> 1. Choice </li> <li class="wizard-step-link"> <a href=".?step:int=1"> 2. First </a> </li> </ul> <div class="form" id="wizard-step-choice"> <form action="http://127.0.0.1" method="post" class="rowlike enableUnloadProtection kssattr-formname-127.0.0.1" id="choice" enctype="multipart/form-data"> <h2>Choice</h2> <p class="discreet"></p> <div class="field"> <label for="choice-widgets-choice"> <span>Choice</span> </label>... <span class="fieldRequired" title="Required"> (Required) </span> <div class="widget"> <select id="choice-widgets-choice" name="choice.widgets.choice:list" class="select-widget required choice-field" size="1"> <option id="choice-widgets-choice-0" value="first" selected="selected">first</option> <option id="choice-widgets-choice-1" value="second">second</option> </select> <input name="choice.widgets.choice-empty-marker" type="hidden" value="1" /> </div> </div> <div class="formControls wizard-buttons"> <input id="form-buttons-continue" name="form.buttons.continue" class="submit-widget button-field" value="Continue" type="submit" /> <input id="form-buttons-clear" name="form.buttons.clear" class="submit-widget button-field" value="Clear" type="submit" /> </div> </form> </div>
成功提交第一个选择
>>> request.form = { ... 'form.buttons.continue': u'Continue', ... 'choice.widgets.choice': [u'first'] ... } >>> wizard = DynamicWizard(None, request) >>> wizard.update() >>> wizard.currentIndex 1 >>> print wizard.render() <ul class="wizard-steps"> <li class="wizard-step-link"> <a href=".?step:int=0"> 1. Choice </a> </li> <li class="wizard-step-link selected"> 2. First </li> </ul> <div class="form" id="wizard-step-one"> <form action="http://127.0.0.1" method="post" class="rowlike enableUnloadProtection kssattr-formname-127.0.0.1" id="one" enctype="multipart/form-data"> <h2>First</h2> <p class="discreet"></p> <div class="field"> <label for="one-widgets-first"> <span>First</span> </label> <div class="widget"> <input id="one-widgets-first" name="one.widgets.first" class="text-widget textline-field" value="initial first" type="text" /> </div> </div> <div class="formControls wizard-buttons"> <input id="form-buttons-finish" name="form.buttons.finish" class="submit-widget button-field" value="Finish" type="submit" /> <input id="form-buttons-back" name="form.buttons.back" class="submit-widget button-field" value="Back" type="submit" /> <input id="form-buttons-clear" name="form.buttons.clear" class="submit-widget button-field" value="Clear" type="submit" /> </div> </form> </div>
后退
>>> del request.form['form.buttons.continue'] >>> request.form['form.buttons.back'] = u'Back' >>> wizard = DynamicWizard(None, request) >>> wizard.update() >>> wizard.currentIndex 0 >>> print wizard.render() <ul class="wizard-steps"> <li class="wizard-step-link selected"> 1. Choice </li> <li class="wizard-step-link"> <a href=".?step:int=1"> 2. First </a> </li> </ul> <div class="form" id="wizard-step-choice"> <form action="http://127.0.0.1" method="post" class="rowlike enableUnloadProtection kssattr-formname-127.0.0.1" id="choice" enctype="multipart/form-data"> <h2>Choice</h2> <p class="discreet"></p> <div class="field"> <label for="choice-widgets-choice"> <span>Choice</span> </label> <span class="fieldRequired" title="Required"> (Required) </span> <div class="widget"> <select id="choice-widgets-choice" name="choice.widgets.choice:list" class="select-widget required choice-field" size="1"> <option id="choice-widgets-choice-0" value="first" selected="selected">first</option> <option id="choice-widgets-choice-1" value="second">second</option> </select> <input name="choice.widgets.choice-empty-marker" type="hidden" value="1" /> </div> </div> <div class="formControls wizard-buttons"> <input id="form-buttons-continue" name="form.buttons.continue" class="submit-widget button-field" value="Continue" type="submit" /> <input id="form-buttons-finish" name="form.buttons.finish" class="submit-widget button-field" value="Finish" type="submit" /> <input id="form-buttons-clear" name="form.buttons.clear" class="submit-widget button-field" value="Clear" type="submit" /> </div> </form> </div>
选择向导的另一个分支
>>> request.form = { ... 'form.buttons.continue': u'Continue', ... 'choice.widgets.choice': [u'second'] ... } >>> wizard = DynamicWizard(None, request) >>> wizard.update() >>> wizard.currentIndex 1 >>> print wizard.render() <ul class="wizard-steps"> <li class="wizard-step-link"> <a href=".?step:int=0"> 1. Choice </a> </li> <li class="wizard-step-link selected"> 2. Second Choice </li> <li class="wizard-step-link"> <a href=".?step:int=2"> 3. First </a> </li> </ul> <div class="form" id="wizard-step-second_choice"> <form action="http://127.0.0.1" method="post" class="rowlike enableUnloadProtection kssattr-formname-127.0.0.1" id="second_choice" enctype="multipart/form-data"> <h2>Second Choice</h2> <p class="discreet"></p> <div class="field"> <label for="second_choice-widgets-choice"> <span>Choice</span> </label> <span class="fieldRequired" title="Required"> (Required) </span> <div class="widget"> <select id="second_choice-widgets-choice" name="second_choice.widgets.choice:list" class="select-widget required choice-field" size="1"> <option id="second_choice-widgets-choice-0" value="first" selected="selected">first</option> <option id="second_choice-widgets-choice-1" value="second">second</option> </select> <input name="second_choice.widgets.choice-empty-marker" type="hidden" value="1" /> </div> </div> <div class="formControls wizard-buttons"> <input id="form-buttons-continue" name="form.buttons.continue" class="submit-widget button-field" value="Continue" type="submit" /> <input id="form-buttons-back" name="form.buttons.back" class="submit-widget button-field" value="Back" type="submit" /> <input id="form-buttons-clear" name="form.buttons.clear" class="submit-widget button-field" value="Clear" type="submit" /> </div> </form> </div>
再次选择
>>> request.form = { ... 'form.buttons.continue': u'Continue', ... 'second_choice.widgets.choice': [u'second'] ... } >>> wizard = DynamicWizard(None, request) >>> wizard.update() >>> wizard.currentIndex 2
初始值实际上是显示的。
>>> print wizard.render() <ul class="wizard-steps"> <li class="wizard-step-link"> <a href=".?step:int=0"> 1. Choice </a> </li> <li class="wizard-step-link"> <a href=".?step:int=1"> 2. Second Choice </a> </li> <li class="wizard-step-link selected"> 3. Second </li> </ul> <div class="form" id="wizard-step-two"> <form action="http://127.0.0.1" method="post" class="rowlike enableUnloadProtection kssattr-formname-127.0.0.1" id="two" enctype="multipart/form-data"> <h2>Second</h2> <p class="discreet"></p> <div class="field"> <label for="two-widgets-second"> <span>Second</span> </label> <div class="widget"> <span class="option"> <label for="two-widgets-second-0"> <input id="two-widgets-second-0" name="two.widgets.second" class="radio-widget bool-field" value="true" checked="checked" type="radio" /> <span class="label">yes</span> </label> </span> <span class="option"> <label for="two-widgets-second-1"> <input id="two-widgets-second-1" name="two.widgets.second" class="radio-widget bool-field" value="false" type="radio" /> <span class="label">no</span> </label> </span> <input name="two.widgets.second-empty-marker" type="hidden" value="1" /> </div> </div> <div class="formControls wizard-buttons"> <input id="form-buttons-finish" name="form.buttons.finish" class="submit-widget button-field" value="Finish" type="submit" /> <input id="form-buttons-back" name="form.buttons.back" class="submit-widget button-field" value="Back" type="submit" /> <input id="form-buttons-clear" name="form.buttons.clear" class="submit-widget button-field" value="Clear" type="submit" /> </div> </form> </div>
清除向导
>>> request.form = { ... 'form.buttons.clear': u'Clear', ... 'second_choice.widgets.choice': [u'second'] ... } >>> wizard = DynamicWizard(None, request) >>> wizard.update() >>> wizard.currentIndex 0 >>> print wizard.render() <ul class="wizard-steps"> <li class="wizard-step-link selected"> 1. Choice </li> <li class="wizard-step-link"> 2. First </li> </ul> <div class="form" id="wizard-step-choice"> <form action="http://127.0.0.1" method="post" class="rowlike enableUnloadProtection kssattr-formname-127.0.0.1" id="choice" enctype="multipart/form-data"> <h2>Choice</h2> <p class="discreet"></p> <div class="field"> <label for="choice-widgets-choice"> <span>Choice</span> </label> <span class="fieldRequired" title="Required"> (Required) </span> <div class="widget"> <select id="choice-widgets-choice" name="choice.widgets.choice:list" class="select-widget required choice-field" size="1"> <option id="choice-widgets-choice-0" value="first" selected="selected">first</option> <option id="choice-widgets-choice-1" value="second">second</option> </select> <input name="choice.widgets.choice-empty-marker" type="hidden" value="1" /> </div> </div> <div class="formControls wizard-buttons"> <input id="form-buttons-continue" name="form.buttons.continue" class="submit-widget button-field" value="Continue" type="submit" /> </div> </form> </div>
项目详情
下载文件
下载适用于您平台的应用程序。如果您不确定要选择哪个,请了解更多关于 安装软件包 的信息。