This repository was archived by the owner on Nov 19, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathajax-form.html
228 lines (200 loc) · 8.75 KB
/
ajax-form.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../core-ajax/core-ajax.html">
<script src="ajax-form.js"></script>
<!--
## HTML forms on performance-enhancing drugs
The `ajax-form` element adds some more power and features to traditional HTML forms.
Also allows the `<file-input>` custom element (and any other custom element form fields
that have a `name` attribute and a `value`) to be submitted along with other traditional
form elements.
### What's wrong with a traditional `<form>`?
1. Form submission changes/reloads the page, and it's not trivial to properly prevent this.
2. You can't send custom headers with a submitted form.
3. You can't (easily) parse the server response after a form is submitted.
4. Programmatically tracking invalid forms/fields is frustrating.
`ajax-form` augments a traditional `<form>` to provide additonal features and solve the problems listed above.
### A very simple use of `ajax-form` looks just like a normal `<form>`, with the addition of an `is` attribute:
<form is="ajax-form" action="my/form/handler" method="post">
<label>Enter your name: <input type="text" name="full_name"></label>
...
</form>
### The inclusion of the `is="ajax-form"` attribute gives the `<form>` special powers, such as:
1. Callbacks when form validation fails, just before the form is submitted, and after the server has responded.
2. The ability to send custom headers to the server with the submit request.
3. Prevention of a page reload/redirect on submit.
4. The ability to include the [`<file-input>` custom element](https://github.com/garstasio/file-input) as a `<form>` field.
### Integation with `<file-input>` custom element
Want a better `<input type="file">` element that can be easily styled, has built-in,
customizable validation, and provides an improved API? Check out the [`<file-input>` custom element](https://github.com/garstasio/file-input).
`ajax-form` allows `<file-input>` custom element to be submitted along with other standard
form fields. Just include your `<file-input>` element as a child of your `<form is="ajax-form">`.
That's it!
As an added benefit, ONLY valid files (not those that have failed any validation rules setup in your `<file-input>` element)
will be sent along with the request!
### Handling the request server-side
If you include a `<file-input>` field, files will be sent with a name according to the `name` attribute on the `<file-input>`.
If more than one file has been selected, the `name` attribute for each file in the request
will include a "[]" at the end of the name string.
### Cross-origin form submits (CORS)
Please note that all forms are actually "submitted" using `XMLHttpRequest`. This means that
your server must include appropriate CORS headers in the response if you want access to the
response data **if the request is a cross-origin request**. Also, requests with custom headers
will be preflighted as well, so your server must handle these correctly. [Read more about
CORS on Mozilla Developer Network](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS).
__Don't forget to [vulcanize](http://www.polymer-project.org/articles/concatenating-web-components.html)
your main/parent HTML file before deploying into production. This will ensure
that all of your HTML imports are concatenated into one file.__
@element ajax-form
@status beta
@homepage index.html
-->
<polymer-element name="ajax-form" extends="form" attributes="action cookies enctype headers method">
<template>
<content></content>
<core-ajax url={{action}} headers={{headers}} method={{acceptableMethod}}></core-ajax>
</template>
<script>
/**
* If your form has one or more fields with an [HTML5 validation attribute](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation)
* (such as `required`), this event will be triggered once after a
* submit attempt if any of the fields do not pass validation checks.
* All invalid field elements will be passed in an array represented by
* the `detail` property of the event passed to your handler.
*
* form.addEventListener('invalid',
* function(e) {
* e.detail.forEach(function(badEl) {
* // handle invalid element
* });
* }
* );
*
* @event invalid
*/
/**
* Invoked after the form has been submitted and a response has been
* received from the server. The associated `XMLHttpRequest` instance
* used to send the request will be passed to your event handler
* on the event's `detail` property.
*
* form.addEventListener('submitted',
* function(e) {
* if (event.detail.status > 299) {
* // submit has failed
* }
* }
* );
*
* @event submitted
*/
/**
* Invoked after the form has passed all validation checks, and
* just before the reuqest is sent.
*
* form.addEventListener('submitting',
* function() {
* // submit in progress
* }
* );
*
* @event submitting
*/
/**
* <b>This is a required attribute.</b>
*
* Same as the action attribute of a non-ajax `<form>`.
* This will hold the path to your server that is set to handle
* the request.
*
* <form is="ajax-form"
* method="POST"
* action="form/handler">
* ...
* </form>
*
* The above form will be submitted to the "form/handler"
* endpoint server on the current domain.
*
* @attribute action
* @type string
* @default ''
*/
/**
* Only applicable for cross-origin form submits. If included,
* cookies will be included with any cross-origin form submit request.
* If not included, cookies will NOT be sent with any
* cross-origin form submit request.
*
* <form is="ajax-form"
* method="POST"
* action="http://otherdomain.com/form/handler"
* cookies>
* ...
* </form>
*
* The above example will ensure that cookies are included with
* the request that is sent when the form is submitted to
* the origin reference in the action attribute (which presumably
* is a domain different than the one hosting the form).
*
* @attribute cookies
*/
/**
* The encoding type for the underlying request's message-body.
*
* <form is="ajax-form"
* method="POST"
* action="form/handler"
* enctype="multipart/form-data">
* ...
* </form>
*
* The above form will be submitted as a multipart encoded POST request.
* By default, without an enctype specified, "application/x-www-form-urlencoded"
* is assumed. GET requests will not have a body, and the form fields
* will be URL encoded as URI query parameters.
*
* @attribute enctype
* @type string
* @default 'application/x-www-form-urlencoded'
*/
/**
* Custom headers to be sent with the form submit request.
* The value must be a JSON Object containing header names and values.
*
* <form is="ajax-form"
* method="POST"
* action="form/handler"
* headers='{"X-Cust-Header": "FooBar"}'>
* ...
* </form>
*
* The above form will be submitted with an "X-Cust-Header"
* header that contains a value of "FooBar".
*
* @attribute headers
* @type Object
* @default null
*/
/**
* <b>This is a required attribute.</b>
*
* Same as the method attribute of a non-ajax `<form>`.
* The method to use when sending the request. Currently,
* GET, POST, and PUT are allowed.
*
* <form is="ajax-form"
* method="put"
* action="form/handler">
* ...
* </form>
*
* The above form will be submitted as a PUT request.
*
* @attribute method
* @type string
* @default 'GET'
*/
Polymer('ajax-form', ajaxForm);
</script>
</polymer-element>