Now we learn how to use forms. |
|
## Create form |
|
First we create our simple form, edit `data.h` file and add header: |
|
#include <cppcms/form.h> |
|
Then create a form class derived from `cppcms::form`: |
|
struct info_form : public cppcms::form { |
|
Then we add widgets to this form: |
|
widgets::text name; |
widgets::radio sex; |
widgets::select martial; |
widgets::number<double> age; |
widgets::submit submit; |
|
|
Where, `text` is text input field, `radio` is multiple choice field, `select` is drop down list of choices, `number<>` is number of specific type and `submit` is submit button. |
|
Now we create a constructor for our class: |
|
info_form() : |
name("name","Your Name"), |
sex("sex","Sex"), |
martial("mat","martial State"), |
age("age","Your Age"), |
submit("submit","Send") |
{ |
|
|
First we call constructors of all our widgets. First parameter is usually `name` HTML field and the second is Description, or value in case of `submit`. |
|
Then we must register all our widgets to this form |
|
*this & name & sex & martial & age & submit; |
|
This allows centralized rendering, loading and validation |
of the form. Then we add different conditions and configurations to our widgets: |
|
sex.add("Male"); |
sex.add("Female"); |
martial.add("Single"); |
martial.add("Married"); |
martial.add("Divorced"); |
|
Adding different options of selection fields. |
|
name.set_nonempty(); |
age.set_range(0,120); |
|
Define limits: name should not be empty and age should be in range of 0--120. |
|
And now we can add it to our content class (with some other fields for future use). |
|
struct message : public base_content { |
string name,state,sex; |
double age; |
info_form info; |
}; |
|
## Form in templates |
|
First we create our output |
|
<% if not empty name %> |
<h1>Hello <% name %></h1> |
<p>You are <% sex %>, <% state %></p> |
<p>Your age is <% age %></p> |
<% else %> |
<h1>Input your details</h1> |
<% end %> |
|
Then we put our form using tag `<% form as_p info %>`: |
|
<form method="post" action="" > |
<% form as_p info %> |
</form> |
|
The flag `as_p` tells to render form `info` using paragraphs. |
|
## Working with form in code: |
|
First we create our content that contains required |
form. |
|
data::message c; |
|
Then we test, if something was send: |
|
if(env->getRequestMethod()=="POST") { |
|
If so we load our form and validate it: |
|
c.info.load(*cgi); |
if(c.info.validate()) { |
|
if the form is valid, we can do anything |
we want. For example setup our content |
fields with appropriate values from the form. |
|
c.name=c.info.name.get(); |
c.sex=c.info.sex.get(); |
c.state=c.info.martial.get(); |
c.age=c.info.age.get(); |
|
We clear it at the end, because we want user to |
put new values |
c.info.clear(); |
|
Now we can render our template as usual: |
|
} // if valid |
} // if post |
render("message",c); |
|
## Additional Validation |
|
Let's assume that standard widgets checks are not good enough. We can extend our validation manually. |
|
For example, I want to make sure that person can't be married if his age under 18. We override `validate()` virtual function that does the job: |
|
virtual bool validate() |
{ |
if(!form::validate()) return false; |
if(martial.get()!="Single" && age.get()<18) { |
martial.not_valid(); |
return false; |
} |
return true; |
} |
|
First we validate form as usual with `form::validate()` |
and then we do our tests, if something is incorrect, |
we mark the filed `martial` as not valid, and this would |
be visible in rendered HTML form. |
|