Main  /  Edit version 2  /  Edit version 3  /   /  Users Area

Difference "Working With Forms" ver. 2 versus ver. 3

Content:

<!--toc-->
## Create a Form
First we create our simple form. Let's create `content.h` file and add header:
#include <cppcms/view.h>
#include <cppcms/form.h>
Then create a form class derived from `cppcms::form`:
namespace content {
struct info_form : public cppcms::form {
Then we add widgets to this form:
cppcms::widgets::text name;
cppcms::widgets::radio sex;
cppcms::widgets::select marital;
cppcms::widgets::numeric<double> age;
cppcms::widgets::submit submit;
Where, `text` is a text input field, `radio` is a multiple choice field, `select` is a drop down list of choices, `number<>` is a number of specific type and `submit` is a submit button.
Now we create a constructor for our class:
info_form()
{
Then we setup an information messages for the form widgets:
name.message("Your Name");
sex.message("Sex");
marital.message("Marital Status");
age.message("Your Age");
submit.value("Send");
Then we register all the widgets withing the form.
This allows centralized rendering, loading and validation
of the entire form.
add(name);
add(sex);
add(marital);
add(age);
add(submit);
Note, `cppcms::form::add` only registers the object
to the form. It does not transfer ownership on the
widget.
Now lets setup some values for our selection widgets
sex.add("Male","male");
sex.add("Female","female");
marital.add("Single","single");
marital.add("Married","married");
marital.add("Divorced","divorced");
Note: the first parameter is "display name" and the
second one is a special key that defines our choice.
Now, let's define some basic restrictions on the fields:
name.non_empty();
age.range(0,120);
We make sure that the name is filled and the age
is in expected range. That's it for our constructor.
And now we can add it to our content class (with some other fields for future use).
struct message : public cppcms::base_content {
std::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.
content::message c;
Then we test, if something was send:
if(request().request_method()=="POST") {
If so we load our form and validate it:
c.info.load(context());
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.value();
c.sex=c.info.sex.selected_id();
c.state=c.info.marital.selected_id();
c.age=c.info.age.value();
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:
}
}
render("message",c);
## Additional Validation
Let's assume that standard widgets checks are not good enough. We can extend our validation manually.
We can add out own restrictions by overriding
`cppcms::form::validate` member function by adding
the following code to `content::info_form`
virtual bool validate()
{
if(!form::validate())
return false;
if(marital.selected_id()!="single"
&& age.value()<18)
{
marital.valid(false);
return false;
}
return true;
}
First of all we need to check that basic form validation
is performed by calling `form::validate` then we add
our own restrictions like for example, martial status
can be only single for non-adult.
When we detect such situation we mark our widget
as invalid and return false for entire validation
process.
## Security Considerations: Cross Site Request Forgery
The straight forward approach to the forms is vulnerable to [Cross Site Request Forgery](/wikipp/en/page/secure_programming#Cross.Site.Request.Forgery..CSRF.) an authorized person is tricked to
perform an action that he was not expected to do (follow the link for more detail).
In order prevent CSRF every POST form should include
a special hidden field that holds a session
specific CSRF token.
So we need to add a small code `<% csrf %>` streight
after `<form ...>` field to our template:
<form method="post" action="" ><% csrf %>
<% form as_p info %>
</form>
And enable `csrf` checks in the [configuration file](/wikipp/en/page/cppcms_1x_config#security.csrf.enable):
"security" : {
"csrf" : {
"enable" : true
}
}
The `<% csrf %>` command would generate a special hidden input field that inject session specific token
and handle all tests for you.
In case of detection of CSRF attack the `cppcms::form::load` would throw a `cppcms::request_forgery_error` exception
That would be caught and reported to the logs at higher levels.
**Note:** CSRF token should be used with POST fields only and never GET request method.
<!--toc-->
## Create a Form
First we create our simple form. Let's create `content.h` file and add header:
#include <cppcms/view.h>
#include <cppcms/form.h>
Then create a form class derived from `cppcms::form`:
namespace content {
struct info_form : public cppcms::form {
Then we add widgets to this form:
cppcms::widgets::text name;
cppcms::widgets::radio sex;
cppcms::widgets::select marital;
cppcms::widgets::numeric<double> age;
cppcms::widgets::submit submit;
Where, `text` is a text input field, `radio` is a multiple choice field, `select` is a drop down list of choices, `number<>` is a number of specific type and `submit` is a submit button.
Now we create a constructor for our class:
info_form()
{
Then we setup an information messages for the form widgets:
name.message("Your Name");
sex.message("Sex");
marital.message("Marital Status");
age.message("Your Age");
submit.value("Send");
Then we register all the widgets withing the form.
This allows centralized rendering, loading and validation
of the entire form.
add(name);
add(sex);
add(marital);
add(age);
add(submit);
Note, `cppcms::form::add` only registers the object
to the form. It does not transfer ownership on the
widget.
Now lets setup some values for our selection widgets
sex.add("Male","male");
sex.add("Female","female");
marital.add("Single","single");
marital.add("Married","married");
marital.add("Divorced","divorced");
Note: the first parameter is "display name" and the
second one is a special key that defines our choice.
Now, let's define some basic restrictions on the fields:
name.non_empty();
age.range(0,120);
We make sure that the name is filled and the age
is in expected range. That's it for our constructor.
And now we can add it to our content class (with some other fields for future use).
struct message : public cppcms::base_content {
std::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.
content::message c;
Then we test, if something was send:
if(request().request_method()=="POST") {
If so we load our form and validate it:
c.info.load(context());
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.value();
c.sex=c.info.sex.selected_id();
c.state=c.info.marital.selected_id();
c.age=c.info.age.value();
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:
}
}
render("message",c);
## Additional Validation
Let's assume that standard widgets checks are not good enough. We can extend our validation manually.
We can add out own restrictions by overriding
`cppcms::form::validate` member function by adding
the following code to `content::info_form`
virtual bool validate()
{
if(!form::validate())
return false;
if(marital.selected_id()!="single"
&& age.value()<18)
{
marital.valid(false);
return false;
}
return true;
}
First of all we need to check that basic form validation
is performed by calling `form::validate` then we add
our own restrictions like for example, martial status
can be only single for non-adult.
When we detect such situation we mark our widget
as invalid and return false for entire validation
process.
## Security Considerations: Cross Site Request Forgery
The straight forward approach to the forms is vulnerable to [Cross Site Request Forgery](/wikipp/en/page/secure_programming#Cross.Site.Request.Forgery..CSRF.) an authorized person is tricked to
perform an action that he was not expected to do (follow the link for more detail).
In order prevent CSRF every POST form should include
a special hidden field that holds a session
specific CSRF token.
So we need to add a small code `<% csrf %>` streight
after `<form ...>` field to our template:
<form method="post" action="" ><% csrf %>
<% form as_p info %>
</form>
And enable `csrf` checks in the [configuration file](/wikipp/en/page/cppcms_1x_config#security.csrf.enable):
"security" : {
"csrf" : {
"enable" : true
}
}
The `<% csrf %>` command would generate a special hidden input field that inject session specific token
and handle all tests for you.
In case of detection of CSRF attack the `cppcms::form::load` would throw a `cppcms::request_forgery_error` exception
That would be caught and reported to the logs at higher levels.
**Note:** CSRF token should be used with POST fields only and never GET request method.

Sidebar:

## Related
- [Templates](/wikipp/en/page/cppcms_1x_tut_hello_templates)
- [Secure Programming](/wikipp/en/page/secure_programming)
## Related
- [Templates](/wikipp/en/page/cppcms_1x_tut_hello_templates)
- [Secure Programming](/wikipp/en/page/secure_programming)
← [Views Inheritance](http://cppcms.com/wikipp/en/page/cppcms_1x_tut_templates_inheritance)
[Sessions](http://cppcms.com/wikipp/en/page/cppcms_1x_sessions)→

About

CppCMS is a web development framework for performance demanding applications.

Support This Project

SourceForge.net Logo

Поддержать проект

CppCMS needs You


Navigation

Main Page


Valid CSS | Valid XHTML 1.0