Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use AngularJS with Rails Form?

I'm using simple_form with AngularJS:

= simple_form @post do |f|
  = f.input :title, input_html: { "ng-model" => "title" }

It works great for my scenario on new post, but for editing on existing post, it doesn't bind/fill in existing value from post's title on form. From what I thought Rails already fill in the value, but AngularJS wipes it out after the page load because $scope.title is blank.

like image 586
Samnang Avatar asked Feb 13 '26 05:02

Samnang


1 Answers

I found the trick is to actually create a controller with an init function that takes the value you want. In my case I just created a app/assets/javascripts/angular_app.js file that looks like this:

//= require_self
AngularRails = angular.module('AngularRails', []);
AngularRails.controller('PostFormCtrl', function($scope) {
  $scope.init = function(title) {
    $scope.title = title;
  }
});

You'll have to translate the view into haml but it should look something like this:

<div ng-app="AngularRails">
  <div ng-controller="PostFormCtrl" ng-init="init('<%= @post.title %>')">
    <%= form_for @post, html: {name: "postForm", "novalidate" => true} do |f| %>
      <%= f.text_field :title, "ng-model" => "title", required: true %>
      <%= f.submit "ng-disabled" => "postForm.$invalid" %>
    <% end %>
  </div>
</div>

Remember to include the angular_app file into application.js and it should world. Obviously, this isn't a very robust solution but you could use active model serializer to convert the rails object to a json object. Then, pass that json object to the init function and in the controller, iterate over the key/value pairs of that json object and set them to $scope. Something like this:

AngularRails.controller('PostFormCtrl', function($scope) {
  $scope.init = function(input) {
    Object.keys(input).forEach(function(key) {
      $scope[key] = input[key];
    });
  };
});

Hope that helps!

like image 130
Tyler Morgan Avatar answered Feb 15 '26 14:02

Tyler Morgan