Rails + CoffeeScript + Jquery – Marking multiply objects for destruction at a time (frontend)

When we build complicated nested forms (for example with 2 or more nested resources in it), quite often we would like to add a multiply remove feature. For example to remove whole groups of resources. We can't do this by simply removing HTML form parts, because objects related to this form parts won't be deleted. Instead, Rails use a
_destroy input that should be set to true, when we want to remove an object (but the form part still needs to be sent).

<input 
  type="hidden" 
  value="false" 
  name="product[groups_attributes][0][_destroy]" 
  id="product_groups_attributes_0__destroy" 
  class="hidden"
>

It is quite easy to use when we remove one resource at a time, we can just do this:

$('#product').find( 'input:hidden' ).val(true)

Of course it is far from being perfect, but for one resource it should do the job. We don't search using _destroy, we just assume, that only the hidden field that is there is the one that we want. Bad idea

What should we do, when we have multiply hidden fields and we only want to set value for those responsible for destruction? Well, we can use a nice Jquery feature: filter with a regexp.

destroy: (node) ->
  node.hide()
  node.find('input').filter ->
    return this.id.match(/__destroy/)
  .val('true')

We get a node (this is the tree part, that we want to remove), we iterate through all the inputs and we take only those, that have an __destroy postfix in their ID. Then we set all of them to true and we hide the whole node (so user will think, that it was removed). After we send such a form, Rails will know that it should remove all objects that were marked for destruction.

Categories: Default

3 Comments

  1. IMO, this should be done on the server side to ensure the data consistency. what if someone modified the html or javascript on the client side?

  2. Well this is not meant to be used as a replacement to data manipulation policies. It’s just a convenient way to mark multiply objects for destruction.

  3. Or just use http://www.w3.org/TR/css3-selectors/#attribute-substrings , i.e. node.find(‘input[id$=__destroy]’).val(…)

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Copyright © 2024 Closer to Code

Theme by Anders NorenUp ↑