You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Forms are one of the most important components for a lot of applications as they are always needed for user input, like searches, logins, registrations, newsletter subscriptions and much more. Matestack implements a `form` component which could wrap differnt form input components also implemented in matestack like text inputs, number inputs, textareas, selects, checkboxes, radio buttons and more.
4
-
3
+
Matestack implements a `form` component which wraps different child form input components like text inputs, number inputs, textareas, selects, checkboxes, radio buttons and more in order to collect user input. The `form` component is implemented with Vue.js and is designed to submit its data via an async HTTP request, usually targeting a Rails controller action through Rails routing, when submitted. The `form` can reset itself, render serverside errors, emit events and perform transitions without full browser page reload after form submission. Alternatively, the form can perform a redirect resulting in a full browser page reload after submission.
5
4
6
5
## Usage
7
6
8
-
### Form component
7
+
### Basic configuration
9
8
10
-
Like in Rails with `form_for` you can create a form in matestack with `form`. It takes a hash as parameter with which you can configure your form and a block with the formular content. In the config hash you can set the HTTP request method, a path, success and failure behavior. You also need to specify a model, string or symbol for what the form is for. All form params will then be submitted nested in this namespace, following Rails behavior and conventions.
9
+
Like Rails' `form_for`, Matestack's `form`takes a hash as parameter which is used to configure the form. Within the block of a `form`, child components like `form_input` are used to collect user input:
11
10
12
11
```ruby
13
12
defresponse
14
13
form form_config do
15
-
form_input key::name, label:'Name'
16
-
# form content goes here
14
+
form_input key::name, type::text, label:'Name'
15
+
# ...
16
+
form_submit do
17
+
button text:"submit", type::submit
18
+
end
17
19
end
18
20
end
19
21
22
+
# we use a helper method to define the config hash
20
23
defform_config
21
24
{
22
25
for:User.new
23
26
path: users_path,
24
-
method::post,
25
-
success: {
26
-
transition: {
27
-
follow_redirect:true
28
-
}
29
-
},
30
-
failure: {
31
-
emit:'user_form_failure'
32
-
}
27
+
method::post
33
28
}
34
29
end
35
30
```
36
31
37
-
Each form requires a few keys for configuration: `:for`, `:path`, `:method`.
32
+
Each form requires a few keys for configuration: `:for`, `:path`, `:method`.
33
+
34
+
*`:for` can reference an active record object or a string/symbol which will be used to nest params in it. The name of that surrounds the params is either the given string/symbol or derived from the active record object. In the above case the submitted params will look as follows: `user: { name: 'A name }`.
35
+
36
+
*`:path` specifies the target path, the form is submitted to (can be a plain String or a Rails url helper method)
37
+
38
+
*`:method` sets the HTTP method the form is using to submit its data, can be `:post` or `:put`
39
+
40
+
### Serverside action
41
+
42
+
As mentioned, the `form` posts its data to a specified Rails controller action through Rails routing.
43
+
44
+
**Be aware to change the response structure of scaffolded Rails controller action like seen below in order to support a Matestack form:**
*`:for` can reference an active record object or a string/symbol which will be used to nest params in it. The name of that sorrounds the params is either the given string/symbol or derived from the active record object. In the above case the submitted params will look as follows: `user: { name: 'A name }`.
84
+
private
40
85
41
-
*`:path` specifies the target path, the form is submitted to
42
-
43
-
*`:method` sets the request method the form is submitted with
86
+
# Only allow a list of trusted parameters through.
87
+
defuser_params
88
+
params.require(:user).permit(:name)
89
+
end
90
+
91
+
end
92
+
```
44
93
45
94
### Form success and failure behavior
46
95
47
-
Forms will be submitted asynchronously and in case of errors dynamically extended to show errors belonging to inputs fields. In case of a successful request the form is resetted.
96
+
Forms will be submitted asynchronously and in case of errors dynamically extended to show errors belonging to inputs fields. In case of a successful request the form is resetted, unless configured not to do so.
48
97
49
98
**Rendering errors**
50
99
51
-
If the request failes and the server responds with json containing an `:errors` key and errors following the active record error schema the form automatically renders these errors below the input and adds a css class "error" to the input and "has-errors" to the form.
100
+
If the request fails and the server responds with JSON containing an `:errors` key and errors following the ActiveRecord error schema, the form automatically renders these errors below the inputs and adds a css class `error` to the each input with an error and `has-errors` to the wrapping form tag:
101
+
102
+
```html
103
+
<formclass="matestack-form has-errors">
104
+
<inputtype="text"class="error">
105
+
<spanclass="errors">
106
+
<!-- for each error string within the error array for the key 'title' -->
107
+
<spanclass="error">
108
+
can't be blank
109
+
</span>
110
+
</span>
111
+
</form>
112
+
```
113
+
114
+
In order to change the DOM structure and applied CSS classes for errors, you can adjust the error rendering via configuration. The code below for example is meant to support Bootstrap form error classes:
52
115
53
-
Read more about error rendering and customizing form errors at the [form api documentation](/docs/api/100-components/form.md).
116
+
```ruby
117
+
defform_config
118
+
{
119
+
for:User.new
120
+
path: users_path,
121
+
method::post,
122
+
errors: {
123
+
wrapper: { tag::div, class: 'invalid-feedback' },
124
+
input: { class: 'is-invalid' }
125
+
}
126
+
end
127
+
```
128
+
129
+
Read more about error rendering and customizing form errors at the [form api documentation](/docs/api/100-components/form.md).
54
130
55
131
**Customizing success and failure behavior**
56
132
57
-
We can customize the success and failure behavior of an`form` component by specifiyng the `:success` or `:failure` key with a hash as value. The value hash can contain different keys for different behavior.
133
+
We can customize the success and failure behavior of a`form` component by specifiyng the `:success` or `:failure` key with a hash as value. The value hash can contain different keys for different behavior.
58
134
59
-
* use `:emit` inside it to emit an event for success or failed responses.
135
+
* use `:emit` inside it to emit an event for success or failed responses.
60
136
* use `:transition` to transition to another page. Either specifiyng a hash containing a path and optional params or a hash with `follow_response: true` in order to follow the redirect of the response.
61
137
* use `:redirect` with a hash containing a path and params or `follow_response: true` to redirect the browser to the target. Be aware that this will trigger a full website reload as it is a redirect and no transition.
62
138
63
139
You can also combine `:emit` and one of `:transition`, `:redirect` if wanted.
64
140
65
-
Read more about success and failure behavior customization at the [form api documentation](/docs/api/100-components/form.md).
141
+
If you want to show a separate success or error message after form submission, you can use the emitted events in order to trigger `toggle` components to show up for a 5 seconds:
142
+
143
+
```ruby
144
+
defresponse
145
+
form form_config do
146
+
form_input key::name, type::text, label:'Name'
147
+
# ...
148
+
form_submit do
149
+
button text:"submit", type::submit
150
+
end
151
+
end
152
+
toggle show_on:"submitted", hide_after:5000do
153
+
span class: "some-success-styling", text:"Yeah! It worked!"
154
+
end
155
+
toggle show_on:"failed", hide_after:5000do
156
+
span class: "some-error-styling", text:"Damn! Somenthing went wrong!"
157
+
end
158
+
end
159
+
160
+
defform_config
161
+
{
162
+
for:User.new
163
+
path: users_path,
164
+
method::post,
165
+
success: {
166
+
emit:"submitted"
167
+
},
168
+
failure: {
169
+
emit:"failed"
170
+
}
171
+
end
172
+
```
173
+
174
+
This will render static texts "Yeah! It worked!" or "Damn! Somenthing went wrong!" in a `span` after form submission. If you want to render the serverside message defined with `render json: {
175
+
message: 'User was successfully created.'
176
+
}, status: :created`, you would have to add some minor Vue.js to the `toggle` content:
Now the serveside messages will appear within the `toggle` components.
190
+
191
+
Read more about success and failure behavior customization at the [form api documentation](/docs/api/100-components/form.md).
66
192
67
193
### Input components
68
194
69
-
Inside a form you can use our form input components `form_input`, `form_textarea`, `form_select`, `form_radio` and `form_checkbox`. Do not use the basic input components `input`, `textarea` and so on, because they do not work with matestack forms. Instead use the _form input_ components. Each input component requires a `:key` which represents the params name as which this inputs value get's submitted. If you specified an active record object or similar in the `form` with the `:for` options, inputs will be prefilled with the value of the corresponding attribute or method of the object. It is also possible to specify `:label` in order to create labels for the input on the fly.
195
+
Inside a form you can use our form input components `form_input`, `form_textarea`, `form_select`, `form_radio` and `form_checkbox`. Do not use the basic input components `input`, `textarea` and so on, because they do not work with matestack forms. Instead use the _form input_ components. Each input component requires a `:key` which represents the params name as which this inputs value get's submitted. If you specified an active record object or similar in the `form` with the `:for` options, inputs will be prefilled with the value of the corresponding attribute or method of the object. It is also possible to specify `:label` in order to create labels for the input on the fly.
70
196
71
-
*`form_input` - Represents a html "input". All w3c specified input types are supported by this component, just pass in your wanted type with the `:type` option.
197
+
*`form_input` - Represents a html "input". All w3c specified input types are supported by this component, just pass in your wanted type with the `:type` option.
72
198
```ruby
73
199
form_input key::name, type::text, label:'Name'
74
200
form_input key::age, type::number, label:'Age'
@@ -81,7 +207,7 @@ Inside a form you can use our form input components `form_input`, `form_textarea
81
207
```
82
208
83
209
*`form_select` - Represents a html "select". You can pass in values as array or hash under the `:options` key, which then will be rendered as html "option"s. Given an array, value and label will be the same, in case of a hash the key will be used as label and the value as value. In order to allow multiple selections set `multiple: true`. Selected values will then be submitted in an array.
84
-
210
+
85
211
*`form_checkbox` - Represents a html "input type=checkbox". You can pass in values as array or hash under the `:options` key, which then will be rendered as checkboxes. Given an array, value and label will be the same, in case of a hash the key will be used as label and the value as value. Selected values will then be submitted in an array. If you leave out `:options` a simple single checkbox will be rendered and a hidden input like rails does which allows for a "true" or "false" checkbox.
86
212
87
213
*`form_radio` - Represents a html "input type=radio". You can pass in values as array or hash under the `:options` key, which then will be rendered as radio buttons. Given an array, value and label will be the same, in case of a hash the key will be used as label and the value as value.
@@ -95,4 +221,4 @@ Wrap a button or any markup which should submit the form when clicked in `form_s
95
221
96
222
## Complete documentation
97
223
98
-
If you want to know all details about the `form` component and all inputs and their usage as well as how you can customize errors, input placeholder, input value initialization and more checkout it's [api documentation](/docs/api/100-components/form.md).
224
+
If you want to know all details about the `form` component and all inputs and their usage as well as how you can customize errors, input placeholder, input value initialization and more checkout it's [api documentation](/docs/api/100-components/form.md).
0 commit comments