14

Using angular.js often items like ng-click or ng-model are written directly in the html form element like so....

<input type="text" ng-model="name">

How would I do that with rails? As rails uses embedded ruby and generates the html....

<%= form_for(@user) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>

How would I add the ng-model to <%= f.text_field :name %> ?

7 Answers 7

27

Ideally, you don't want to be mixing embedded ruby interpolation and Angular's interpolation. It's better to have ruby asynchronously serve JSON to Angular, and let Angular take care of filling in the data on the client side.

Sign up to request clarification or add additional context in comments.

2 Comments

Yeah after thinking about this, I think that makes sense code wise.
can you expand on this a little? i have a complex form with 2 levels of subforms that i'm converting to Angularjs. The subforms are contained in rails partials. The only way I can see doing this in AngularJs is to move all of my partials out of the /views/model directory and remake them as plain html files (using ngRoute to access) in the javascript directory--is this the best way to do it? Then I would lose all functionality of the form as a fallback if Angular doesn't work. Also will need to handcode in lots of form elements...maybe i'm looking at it wrong?
9

Try this, when it's a hyphen separated word, you need to put within a hash notation.

f.text_field :name, :ng => {:model => "name"}

4 Comments

you can also use a string key: "ng-model" => "name"
or ng_model: "name"
@MurifoX It works for new form, and how about edit existing form? It doesn't fill in the existing value correctly?
You need to put the :value attribute and set it to your model attribute @model.attribute.
3

I was working with AngularJS directives and Rails 4 in order to make the bootstrap-datepicker jquery plugin work on a Rails 4 erb template, the code that I used inside the text_field_tag is the following:

<%= text_field_tag(:start_day, nil, class: 'form-control', datepicker: 'datepicker') %>  

It's important to notice that this works with AngularJS directives, the code that you get on the DOM is as follows:

<input class="form-control" datepicker="datepicker" type="text">

I worked with the directive in the following way:

timeAdminCal.directive('datepicker', function(){
      return {
        restrict: 'A',
        link: function ($scope, $element) {
          $element.datepicker({
            format: 'd/m/yyyy',
            autoclose: true,
            todayHighlight: true
          });
        }
      }
    });

Notice that, according to AngularJS directive docs you can restrict a class name, so you may use any class name on your text_field_tag and it will work too.

timeAdminCal.directive('datepicker', function(){
      return {
        restrict: 'C', // Bind DOM element by class name 'datepicker'
        link: function ($scope, $element) {
          $element.datepicker({
            format: 'd/m/yyyy',
            autoclose: true,
            todayHighlight: true
          });
        }
      }
    });

Comments

3

The following is what worked for me (But it will disable error message("Please enter name.") of angularjs, i.e. required: "required"):

<%= f.input :id, as: :select, label: false, prompt: 'Select a selection',  input_html: { "ng-model" => ""} %>

Comments

0

I think you can use the :html option to set any element attributes. Haven't tried it with angular.js special attributes though ;-)

f.text_field :name, :html => { :ng-model => "name" }

5 Comments

pass the html options hash with the value portion, not the html key, i.e f.text_field :name, :ng-model => "name"
This makes no sense to me. When you're calling a helper, it's supposed to render a string back to your html template, given some source parameters. The goal of Angular is to update the bindings each time they change and it won't, obviously, call the rails helper magically again. If you want Angular behavior you have to stick to plain html.
The only issue with this method is that anything with a single quote will break it
@yagooar, that's not quite right. <%= f.text_field :name, :ng-model => "name" %> will (I'm going from memory here) output <input type="text" id="model_name" name="model[name]" ng-model="name"> on page load, then, after the HTML has been, Angular will parse the page & interpret that input no differently from if you'd skipped Ruby and written the HTML directly - so the correct bindings will still be created and it should work. Then again, I'd agree that it's probably a bad idea to mix Ruby helpers and Angular directives. (Disclaimer: I'm new to Angular)
0

On my current project, I had to start transforming static templates into angular pages, what I did was to render jbuilder views inside the template and put it in ng-init.

If the screen ever becomes part of a single page app, I will simply have to remove that render and add a query to the api to load that data. That's how Twitter does it, and it's simple and effective.

Comments

0

If you use ng-model, this means that you overwrite the form_for behavior for objects. For example, if you have

= form_for :user do |f|
  = f.text_field :username, 'ng-model': user.username

This means the text field will not render value passed from rails controller. You need to add the value of username to angular model inside the angular controller.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.