Differences between revisions 1 and 6 (spanning 5 versions)
Revision 1 as of 2005-12-11 04:50:15
Size: 488
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 7: Line 7:
Line 8: Line 9:
'''Cheetah 只能组织有模板的页面输出,但是……'''
 * 对于动态变化的表单,有什么更好的方式来组织?
Line 10: Line 12:
'''[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 实现
 * 即有之,则用之!
 * 示例:{{{#!python
from Karrigell_QuickForm import Karrigell_QuickForm

p = Karrigell_QuickForm('teste','POST','foo.py','Authentication')
p.addElement('text','login')
p.addElement('text','password')
p.addRule('login','required',"Login is required!")
p.addGroup(["submit","botao_enviar","Send"]
           ,["reset","botao_limpar","Clear"])
p.display()
}}} 6行完成一个标准的登录表单!!!哈哈哈!赞!
attachment:snap-KwDay30.png

=== 改造 ===
'''毕竟是 alpha 版本,居然还是全面的table 结构!'''
 * 代码也很ugly 哪!使用["Leo"]整理后
 attachment:snap-KwDay3Leo.png
 
 * 立即改造!{{{#!python
def addRadioGroup(self,name,value):
 """add a radio element - addRadioGroup('genre',{'male':'Male','female':'Female'})"""
        self.form_list.append("<tr><td align='right' valign='top'><b>"+name.title().replace('_',' ')+":</b></td> <td valign='top' align='left'>")
 radio = ""
        t = value.items()
 for a,b in t:
     radio = radio + "<input type='radio' name='"+name+"' value='"+a+"'>"+"<label><font face=verdana size=2>"+b+"</font></label><br>"
        self.form_list.append(radio+"</td>")
 self.form_list.append("</tr>")
}}} 増补为:{{{#!python
def addRadioList(self,name,desc,value,id=""):
     """add a radio element export as UL LI group
    """
    htm = """
        <li id='%s'><b>%s:</b>
            <ul>"""
    self.form_list.append(htm%(id,desc))
    radio = ""
    t = value.items()
    tmpl = """<li>
        <input type='radio'
        name='%s'
        value='%s'>
        <label>%s</label>
        """
    for a,b in t:
        radio = radio + tmpl%(name,a,b)
    self.form_list.append(radio+"</ul></li>")
}}}

=== 利用 ===
'''直接将昨天的展示函式修改一下子就应该好用的!'''
 * `def expage(dict):` 对应的修改为:
{{{#!python
def qpubish(dict):
    exp = ""
    p = Karrigell_QuickForm('fm_kq','POST','#',dict.desc.desc)
    
    p.addElement('node','<ul>','')
    # 深入数据 基本和昨天的一样,仅仅是输出时使用 Karrigell_QuickForm 对象而已
    qli = {}
    k = [int(i) for i in dict.ask.keys()]
    k.sort()
    for i in k:
        ask = dict.ask[str(i)]
        qk = [j for j in ask.keys()]
        qk.sort()
        for q in qk:
            if 1==len(q):
                qli[q] = ask[q]
            else:
                pass
        p.addRadioList("cr_ask%s"%i
                   ,ask["question"]
                   ,qli)
    p.addElement('node','</ul>','')
    p.addGroup(["submit","btn_submit","提交"]
               ,["reset","btn_reset","重写"])
}}}
 * 注意到原先的 Karrigell_QuickForm 只有display(),要求直接输出,但是你需要进一步的HTML 处理
 * 所以有了{{{#!python
def export(self):
    """ export the html form code so people can do something for them self
    """
    exp = ""
    ...
    for c in self.css_list:
        exp += c+"\n"
    for i in self.form_list:
        exp += i+"\n"
    return exp
    }}} 基本上就是将原先的 `print` 替换为 `exp+=` 记录为字串对象然后返回
 * 还有`def addElement(self,element,name,options=None):` 中追加更自由的任何HTML 节点输出:{{{
        elif element == 'node':
            self.form_list.append(name)
}}}

== JS 问题 ==
'''一切顺心,表单正确生成了,但是,Karrigell_QuickForm 提供的JS检验不支持Radio列表的!'''
 * 呜乎哀哉!!这是个问题哪!如果不是所有问题回答完就提交的话
  * 交给服务端检验,浪费带宽!你还要记录上次的问题情况,返回/提示/重答
  * 不检验,则没有办法进行统计
=== 继续发现! ===
'''现在的问题是有什么现成的可以模式化的定义表单测验的JS组件?'''
 * TiosnG ![ti'aosn'gu]
  * There is one site named Google! -- 哈哈哈!!
  * '''[http://www.amowa.net/jsvalidation/ JavaScript Validation Framework]''' 国人作品!

## [email protected] [email protected]

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

=== 关键代码 ===
'''JVF的使用很有个性,使用外部的XML 文件进行设置,标准的J2EE行为哪!'''
 * 所以,对应的增补Karrigell_QuickForm
  1. addJSRule() 追加专门的JVF 规则{{{#!python
    def addJSRule(self,name,message):
        """add a xml rule for javascript checking
        """
        exp = self.JSvMXLnode%(name,message)
        self.JSvRules.append(exp)
}}}
  1. addJSValidation() 追加调用JVF的页面行为{{{#!python
    def addJSValidation(self):
        """add a javascript rule in order to validate a form field
        - addRule('elem_name','required','Name is required!')
        """
        orig = "enctype='multipart/form-data'"
        repl = """
            onsubmit='return doValidate("%s");'
            """
        begin_form=self.form_list[0].replace(orig
                                     ,repl%self.name)
        self.form_list[0] = begin_form
}}}
  1. saveJSRule() 记录规则集合为JVF需要的XML{{{#!python
    def saveJSRule(self,xml):
        """exp and save a xml rule for javascript checking
        """
        exp = ""
        for node in self.JSvRules:
            exp+= node
        #exp = self.JSvXMLtmpl%(form,exp)
        open(xml,'w').write(self.JSvXMLtmpl%(self.name
                                             ,exp)
                                             )
}}}
  1. 对应的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 = []
}}}

