These days single page apps are all the rage. There are many technologies emerging that enable slick web UI without having to do much, if anything, on the server side.
Historically, Rails used the Prototype and recently jQuery library to handle progressive enhancement.
A few words on AngularJS …
AngularJS is a toolset for building the framework most suited to your application development. It is fully extensible and works well with other libraries. Every feature can be modified or replaced to suit your unique development workflow and feature needs. - angularjs.org A few words on progressive enhancement … Progressive enhancement is a strategy for web design that emphasizes accessibility, semantic HTML markup, and external stylesheet and scripting technologies. Progressive enhancement uses web technologies in a layered fashion that allows everyone to access the basic content and functionality of a web page, using any browser or Internet connection, while also providing an enhanced version of the page to those with more advanced browser software or greater bandwidth. - Wikipedia
OK! So we want to progressively enhance our Rails form with AngularJS, for whatever our reasons are :) - Lets get started!
First, implement a basic Rails scaffold.
For the purposes of this tutorial we will be using Rails 4.0.1 and Angular version 1.2.9.
This will generate a basic Rails app ( with author model, database and form views ) and boot the basic rails server.
Now, navigate to the new author form in your browser. You will see a basic non progressive-enhancement form that you can submit to.
Next, angularize the app.
1) Open the file:
2) Now, create a new layout template for the authors resource by copying the existing one…
By default rails will look for a layout with the same name as the controller before it falls back to application layout.
3) Open the file:
app/views/layouts/authors.html.erb and add the angular cdn to the header:
4) then rewrite the
<body> tag so it reads:
You can see the file in that state.
Now we can begin to enhance the form.
1) Open the file:
Now edit the cooresponding form template
app/views/authors/_form.html.haml like so, you can see the diff here:
Now, you will notice when you submit the form, that it still does a traditional full page post, this is obviously not what we want. To get round this issue we need to use an angular directive to replace the submit button with something a bit more friendly.
First, add the directive to the coffeescript.
Then, bind the forms submit button to the directive, like so…
Note the camelcase to hypenated conversion between the angular directive and the template binding.
Now angular will happily replace the submit button with a link that is bound to the
FormControllers submitForm() function, and when you click this link, it will submit the form behind the scenes via ajax, right?
Just one more thing …
We need to set up the XSRF, XRW and Accept headers in order for rails to properly negotiate the request. Also we need to specify the values we are going to send back to rails. Add the following to the angular code. See the diff for details.
And in the
FormController change the
submitForm functions http post to:
And there you go. Progressive enhancement for JS users and Plain Old Posts for non JS users!
We will look at handlng validations, implementing a nested form and how fields_for correleates quite nicely to Angulars ng-repeat.
- handle validations with angular
- implement form service to handle scopes across controllers.
- implement nested model and its relation to ng-repeat.
Thanks for reading! You can check out the source for this tutorial here