How to have additional fields in SQLFORM that are not in table in web2py? - forms

I have a form for creating new records in a table generated using SQLFORM. One of the fields of the table will not be directly exposed to the user but instead created based on the values of a few other input elements which themselves are not part of the table.
How do I add additional fields to an SQLFORM that are not part of the table and do not need to be part of the database insert? And where would be the place to calculate the non-exposed field before inserting into the database?
(A hypothetical example would be having latitude and longitude coordinate fields in the table but no address field. In this example, would need address field on create form that could be used to geocode and store coordinates in lat/lng fields)

The way I solved this was by using SQLFORM.factory instead of SQLFORM.
1. I extracted the fields defined on my table
fields = [field for field in db.customer]
2. appended the new fields I wanted
fields += [
Field('customer_type','string', label=T('Customer Type'),
requires=IS_IN_SET(customer_types, zero=None, sort=False)),
Field('another_field','string', label=T('Another Field')),
]
3. used SQLFORM.factory to generate the form
form = SQLFORM.factory(
*fields,
formstyle='bootstrap',
_class='customer form-horizontal',
table_name='customer'
)
* note the asterisk before fields is necessary
4. still used form.process().accepted but then calculated what I needed to and then manually handled the database insert
if form.process().accepted:
...
form.vars.some_nonwritable_field = calculate_complicated_value()
db.customer.insert(**db.customer._filter_fields(form.vars))
...
_filter_fields prevents the dynamically added fields from being part of the insert.
This way I could add additional field to the form that were validated but not part of the insert.

In recent versions of web2py you can do it shorter:
form = SQLFORM.factory(
db.table,
Field('my_field_1'),
Field('my_field_2'),
)

Related

How to store DLookup from [Form] to Table Field in MsAccess 2013?

I have two MS Access tables: IdMhs and T_UKT. I want to automatically fill in [IdMhs].[SPP] from some criteria in [T_UKT].[UKT]. I cannot put it in query relationship, because the row cannot be edited on a form.
So I make a form and I get the number SPP (a textbox on form) automatically by using and it works fine:
=DLookUp("SPP";"T_UKT";"UKT = " & [Form].[UKT])
The problem is: the lookup value just shows on the form, and the results are not filled in the field in table ([IdMhs].[SPP]).
Any idea what an expression I should write to fill it in IdMhs table automatically?
Need macro or VBA code to save value into table. If form is bound to IdMhs table, simply like:
Me!SPP = Me.tbxSPP
The real trick is figuring out what event to put the code into. You have a control (possibly combobox) where the UKT value is selected? Use its AfterUpdate event.
Why do you need to save the SPP value and not just retrieve it in a query that joins tables?
What is nature of table relationship? Is T_UKT a lookup table? If so should be able to include it in form RecordSource and then the SPP value would be available for display in textbox and DLookup not needed. Domain aggregate functions can perform slowly on forms and reports and should be a last resort option. The same code would be used to save the value. The query join should be 'show all records from IdMhs and only those from T_UKT that match'. Set textbox bound to T_UKT SPP field as Locked Yes, TabStop No.

web2py update on multiple tables with SQLFORM

