0

I am building a nested simple_form_for in rails using cocoon to dynamically add and remove nested elements. The main model object is a quote and a quote has many employees. I've reached the limit of my amateur code skills and would like some guidance on writing a neat js script so to achieve the following:

  • if nested_object.count <= 2 then remove_empee_link.hide
  • if nested_object.count > 2 then remove_empee_link.show, but not on the first two nested_objects.

  • if nested_object.count > 10 then add_empee_link.hide, otherwise always add_empee_link.show

Adapted from a really helpful post here courtesy of @nathanvda I've got to here;

$(document).ready(function() {
   function check_to_hide_or_show_add_empee_link() {
     if ($('#empee-form .nested-fields:visible').length == 5) {
       $('#empee-form .links a').hide();
     } else {
       $('#empee-form .links a').show();
     }
   }

   $('#empee-form').on('cocoon:after-insert', function() {
     check_to_hide_or_show_add_empee_link();
   });

   $('#empee-form').on('cocoon:after-remove', function() {
     check_to_hide_or_show_add_empee_link();
   });

   check_to_hide_or_show_add_empee_link();     
 });

$(document).ready(function() {
   function check_to_hide_or_show_remove_empee_link() {
     if ($('#empee-form .nested-fields:visible').length <= 2) {
       $('.remove_fields').hide();
     } else {
       $('.remove_fields').show();
     }
   }

   $('#empee-form').on('cocoon:after-insert', function() {
     check_to_hide_or_show_remove_empee_link();
   });

   $('#empee-form').on('cocoon:after-remove', function() {
     check_to_hide_or_show_add_remove_empee_link();
   });

   check_to_hide_or_show_add_remove_empee_link();     
 });

But I'm struggling to put a strategy together on how I can I achieve what I outlined in my biullets above in a neat solution, any guidance would be really appreciated after starting and playing with this for hours. Thanks

The updated code that I've now written, but the behavior is unexpected;

  • If 1, 2 or 3 nested elements on page, then all remove_links hidden.
  • If 4 nested elements on page then 1st, 2nd & 4th have remove_link hidden
  • If 5 nested elements on page then 1st, 2nd & 3rd have remove_link hidden

Intended behaviour, 1st and 2nd remove_links hidden always, anoy others shown:

// Hiding the 1st 'remove employee' link for the first two employee fields.
$(document).ready(function() { 
    function hide_first_and_second_remove_empee_links() {
        var remove_links = $('.remove_fields')
        $(remove_links[0]).hide();
        $(remove_links[1]).hide();
        // $('a.remove_fields:first-child').hide();
        // $('a.remove_fields:nth-child(2)').hide();
    }
    $('#empee-form').on('cocoon:after-insert', function() {
    hide_first_and_second_remove_empee_links();
  });
  $('#empee-form').on('cocoon:before-insert', function() {
    hide_first_and_second_remove_empee_links();
  });
  hide_first_and_second_remove_empee_links();
});

How can this be? There's one method, it collects all .remove_fields' into the remove_links var, then wraps the[0]element of that collection in a jQuery object and callshideon it. Then the same to the1element. That method is called on page ready and then again oncocoon:before-insertandafter-insert. I don't see how the definition of the[0]and the1` elements changes?

jbk
  • 1,911
  • 19
  • 36

1 Answers1

1

Your logic becomes easier when you write:

  • always hide the first two remove links
  • hide the add association link if there are more than 10 employees

The second is already covered in your answer.

The first one is actually pretty easy using jquery:

$('.remove-fields:first-child').hide()
$('.remove-fields:nth-child(2)').hide()
nathanvda
  • 49,707
  • 13
  • 117
  • 139
  • Thanks @nathanvda, definitley your proposed logic makes more sense ;), though I couldn't get the :nth-child or first-child methods to work at all. Instead I've resorted to creating a collection, writing a function to hide the [0] and [1] elements of the selection and calling that function on cocoon:before-insert and after-insert. However that's resulting in behavior I can't quite fathom. When you have a mo would you be kind enough to nosey at the code I'm using in the updated question body to help me understand. V much appreciated. – jbk Jun 25 '17 at 13:39
  • Can you show your views, so we can see how your html is built? – nathanvda Jun 26 '17 at 23:26