2016-11-07 4 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 формы, только с одним скрытым 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)? Я попытался добавить FORMNAME аргумент:

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

Смежные вопросы