0

So in a rails app I have a table in my database, hard drives, and for each hard drive I have a variable number of heads and platters. When I create or edit the hard drive, I want to either a) display dynamically the number of head status and platter status forms that are needed or b) route the user to a page that has the appropriate number of head and status forms continuously on the page. I favor option a, but I think it will require some custom javascript or something in order for it to work (not really feasible unless there is a plugin, I don't know javascript). Really, I want to reject any hard drive that not have it's platter and head statuses entered.

(variable names are of course hard_drive, platter_status, and head_status)

For an example, if I have a laptop drive, I want to define that it has 1 head and platter while creating the drive. Either when the value in the combobox for the head & platter count changes, display the form for the platter & head status. When the create button is hit, it should use the data to create the hard_drive in the database, and each of the platter_status and head_status items as appropriate.

How do I do this? I know that in the view, I have to add something that will detect the change in the combo box and display the layout using the value from the combobox.

It is similar in nature to this


Edit 1: So, I have this, and so far it's not working, but I have the right idea. I stumbled upon some threads that talk about using javascript to dynamically add html.

  <div class="field" id="head_count" >
    <label for="hard_drive_head_count">Head count</label><br />
    <input id="hard_drive_head_count" name="hard_drive[head_count]" type="number" value="0" />
    <script type="text/javascript">
      var input = document.getElementById('hard_drive_head_count'),
        events = [
        "input",
         ];
      events.map(function(ev) {
      input.addEventListener(ev, function() {
        console.log(ev + ' => ' + input.value);
    if (parseInt(input.value) === 1) {
      document.getElementById('platter_statuses').innerHTML= "howdy";
    } else {
      document.getElementById('platter_statuses').innerHTML="";
    }
      }, false);
      });
    </script>
  </div>
  <label for="platter_status">Platter status</label><br />
  <div class="field" id="platter_statuses" >

  </div>

Now that I have this however, the question moves to - how can I populate this quickly with the forms from the _form.html.erb for the platter_status views, with the stuff all filled in from the database as it should? I thought about in the else, using some dynamic ruby, but I don't know exactly how to pass an argument (the platter number and the drive id) so that the database knows what to populate it with, and I don't know what to put after the @ in <%= @SOMETHING_HERE %> so that it resolves to the platter_status view...

Community
  • 1
  • 1
Adam Miller
  • 1,756
  • 1
  • 25
  • 44

1 Answers1

0

I actually found that there is a helper that is great for what I needed. It's the accepts_nested_attributes_for function in the model. This, combined with rails cast 196 and 197 helped me achieve exactly what I wanted.

In the hard_drive model, you should have a:

attr_accessible :head_statuses_attributes
has_many :head_statuses, :dependent => :destroy
accepts_nested_attributes_for :head_statuses, :allow_destroy => true

for the head_status and platter_status models.

In the view, you'll need a line like this:

<%= link_to_add_fields "add head status", f, :head_status %>

and in the partial outside of any tag, you'll need a:

 <%= link_to_remove_fields "Remove", f %> 

For more information, see these articles: how accepts_nested_attributes_for works

How the dynamic editing is possible How the dynamic editing is possible part 2

Community
  • 1
  • 1
Adam Miller
  • 1,756
  • 1
  • 25
  • 44