web2py: multiple forms on one page - forms

I am trying to make a form which shows all products from a group in a list. They can be given a quantity and added to a quote. Which is then stored in the database.
None of the automagical form options are working for me. So I've made each row showing information for a given product with the Quantity box and an add item button it's own form. But the loop which makes each form is doing something strange.
Controller:
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")`
For 2 rows. The View has the below 2 forms, with only one hidden div with the formkey and formname. So I can't name the forms in order to process them properly:
<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>
How do I give the forms individual names (preferably product.id)?
I tried adding the formname argument:
form.accepts(request, session, formname=product.id)
But this only names one form and the other is still named 'Default'.

In your code, you create multiple forms in the for loop, but after exiting the loop, you call form.accepts(). At that point, the value of form is the last form created in the loop, so only that form is processed.
Note, when a form is initially created, the form.accepts (or the preferred form.process) method adds the _formname and _formkey hidden fields to the form (these are used for CSRF protection). When that same method is called after form submission, it additionally handles form validation. So, given your workflow, you must process all the forms both at creation and submission. Maybe something like this:
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)

Related

EF Core 6 randomly and rarely inserts multiple records

On a simple form, with one textbox not readonly, I am getting multiple records generated which are identical except for the Id and UpdatedDate. I am using Entity Framework Core 6 and Razor Pages. This occurs only once every few hundred entries. Any thoughts?
I am entering the date like this:
Rate.UpdatedDate = DateTime.Now;
where Rate is the model I am binding to. I am saving changes with:
_context.MedBAmounts.Add(Rate);
await _context.SaveChangesAsync();
<td class="form-group" style="width:7%">
<label asp-for="Rate.NewAmount" class="control-label"></label>
<select asp-for="Rate.NewAmount" id="newRate" class="form-control">
<option>164.90</option>
<option>230.80</option>
<option>329.70</option>
<option>428.60</option>
<option>527.50</option>
<option>560.50</option>
</select>
</td>
<td class="form-group" style="width:6%">
<input type="submit" value="Save" class="btn btn-primary" asp-route- mode="#Model.Mode" style="margin-top:15px; padding:5px;" />
</td>
I am getting:
Two Ids, UpdateDate off by 1 second and same NewAmount. (https://i.stack.imgur.com/2IIdr.png)

How to update multiple objects by one html request?

I have a problem and can't find a decision.
I need to update a value for several objects by one form. If I did it one by one, without submit button it works fine. But I want to do it by click to one button.
My HTML form:
<form method="post" action="{% url 'installmentreport-update' %}">
{% for installmentreport in installment.installmentreport_set.all %}
<tr>
<td class="align-middle" style="text-align:center">{{installmentreport.title}}</td>
<td class="align-middle" style="text-align:center">
{% csrf_token %}
<input type="number" name='spent' value={{installmentreport.spent}} placeholder={{installmentreport.spent}} size="8">
<input type="hidden" name='id' value={{installment.id}}></td>
<input type="hidden" name='pk' value={{installmentreport.id}}>
</tr>
{% endfor %}
<td></td>
<td class="align-middle" style="text-align:center"><input type="submit" class="btn btn-warning" name="submit" value="Update"></form>
Views:
class InstallmentReportUpdate(LoginRequiredMixin,PermissionRequiredMixin,UpdateView):
model = InstallmentReport
permission_required = 'catalog.can_change_program'
fields = ['spent']
def get_object(self):
pks = self.request.POST.getlist('pk')
for pk in pks:
return InstallmentReport.objects.get(pk=pk)
def form_valid(self, form):
if self.request.method == 'POST':
spents = self.request.POST.getlist('spent')
if form.is_valid():
for spent in spents:
instance = form.save(commit=False)
form.instance.spent = spent
instance.save()
return super().form_valid(form)
def get_success_url(self):
id = self.request.POST.get('id')
return reverse('installment-detail-owner', args=[str(id)])
I use Python3.7 and Django2.2
I did it!
Views:
def get_object(self):
pks=self.request.POST.getlist('pk')
spents = self.request.POST.getlist('spent')
for pk, spent in zip(pks,spents):
print(pk)
print(spent)
InstallmentReport.objects.filter(pk=pk).update(spent=spent)
return InstallmentReport.objects.get(pk=pk)

Powermail: create fields from entries in database

My problem:
i need a matrix of fields in Powermail:
product_1 - price_1 - number_1
product_2 - price_2 - number_2
product_3 - price_3 - number_3
and so on. No problem to create this fields manually, but i need it derived from a database. The numbers of lines depends on the number of entries in the database.
is there a possibility to create fields "on the fly", perhaps by typoscript or a userfunc?
Thanks!
I would create a new field type an call it (e.g.) productsheet. In the manual there is an example how to do it: https://docs.typo3.org/typo3cms/extensions/powermail/ForDevelopers/AddNewFields/Index.html
Here two example page TSConfig lines for the new field:
# Add new fields
tx_powermail.flexForm.type.addFieldOptions.productsheet = Product Fields
tx_powermail.flexForm.type.addFieldOptions.productsheet.dataType = 1
Here is an example Productsheet.html partial file for this:
{namespace vh=In2code\Powermail\ViewHelpers}
<h2><vh:string.escapeLabels>{field.title}</vh:string.escapeLabels><f:if condition="{field.mandatory}"><span class="mandatory">*</span></f:if></h2>
<table>
<thead>
<tr>
<th scope="col">Menge</th>
<th scope="col">Artikel Nr.</th>
<th scope="col">Bezeichnung</th>
<th scope="col">Preis Fr./m</th>
</tr>
</thead>
<tbody>
<f:for each="{0:1,1:2,2:3,3:4,4:5,5:6,6:7,7:8,8:9,9:10}" as="key">
<tr>
<td>
<f:form.textfield type="number" class="mdl-textfield__input " name="field[{field.marker}][amount_{key}]" value="" />
</td>
<td>
<f:form.textfield class="mdl-textfield__input " name="field[{field.marker}][article_no_{key}]" value="" />
</td>
<td>
<f:form.textfield class="mdl-textfield__input " name="field[{field.marker}][description_{key}]" value="" />
</td>
<td>
<f:form.textfield class="mdl-textfield__input " name="field[{field.marker}][price_{key}]" value="" />
</td>
</tr>
</f:for>
</tbody>
</table>
Next step would be to insert fields - as you wrote - on the fly. So what about inserting an own viewhelper instead of defining a hardcoded array in the
Now you could prefill the fields with value="" by your own.
Hope that helps
You can use the TypoScript field of powermail to generate code from typoscript.
You can also use your own field type like discribed here with page TSConfig:
tx_powermail.flexForm.type.addFieldOptions.new = New Field
# The label could also be written with LLL: to localize the label
# Example to grab a value from locallang.xml or locallang.xlf
#tx_powermail.flexForm.type.addFieldOptions.new = LLL:EXT:ext/Resources/Private/Language/locallang.xlf:label
# Tell powermail that the new fieldtype will transmit anything else then a string (0:string, 1:array, 2:date, 3:file)
# Example for dataType array
#tx_powermail.flexForm.type.addFieldOptions.new.dataType = 1
# The new field is not just a "show some text" field. It's a field where the user can send values and powermail stores the values?
# You can tell powermail that this new field should be exportable in backend module and via CommandController
#tx_powermail.flexForm.type.addFieldOptions.new.export = 1
newis the field identifier. Powermail search by default for a partial with the identifier name e.g. New.html.
Now you can use a ViewHelper to get the data and create the html for the fields.

Submitting a Form using Jquery

Okay so I am converting some code to jQuery and currently the js is just changing the focus to a button with the target id using whenever you press enter or double click in a <select> tag. document.getElementById.focus() and then document.getElementById.click() and returning true to submit this form. Just looking for some example on how to do same thing using jQuery instead. I understand that there is a .keypress() and a .dblclick() function in jQuery and thats what I think I should be using but passing the values of the input box or the select values are a little difficult since there are multiples of each in the form. FYI this is a search page that sends SQL to an oracle database.
Update-
$(document).ready(function(){
$('form').submit(function(){
$(this).keypress()
if(event.which ==13){
}
});
});
This is what i have so far not sure if i am on the right track or not.
so here is an example of how the form is.
<form>
<tr>
<td nowrap="nowrap"><b> Search by Number </b></td>
<td style="vertical-align:top"><input type="text" name="revisor_number" value=revisor_number>" size="55" maxlength="100" /><br/><span style="font-size:75%">commas between numbers (10,15,20), dash for range(10-20)</span><br/></td>
<td> <input type="submit" name="submit_number" id="submit_number" value="GO"/></td>
</tr>
<tr>
<td style="vertical-align:top" nowrap="nowrap"><b> Search by Type </b></td>
<td>
<select name="subtype[]" size="3" multiple="multiple" onkeypress="keyPress(event, 'submit_subtype');" ondblclick="keyPress(event, 'submit_subtype');">
<option value="">>--- All ---</option>
<td style="vertical-align:top"> <input type="submit" name="submit_subtype" id="submit_subtype" value="GO"/></td>
You need to move it outside of your submit function, replace it with:
$('input, textarea').keypress(function(e) {
if(e.which == 13) {
$(this).blur();
$('#submit').focus().click();
}
});
Assuming '#submit' is the ID of your button.
I don't know if i understand what you want,
but submitting a form with a button in jQuery is something like :
$('button').on('click', function(){
$('yourForm').submit();
});

ASP.net: How to toggle a checkbox based on a dropdownlist selection

I have a dropdownlist control and it's populated with a list of peoples names from a database. I want to enable a CheckBox control if the user selects a person in the list and disable the checkbox if they select BLANK (also an option in the list).
Here is a portion of my code...
<tr>
<td> <asp:Label ID="lblAssignedTo1" runat="server" Text="Assigned To:"></asp:Label></td>
<td><asp:DropDownList ID="ddlAssignedTo1" runat="server" AppendDataBoundItems="True" DataSourceID="dsAssignedTo" DataTextField="StaffName" DataValueField="StaffID"><asp:ListItem Text="" /></asp:DropDownList></td>
</tr>
<tr>
<td> <asp:Label ID="LabelEmail1" runat="server" Text="Send Email:"></asp:Label>
</td>
<td><asp:CheckBox ID="cbEmail1" runat="server" Checked="true" /></td>
</tr>
The checkbox is a trigger to send an email to the person selected from the list. I want it to default the checkbox to "enabled" if a person is selected from the list to make sure the program I am using is going to send an email later on.
I had a look at http://api.jquery.com/change/ for an example of this, but it's not using a checkbox control, so not sure if it would work. Sorry I am new to jScript.
Thanks in advance
A pure HTML and JavaScript approach would look something like this:
<select id="people">
<option value="">Select One</option>
<option value="person1">Person 1</option>
<option value="person2">Person 2</option>
<option value="person3">Person 3</option>
</select>
<input type="checkbox" name="sendemail" id="sendemail" disabled="disabled" />
$(document).ready(function() {
$('#people').change(function() {
if($(this).val() == '') {
$('#sendemail').attr('disabled', 'disabled');
}
else {
$('#sendemail').removeAttr('disabled');
}
});
});
http://jsfiddle.net/AEXpG/
In terms of your code, just grab the select list and checkbox ClientId and then apply the above jQuery code to them.