## Basic Concepts |
|
First of all, it is recomended to read a tutorial [Start With Forms](/wikipp/en/page/tut_forms) |
First of all, it is recommended to read a tutorial [Start With Forms](/wikipp/en/page/tut_forms) |
|
Forms system of CppCMS has three major types of classes: |
|
1. Form -- `cppcms::form` --- the base class for form container, It is responsible on form validation, rendering. Usually, user derives its own classes from `cppcms::form` |
2. Widgets in the namespace `cppcms::widgets`. They are basic elements of form like input text, number, checkbox, submit button etc. |
3. `cppcms::widgetset` --- simple class for partial rendering of forms for easier integration with templates. |
|
All of them are derived from `base_form` that provide basic |
interface for loading, rendering and validation of forms. |
|
## Class cppcms::form |
|
This class used as base class for any HTML form developer |
wants to create. This class is non-copyable and used as |
container for loading, validating and rendering widgets. |
|
### Member functions |
|
- **`void append(base_form *)`** register widget to the form. |
|
When form is created every widget should be registered |
for validation and rendering. It can be done by calling |
`append()` function. |
- **`form &operator &(base_form &f)`** -- syntactic sugar for `append()`. For example: |
|
struct sum : public cppcms::form { |
widgets::number<int> M,N; |
widgets::submit button; |
my_form() : |
M("m","M"), |
N("n","N"), |
button("submit","Sum") |
{ |
*this & M & N & button; |
} |
}; |
|
Now, when the form is rendered it is renders all widgets |
given in this list. |
|
- **`virtual void load(cgicc::Cgicc const &cgi)`** -- load form data for CGI environment. It is used when we need to |
load sumbitted data from user. For example: |
load submitted data from user. For example: |
|
if(env->getRequestMethod()=="POST") { |
sum.load(*cgi); |
- **`virtual bool validate()`** -- validate loaded data. This method is always called after load. It is used for checking validity of all form widgets. |
|
if(env->getRequestMethod()=="POST") { |
sum.load(*cgi); |
if(!sum.validate()) { |
// Process request |
} |
} |
// Continue with empty or partially filled form |
|
This method is usually overridden for forms developer |
in order to implement advanced tests that are |
not availible on widgets level. For example: |
not available on widgets level. For example: |
|
struct sum : public form { |
widgets::number<int> odd,even; |
... |
virtual bool validate() |
{ |
if(!form::validate()) |
return false; |
if(odd.get() % 2 == 1) |
return true; |
odd.not_valid(); |
return false; |
} |
}; |
|
When you reimplement validation, you should always |
perofrm base form validation and then peroform your |
When you re-implement validation, you should always |
perform base form validation and then perform your |
own tests. |
|
Generally, best practive is performing **all** possible |
Generally, best practice is performing **all** possible |
tests on form level, even complex things like keys validity and so on, in order make use of forms transparent |
for developer, i.e.: if form is valid then it is 100% valid. |
|
- **`void clear()`** --- reset the form, clear all widgets. |
|
## Class cppcms::widgetset |
|
Is a container that is similar to `form` but it is used only |
for rendering different types of widgets. |
|
It has following important member function: |
|
widgetset &operator<<(widgets::base_widget &w); |
|
That allows registering of various widgets to the set. |
For example: |
|
struct op { |
widgets::number<int> x,y; |
widgets::button add,sub,mul,div; |
widgetset inputs; |
widgetset ops; |
op() : |
... |
{ |
*this & x & y & add & sub & mul & div; |
inputs<<x<<y; |
ops<<add<<sub<<mul<<div; |
} |
}; |
|
Now can write template: |
|
<table> |
<% form as_table ops_form.inputs %> |
</table> |
<p><% form as_space ops_form.ops %></p> |
|
Now push buttons and input fields are rendered using |
different methods. |
|
## Widgets |
|
TODO |