=== 果然不出所料 ===
'''仅仅追加少量代码就完成所想的客户端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
=== 迁就,先! ===
 * 与KarriGell 配合[[FootNote(测试JS 成功引用否的小技巧:`alert("Include KO!");` JS 中加入强制提示看刷页面见分晓!)]],当前需要:
     1. `js=%(base)s/karriweb/js` 这样的专门虚拟目录发布,以便,其它各种应用也可以享受
     1. `var ValidationRoot = "/js/";` JVF 本身也要声明所在目录
     1. {{{
ValidateMethodFactory.validateRequired = function(field, params) {
 ...
 window.location.replace("#errorDiv");
}}} 使用replace 来减少不必要的页面刷新
     1. 使用`p.saveJSRule("../js/validation-config.xml")` 时要对应的修正写入的正确目标文件
 * KQF 对JVF 的迁就:
Line 12: Line 212:
CSS 的交流...

滥用Leo...

'''到现在页面都是白丁!不能忍了!加载CSS!'''
 * 不清楚KarriGell 的页面引用效率,直接将CSS,写入页面好了,反正有["Leo"]来维护
  * 每一需要CSS美化的页面都加`<<k_base>>` 引用,
  * 引用都是从`复用代码` 中clone 过来的同一节点
  * 包含的就是`k_base.css` 你以往积累的一个通用兰色基调的CSS

attachment:snap-KwDay3css.png

== 小节 ==
'''今天发现并引入了 [http://www.orionlab.net/karrigell_quickform/Karrigell_QuickForm.html KQF]和 [http://www.amowa.net/jsvalidation/ JVF]好象有点复杂的样子……'''
 * 现在所有的基本功能都有了,接下来的就是要实用化:
     1. 有用户验证,要登录
     1. 多问卷选择/回答/编辑
     
Line 22: Line 231:
== 讨论 ==
[[Include(/Discuss)]]

::-- 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)