icon picker
Form-Generator

Components

Form-HTML-Gen

Will gen with the sub-forms html
so that when add record form we don’t have to do anything else
just one call to the API (or index-db) to get the Form HTML
when view-form and sub-form is 1:1 then we just get the data separately and databind
or when 1:Many view-form can take the existing html without having having to retrieve it
form element is already in there to wrap it up
and has the data-form-id attribute (to help identify it)
but the save button is only on the Form-Page

FormService → The Form-Component

LoadForm()
Calls the API to get the Form Props/HTML
(Or could check index-db)
Calls API to get the View_Fields
Needed for Onload AND OnSave to get the fields
If Not IsAddRec (Since when Add-Rec-Forms are Fully Ready to just be rendered)
Calls API to get the Data
Calls API to get the Sections
To pass init of all of the sections where for_view_id
and use the for_view_type_id
#TODO:
(Sections, View_Fields and View_Tables could be retrieved together with the View Props)
so just a single call instead of 4
Sub-Forms
We loop through Sections (retrieved via API) and call the FormService for each of them that have the “for_view_id” and the “for_view_type_id =1”
Passing Record-IDs
When Sub-Forms we must have the view_tables returned so that we can cross-reference which record_ids we need to pull out of the data by the view_table.id
('t_' + convert(varchar, v_t_id) + '.' + 'id' + ' as t_id_' + convert(varchar, v_t_id))
Calls the JS: “RenderForm()”
see below
JS: “RenderForm(html, fields, data, is_multi_rec)” (OR: ‘FormRender’) (OR: RenderFormMultiRec() to simplify)
Checks for “form-placeholders” (like form-container-{id}) for sub-forms and if not exists then add to the main “form-container” element
when is_multi_rec then data is an array and we have to create a new form container for each record
when data exists then do JS: DataBind()
MR/RenderFormMultiRec
we just append the html (which already contains the form tags) to the container and create a hidden input for the recs_num_{form_id}
set the <form rec_id attribute
JS: DataBind(form (element), fields, data)
Since Forms can be within forms we need to make sure to limit the querySelector to not go outside of the form that we pass in
Loop through all of the fields which have data associated and then have our
JS:“SetValue(field_key, value, field_type_id)” function work its magic on whatever field
OR JS:“SetValue(field, value)”
if we can pass in the model object
For DisplayForms or when the field is view-only
data-values should be preformatted via Blazor using the: FieldFormatter.FormatField(field.input_type, field.value.ToString());
so that JS isn’t doing any of the formatting
We await all of the JS ops and once completed we can then set the isLoading to false to show the whole form
But ideally we don’t await the sub-forms loading if there is a main form
and can show a message specifically to say which sub-form is being loaded so its super-clear
SaveForm(IsValidate=true)
get the form-data
JS:ValidateForm(form_id)
for all of the Form + Sub-Forms recursively
Uses Parsley
Make sure that Parsley will work with our multi-form setup
Could also loop through all of the fields and check if they are valid
Like in Blazor
and manually return the error messages
We have to be able to return the error messages from the API
Rec-Saver
Map the SubmittedFormData back to the Fields
When view.for_table_is_multi_rec then will call the SaveRecForTable() with a copy of table object
(? Or do we have a “Records” model/object that will then have a link to the View_Table rec for it)
Compare the Values to the Original to see which are “touched”
Loop through just the tables which have “touched” fields
(Should be in the correct ord of view_tables)
Call the SaveRecForTable()
If the table.parent_rec_id is null and its not the base table then FIRST we need to “fill-in” the intermediary tables by calling the SaveRecForTable() for its parent table recursively
Calls the API for RecSaver
See RecSaver class for how we pass in the data which
will put the rec_id on the table if its a new rec
Uses those Rec-IDs to be able to loop through the Sub-Forms (already existing object) and call the SaveForm(Not-IsValidate)
For MultiRec
Gets the rec-num-{form_id} from JS
Loops through the forms where data-form-id={form_id}
to call the same set of functions
The formDataMultiRec will have the tables copied to it as “tables” key
which copies the whole List<v_view_tables>
even though we will only set the rec_id on some of them

Multi-Rec Add/Edit Forms

When form_multi_rec_add_edit_min_num and its greater than the number of formDataRecs then we have to call FormRecNumChanged()
so that it will display all of the recs that need to get entered



TESTS

That when Add-Rec Form (and not-is_prefill) then its completely ready
refed-sub fields are moved under the “Ref_Table”
and removed
That that the intermediary tables will have recs created when we have multiple levels of tables
Other 1:1 tables under the root table will be updated if they have updated fields, otherwise not



Params / QS






Questions

How do sub-forms get Init? (and sub-forms within sub-forms)
Like where in the process of Init the parent form do we go through the child forms\
When Add/Edit Forms and no records, do we wait until they actually click on “Add Record” to make the AJAX call (#JITL)?
Either we have a separate AJAX call for the Sub-Forms Model
The HTML Attributes Approach
we have all of the attributes for this form in a div within the parent-form
so we know which entity ids to pass to init
so after the parent form html is rendered, a JS function scans for sub-form placeholders and will init them
The Async Sub-Forms Model Approach
API call to get all of the sections which are forms
Forms Component is manually
? Could we also have the Forms Component be able to actually accept the data and bind it to the values in the inputs or the displayVals ?

Forms HTML Gen

loop by form blocks
select * from sections where section_type_id = 1 (parent)
create a blank one if there are none
can be Multi-Col
sections.IsMultiCol
which means the form-block is a row and each child section within is a col
loop by form sections which are grouped by the from blocks
each section uses a Card

Test-Scenarios

MR Form with multiple rows (within one section)
MR Form with multiple sections
rare because the MR forms are usually horizontally

Forms within Forms

When sections have for_view_id
Have to be treated like they are separate FormComponent
? But how can we do this from the HTML


The “Form-Component”

We want to be able to have the gen-forms on any page
even manual
so we use the FormComponent
which is the main part in the Form Page
? How to protect the validity of the rec_id hidden input to ensure that it isn’t manipulated
possibly check that it belongs to the parent_rec_id
mainly we check that the user has access to the parent_rec and this rec by the IDs
the ID is not updated so not like they can move records around



The Omma Style Approach

Generate the HTML for the Form and store it in the DB
(or somewhere else on the server in the files but DB is much simpler)
Will have to move the
Will make 3 AJAX calls (2 if add-rec only)
form html
record-data (if not add-rec)
sidebar-links
Store the Form HTML to reuse
so that for Multi-Record forms it will instantly add a new record section







Layout Considerations


Init
Show the loading indicator until we have the all of the form ready
? How do we know what to pass in
Test that we can work without the formData based on the field.value
or have to
? How can we get all of the records for the multiRec View/Edit Form?

Grid

both fields and sections use the same type of grid layout
where we loop through the rows (by the row-num)
and then the cols in that row

Multi-Rec View & Add/Edit Forms

? No-Sections option so we aren’t creating a different card for each form ?
Or have Card within a Card
“AddRecordForm()”
to create another instance of the form with empty formData

Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.