Differences between revisions 5 and 6
Revision 5 as of 2005-12-13 04:31:14
Size: 8989
Editor: ZoomQuiet
Comment:
Revision 6 as of 2005-12-13 04:47:35
Size: 9028
Editor: ZoomQuiet
Comment:
Deletions are marked like this. Additions are marked like this.
Line 231: Line 231:
== 讨论 ==
[[Include(/Discuss)]]

Line 233: Line 237:

::-- ZoomQuiet [DateTime(2005-12-11T04:50:15Z)] TableOfContents

1. K3日:发现!

Cheetah 只能组织有模板的页面输出,但是……

  • 对于动态变化的表单,有什么更好的方式来组织?

1.1. Karrigell_QuickForm

[http://www.orionlab.net/karrigell_quickform/Karrigell_QuickForm.html Karrigell_QuickForm] 真的是想要什么就来什么!

  • 刚刚从订阅的[http://sourceforge.net/mailarchive/forum.php?forum=karrigell-main karrigell-main 列表]中看到有人完成了一个 Pear 中 quickform的Karrigell 实现

  • 即有之,则用之!
  • 示例:

       1 from Karrigell_QuickForm import Karrigell_QuickForm
       2 
       3 p = Karrigell_QuickForm('teste','POST','foo.py','Authentication')
       4 p.addElement('text','login')
       5 p.addElement('text','password')
       6 p.addRule('login','required',"Login is required!")
       7 p.addGroup(["submit","botao_enviar","Send"]
       8            ,["reset","botao_limpar","Clear"])
       9 p.display()
    
    6行完成一个标准的登录表单!!!哈哈哈!赞!

attachment:snap-KwDay30.png

1.1.1. 改造

毕竟是 alpha 版本,居然还是全面的table 结构!

  • 代码也很ugly 哪!使用["Leo"]整理后

    attachment:snap-KwDay3Leo.png

  • 立即改造!

       1 def addRadioGroup(self,name,value):
       2         """add a radio element - addRadioGroup('genre',{'male':'Male','female':'Female'})"""
       3         self.form_list.append("<tr><td align='right' valign='top'><b>"+name.title().replace('_',' ')+":</b></td> <td valign='top' align='left'>")
       4         radio = ""
       5         t = value.items()
       6         for a,b in t:
       7             radio = radio + "<input type='radio' name='"+name+"' value='"+a+"'>"+"<label><font face=verdana size=2>"+b+"</font></label><br>"
       8         self.form_list.append(radio+"</td>")
       9         self.form_list.append("</tr>")
    

    増补为:

       1 def addRadioList(self,name,desc,value,id=""):
       2         """add a radio element export as UL LI group
       3     """
       4     htm = """
       5         <li id='%s'><b>%s:</b>
       6             <ul>"""
       7     self.form_list.append(htm%(id,desc))
       8     radio = ""
       9     t = value.items()
      10     tmpl = """<li>
      11         <input type='radio' 
      12         name='%s' 
      13         value='%s'>  
      14         <label>%s</label>      
      15         """        
      16     for a,b in t:
      17         radio = radio + tmpl%(name,a,b)
      18     self.form_list.append(radio+"</ul></li>")
    

1.1.2. 利用

直接将昨天的展示函式修改一下子就应该好用的!

  • def expage(dict): 对应的修改为:

   1 def qpubish(dict):
   2     exp = ""
   3     p = Karrigell_QuickForm('fm_kq','POST','#',dict.desc.desc)
   4     
   5     p.addElement('node','<ul>','')
   6     # 深入数据 基本和昨天的一样,仅仅是输出时使用 Karrigell_QuickForm 对象而已
   7     qli = {}
   8     k = [int(i) for i in dict.ask.keys()]
   9     k.sort()
  10     for i in k:
  11         ask = dict.ask[str(i)]
  12         qk = [j for j in ask.keys()]
  13         qk.sort()
  14         for q in qk:
  15             if 1==len(q):
  16                 qli[q] = ask[q]
  17             else:
  18                 pass        
  19         p.addRadioList("cr_ask%s"%i
  20                    ,ask["question"]
  21                    ,qli)
  22     p.addElement('node','</ul>','')
  23     p.addGroup(["submit","btn_submit","提交"]
  24                ,["reset","btn_reset","重写"])
  • 注意到原先的 Karrigell_QuickForm 只有display(),要求直接输出,但是你需要进一步的HTML 处理

  • 所以有了

       1 def export(self):
       2     """ export the html form code so people can do something for them self
       3     """
       4     exp = ""
       5     ...
       6     for c in self.css_list:
       7         exp += c+"\n"
       8     for i in self.form_list:
       9         exp += i+"\n"
      10     return exp
    

    基本上就是将原先的 print 替换为 exp+= 记录为字串对象然后返回

  • 还有def addElement(self,element,name,options=None): 中追加更自由的任何HTML 节点输出:

            elif element == 'node':
                self.form_list.append(name)

1.2. JS 问题

一切顺心,表单正确生成了,但是,Karrigell_QuickForm 提供的JS检验不支持Radio列表的!

  • 呜乎哀哉!!这是个问题哪!如果不是所有问题回答完就提交的话
    • 交给服务端检验,浪费带宽!你还要记录上次的问题情况,返回/提示/重答
    • 不检验,则没有办法进行统计

1.2.1. 继续发现!

现在的问题是有什么现成的可以模式化的定义表单测验的JS组件?

  • 致力于 Python 的Ajax框架开发的 [http://www.amowa.net AMOWA]团队作品,值得期待!使用之!

1.2.2. 关键代码

JVF的使用很有个性,使用外部的XML 文件进行设置,标准的J2EE行为哪!

  • 所以,对应的增补Karrigell_QuickForm

    1. addJSRule() 追加专门的JVF 规则

         1     def addJSRule(self,name,message):
         2         """add a xml rule for javascript checking
         3         """
         4         exp = self.JSvMXLnode%(name,message)
         5         self.JSvRules.append(exp)
      
    2. addJSValidation() 追加调用JVF的页面行为

         1     def addJSValidation(self):
         2         """add a javascript rule in order to validate a form field  
         3         - addRule('elem_name','required','Name is required!')
         4         """
         5         orig = "enctype='multipart/form-data'"
         6         repl = """
         7             onsubmit='return doValidate("%s");'
         8             """ 
         9         begin_form=self.form_list[0].replace(orig
        10                                      ,repl%self.name) 
        11         self.form_list[0] = begin_form
      
    3. saveJSRule() 记录规则集合为JVF需要的XML

         1     def saveJSRule(self,xml):
         2         """exp and save a xml rule for javascript checking
         3         """
         4         exp = ""
         5         for node in self.JSvRules:
         6             exp+= node
         7         #exp = self.JSvXMLtmpl%(form,exp)
         8         open(xml,'w').write(self.JSvXMLtmpl%(self.name
         9                                              ,exp)
        10                                              )
      
    4. 对应的KQF中有预设对象

      self.JSvXMLtmpl="""<?xml version="1.0" encoding="utf-8"?>
      <!DOCTYPE validation-config SYSTEM "validation-config.dtd">
      <validation-config lang="auto"> 
              <form id="%s" show-error="errorMessage" onfail="" 
              show-type="first">
          %s
              </form>
      </validation-config>
      """
      self.JSvMXLnode = """
                      <field name="%s" 
                      display-name="%s" onfail="">
                              <depend name="required" />
                      </field>
      """
      self.JSvRules = []

1.2.3. 果然不出所料

仅仅追加少量代码就完成所想的客户端JS验证功能

def qpubish(dict):
    ...
    ## 具体问题解析
    k.sort()
    for i in k:
        ...
        p.addJSRule("cr_ask%s"%i,"问题%s "%i)
    ## 整体行为处理
    p.addJSValidation()
    p.saveJSRule("js/validation-config.xml")
    
    p.addElement('node','</ul>','')
  • 果然不出所料 没有任何悬念的完成任务!

attachment:snap-KwDay31.png

1.2.4. 迁就,先!

1.3. 滥用Leo

到现在页面都是白丁!不能忍了!加载CSS!

  • 不清楚KarriGell 的页面引用效率,直接将CSS,写入页面好了,反正有["Leo"]来维护

    • 每一需要CSS美化的页面都加<<k_base>> 引用,

    • 引用都是从复用代码 中clone 过来的同一节点

    • 包含的就是k_base.css 你以往积累的一个通用兰色基调的CSS

attachment:snap-KwDay3css.png

1.4. 小节

今天发现并引入了 [http://www.orionlab.net/karrigell_quickform/Karrigell_QuickForm.html KQF]和 [http://www.amowa.net/jsvalidation/ JVF]好象有点复杂的样子……

  • 现在所有的基本功能都有了,接下来的就是要实用化:
    1. 有用户验证,要登录
    2. 多问卷选择/回答/编辑

1.5. 实例下载

使用 [wiki:self/AllAboutSubversion SVN 下载]:

  • [wiki:selfsvn/zqlib/trunk/zqlib/tangle/zoomq/Karrigell/obpKWD/KwDay3/ KwDay3实例]

1.6. 讨论

Include(/Discuss)


返回 KarrigellWebDev -- 快速体验K开发

KwDay3 (last edited 2009-12-25 07:18:00 by localhost)