I would like to know if its possible to create a form using:
record = request.args(0)
form = SQLFORM.factory(db.tbl1, db.tbl2, db.tbl3, db.tbl4, record)
Is this possible, as I keep getting an error when I try it.
define_table argument is not a Field or Table: 1
Positional arguments to SQLFORM.factory can only be fields or tables (from which the fields will be extracted). Other arguments must be passed as keyword arguments:
form = SQLFORM.factory(..., record=record)
However, passing a record ID as the record argument to SQLFORM.factory won't work because SQLFORM.factory generates a dummy DAL instance with a dummy table, so it won't be able to query the dummy table using the record ID in order to retrieve a record. In any case, it is not clear to which record your record ID would refer (you're form comprises four separate db tables).
If your goal is to use the record to pre-populate the form values, an alternative is to set the field defaults to those values.

Copy value formula from one field to another in different forms - LOTUS NOTES

Is it possible to assign to a field from a form a value stored in a field on a different form? Eg: txt_Name is on form_MAIN and txt_LastName is on form_SECOND.
I tried: ( on the Window Title on the form_MAIN ) ( the field "text_uniqueid" contains #Text(#DocumentUniqueId)
FIELD OldOrderNumber := #GetField("text_uniqueid");
and then I wanted to see if I can see the variable's value on the second_FORM:
#Prompt([Ok];"title";OldOrderNumber)
but the result is null.
In other words, what I want to do is: To copy the unique id of the main form to a field situated on the second form.
#GetField can only get values from the current document. To fetch a field value from another document you need to use #GetDocField and supply the UNID of the document you want to read from.
#GetDocField
Given the unique ID of a document, returns the contents of a specific
field on that document. The document must reside in the current
database.
Syntax
#GetDocField( documentUNID ; fieldName )

Display on a view fields values from different forms - Lotus Notes

I have a main form which contain an embedded view. This embedded view is displaying field values that exist in another form. How can i display fields that are in the main form and fields that are in the other form on the same ordinary view?
Firstly, your View Selection formula needs to select documents created with both forms
SELECT Form = "Main" | Form = "Other"
or you can use a short-hand version
SELECT Form = "Main":"Other"
Then you need to enter a conditional formula in the column where you want to display values from documents created with both forms
#IF(Form = "Main" ; FieldName1 ; Form = "Other" ; FieldName2 ; "")
although, as only those two forms are permitted, you can shorten that too
#If(Form = "Main"; FieldName1 ; FieldName2)
Hope this helps,
Phil
You could emulate the view in a rich text field, using the technique I describe here:
http://www.bleedyellow.com/blogs/texasswede/entry/dynamictables
You need to modify the code to get both your "main" document and your "other" document, and combine them together into one row. This way you can display values from different documents (even one "main" and multiple "other" documents).
It would work something like this:
Create temp document with rich text field.
Get the first "main" document and "other" document(s) associated with it (doc.Responses if they are child documents).
Create a new document using the row template form, and put values into the different fields.
Render the new row document into the rich text field on the temp document.
Repeate above steps for each main document.
If you only have values from one other document displayed on the main form, there's no need to use an embedded view to display the values. You could use computed text to display the values from the second document along with values from the main document.
If you need to view multiple documents and want to include values from the main document in the embedded view on the same lines as the other documents, I would recommend having the values from the main document be stored on those other documents, rather than trying to put the other document data on the main form (since there would be multiple other documents, requiring multiple field values on the main).
That said, if the field values are already on the main form, why do you need to display them a second time on those lines in the embedded view? After all, it would repeat the same value on every line in that column.
Visualize it in sql format:
Form A:
EmpNum | Name
Form B:
Name | Project
Can I have something like this in Lotus Notes:
SELECT *
FROM Form A, Form B
WHERE Form A.Name = Form B.Name

Create a new FileMaker layout showing unique records based on one field and a count for each

I have a table like this:
Application,Program,UsedObject
It can have data like this:
A,P1,ZZ
A,P1,BB
A,P2,CC
B,F1,KK
I'd like to create a layout to show:
Application,# of Programs
A,2
B,1
The point is to count the distinct programs.
For the life of me I can't make this work in FileMaker. I've created a summary field to count programs resetting after each group, but because it doesn't eliminate the duplicate programs I get:
A,3
B,1
Any help much appreciated.
Create a a summary field as:
cntApplicaiton = Count of Application
Do this by going into define fields, create a field called cntApplication, type summary. In the options dialogue make the summary field a count on application
Now create a new layout with a subsummary part and nobody. The subsummary should be sorted on Application. Put the Application and cntApplication fields in subsummary. If you enter browse mode and sort by Application you ought to get the data you want.
You can also create a calc field with the formula
GetSummary(cntApplication; Application)
This will allow you to use the total number of Applications with in a record
Since I also generate the data in this form, the solution I've adopted is to fill two tables in FileMaker. One provides the summary view, the other the detailed view.
I think that your problem is down to dupliate records and an inadequate key.
Create a text field called "App_Prog". In the options box set it to an auto-enter calc, unchecking the 'Do not replace...' option, and use the following calc:
Application & "_" & Program
Now create a self join to the table using App_Prog as the field on both sides, and call this 'MatchingApps'.
Now, create (if you don't alread have one) a unique serial number field, 'Counter' say, and make sure that you enter a value in each record. (Find all, click in the field, and use serial number option in'Replace Field Contents...')
Now add a new calc field - Is_Duplicate with the following calc...
If (Counter = MatchingApps::Counter; "Master Record" ; "Duplicate")
Finally, find all, click in the 'Application field, and use 'Replace Field Contents...' with a calculation to force the auto-enter calc for 'App_Prog' to come up with a value.
Where does this get you? You should now have a set of records that are marker either "Master Record" or "Duplicate". Do a find on "Master Record", and then you can perform your summary (by Application) to do a count of distinct application-program pairs.
If you have access to custom functions (you need FileMaker Pro Advanced), I'd do it like this:
Add the RemoveDuplicates function as found here (this is a recursive function that takes a list of strings and returns a list of unique values).
In the relationships graph, add another occurrence of your table and add an Application = Application relationship.
Create a calculated field in the table with the calculation looking something like this:
ValueCount(RemoveDuplicates(List(TABLE2::Program)))
You'll find that each record will contain the number of distinct programs for the given application. Showing a summary for each application should be relatively trivial from here.
I think the best way to do this is to create a separate applications table. So as you've given the data, it would have two records, one for A and one for B.
So, with the addition of an Applications table and your existing table, which I'll call Objects, create a relationship from Applications to Objects (with a table occurrence called ObjectsParent) based on the ApplicationName as the match field. Create a self join relationship between Objects and itself with both Application and Program as the match fields. I'll call one of the "table occurrences" ObjectsParent and the other ObjectsChildren. Make sure that there's a primary key field in Objects that is set to auto-enter a serial number or some other method to ensure uniqueness. I'll call this ID.
So your relationship graph has three table occurrences:
Applications::Applicaiton = ObjectsParent::Application
ObjectsParent::Application = ObjectsChildren::Application, ObjectsParent::Program = ObjectsChildren::Program
Now create a calculation field in Objects, and calculating from the context of ObjectsParent, give it the following formula:
AppCount = Count( ObjectsChildren::ID )
Create a calculation field in Applications and calculating from the context of the table occurrence you used to relate it to ObjectsParent with the following formula:
AppCount = ObjectsParent::AppCount
The count field in Objects will have the same value for every object with the same application, so it doesn't matter which one you get this data from.
If you now view the data in Applications in list view, you can place the Applications::Application and Applications::AppCount fields on the layout and you should get what you've requested.