polymer-rails-forms
What this gem does
This gem depends on emcee and adds to your vendor/assets/components directory the rails-form element. Which, unsurprisingly, let's you create complex rails compatible forms in polymer by simply defining a form's structure and optionally data via javascript.
Installation
first follow the installation instructions for emcee
gem install polymer-rails-form
rake polymer_rails_forms:install
then in your /app/assets/components/application.html file add
*= require rails-forms/rails-form
Basic example
This is what a simple login form could look like using this gem
<rails-form id='sign_in_form' action="/users/sign_in" method="POST" scope="user" submitText="Sign In"></rails-form>
<script>
document.getElementById("sign_in_form").setAttribute("structure", JSON.stringify({
email: { type: 'string', label: "Email Address" },
password: { type: 'password' }
}))
</script>
This syntax, however short is a bit clunky, a better way of using this gem is to create forms by creating a polymer element that extends rails-form. Here's the same login form
<link rel="import" href="../rails-forms/rails-form.html" >
<polymer-element name="login-form" extends='rails-form'>
<shadow></shadow>
<script>
Polymer({
action: "/users/sign_in",
method: "POST",
scope: "user",
submitText: "Sign In",
ready: function(){
this.structure = {
email: { type: 'string', label: "Email Address" },
password: { type: 'password' },
}
}
});
</script>
</polymer-element>
This syntax gives you the flexibility to add encapulated methods and styles. It's a lot better for complex forms.
Nested attributes are supported (otherwise what's the point right?). This is that login form again, but this time with nested location attributes
<link rel="import" href="../rails-forms/rails-form.html" >
<polymer-element name="login-form" extends='rails-form'>
<shadow></shadow>
<script>
Polymer({
action: "/users/sign_in",
method: "POST",
scope: "user",
submitText: "Sign In",
ready: function(){
this.structure = {
email: { type: 'string', label: "Email Address", required: true },
password: { type: 'password', required: true },
location: { type: 'nest', allowAdd: false, multiple: false, structure: {
address: { type: "string" },
city: { type: "string" },
state: { type: "string" },
zip: { type: "string" }
}
}
}
}
});
</script>
</polymer-element>
This would give the location input the name user[location_attributes][city]
. If you were
to set multiple: true
the name would become user[location_attributes][0][city]
. And if
you were to set allowAdd: true
the inputs would be in a list with the option to create more.
Validations
Also not that I've included required: true
on the email and password fields. This means this triggers
them to be validated onSubmit and onChange. For a custome validation just use validates: 'method_name'
Note:
If you're going to use the domReady function in your custom form element, be sure to call
this.super()
at the top of the function to run the form's default domReady functionality
(which includes appending all the inputs so... kind of important). If you don't want the default
functionality though, just make sure you run the this.appendInputs()
so the inputs get added.
XHR
To make the form ajaxy just include the form element's xhr='true'
param
and override the handleXhrCallback
function.
Selects
selects are the same as any other input except that they also require the values property which is and array of
arrays, so [[value1, text2], [value2, text2]]
What's supported what's not
So far the field types that are supported are:
- string
- password
- hidden
- textarea
- url
- integer
- date (uses pickaday.js)
- location (uses google places API, which you'll have to include separately)
- image (works, but CSS is messed up)
- checkbox
- json (limted, only basic objects are supported so far, not nested arrays and objects)
What's not supported
- radio buttons
- ranges
- everything else
Support for radio buttons, ranges (sliders), and selects will hopefully be coming shortly. Everything else, who knows. This is still a very early release.