2016-11-07 59 views
1

我正在尝试制作一个窗体,显示列表中的所有产品。可以给他们一个数量并添加到报价中。然后将其存储在数据库中。web2py:在一个页面上的多个表格

没有自动化表单选项适用于我。所以我已经使每行显示给定产品的信息和数量框以及添加项目按钮是它自己的形式。但是使每种形式的循环都在做一些奇怪的事情。

控制器:

products = db(db.product.group_id == productgroupnumber).select() 
forms=[] 
for product in products: 
    form = FORM(TABLE(TR(TD(product.productname), 
         TD((product.purchasecost or 0)), 
         TD((product.monthlycost or 0)), 
         TD(INPUT(_type='number', _name='quantity')), 
         TD(INPUT(_type='submit', _value=T('Add to Offer'))) 
         ) 
        ) 
       ) 
    forms.append(form) 

session.quotedproducts = [] 
if form.accepts(request, session, keepvalues = True): 
    product = db(db.product.id == product_id).select().first() 
    offeritem = [product_id, request.vars.quantity, product.purchasecost, product.monthlycost] 
    session.quotedproducts.append(offeritem) 
    response.flash = T("Item added to offer")` 

对于2行。该视图具有以下2种形式,只有一个带formkey和formname的隐藏div。所以我不能命名表格以便正确处理它们:

<form action="#" enctype="multipart/form-data" method="post"> 
    <table> 
     <tr> 
      <td>Block of 10 Phone Numbers</td> 
      <td>19.0</td> 
      <td>0</td> 
      <td><input name="quantity" type="number" /></td> 
      <td><input type="submit" value="Add to Offer" /></td> 
     </tr> 
    </table> 
</form>  

<form action="#" enctype="multipart/form-data" method="post"> 
    <table> 
     <tr> 
      <td>100 Block of Phone Numbers</td> 
      <td>149.0</td> 
      <td>0</td> 
      <td><input name="quantity" type="number" /></td> 
      <td><input type="submit" value="Add to Offer" /></td> 
     </tr> 
    </table> 

<!--Why is there only one of these??--> 
    <div style="display:none;"> 
     <input name="_formkey" type="hidden" value="b99bea37-f107-47f0-9b1b-9033c15e1193" /> 
     <input name="_formname" type="hidden" value="default" /> 
    </div> 
</form> 

如何为表单提供个人名称(最好是product.id)? 我尝试添加表格名称参数:

form.accepts(request, session, formname=product.id) 

但是,这只是一个名称的形式和其他的仍命名为“默认”。

+0

用户应该能够同时提交多个表单,还是单个提交中只包含一个表单? – Anthony

+0

只有一个表单。所以一行有一个数量字段和一个“添加到报价”按钮。一次只能添加产品。 – Eddie

回答

0

在您的代码中,您在for循环中创建了多个表单,但在退出循环后,请致电form.accepts()。此时,form的值是循环中创建的最后一个表单,因此只处理该表单。

注意,当最初创建一个形式中,所述form.accepts(或优选form.process)方法增加了_formname_formkey隐藏字段的形式(这些被用于CSRF保护)。当表单提交后调用相同的方法时,它还处理表单验证。因此,考虑到您的工作流程,您必须在创建和提交时处理所有表单。可能是这样的:

products = db(db.product.group_id == productgroupnumber).select() 
forms = [] 
for product in products: 
    quantity_name = 'quantity_%s' % product.id 
    form = FORM(TABLE(TR(TD(product.productname), 
         TD((product.purchasecost or 0)), 
         TD((product.monthlycost or 0)), 
         TD(INPUT(_type='number', _name=quantity_name)), 
         TD(INPUT(_type='submit', _value=T('Add to Offer'))) 
         ) 
        ) 
       ) 
    if form.process(formname=product.id, keepvalues=True).accepted: 
     offeritem = [product.id, form.vars[quantity_name], 
        product.purchasecost, product.monthlycost] 
     session.quotedproducts.append(offeritem) 
     response.flash = T("Item added to offer") 
    forms.append(form) 
+0

啊我明白了。谢谢,这回答了这个问题。 – Eddie

+0

您提到处理提交的表单也。我有表单命名。但是,'Form'变量只存在于创建循环的范围内。如何在提交时再次处理它们? – Eddie

+0

表单被提交给生成它们的相同动作,所以相同的代码处理提交。当在创建时调用'form.process()'时,它会为表单生成隐藏的'_formname'和'_formkey'字段。在提交时调用相同的方法时,它会检查'_formkey'字段并验证表单。 – Anthony