Client side deleted object instance and sends to the server

Asked

Viewed 104 times

2

I wonder if anyone has ever been through this problem and how did you solve it.

I am using JSP and Spring Data JPA.

I delete records from the middle of a form that’s a detail using Javascript, right? But when I give a POST the server creates that (s) deleted object(s) with the null attributes. I would not like this to happen, as much as I can validate to delete it on the server, because the object will take up space in the server memory.

But when I delete the last record with Javascript it does not instance this last object on the server. Only the middle.

inserir a descrição da imagem aqui

Thank you in advance.

1 answer

2


The problem

The Binding among the inputs and the List in the Spring model is done through an index in the name of the input. For example:

<form:input path="products[${i.index}].quantidade" id="quantidade${i.index}" />
<form:input path="products[${i.index}].total" id="total${i.index}" />

Your Javascript logic is probably simply removing the elements from form, e. g.:

function removeProduct(index) {
  var myForm= document.getElementById('form');
  var quantidade = document.getElementById('product[' + index + '].quantidade');
  var total = document.getElementById('product[' + index + '].total');
  myForm.removeChild(quantidade);
  myForm.removeChild(total);
}

As a consequence, after removing any item other than the last one from the list, the inputs in his form get messy, e.g.:

<input type="text" name="products[0].quantidade" id="quantidade1" value="10" />
<input type="text" name="products[0].total" id="total1" value="10000" />
<input type="text" name="products[3].quantidade" id="quantidade4" value="8" />
<input type="text" name="products[3].total" id="total4" value="800" />

When you submit this form the Spring popularize the list by skipping the elements in the indexes 1 and 2.

Solutions

  1. Reindexar the names of inputs with client-side Javascript (for example, after each removal or before sending the form). This is the most "clean" solution, but it can get complicated, especially when you have nested lists within lists. If you go that way I suggest you structure your Markup in order to facilitate the change of name of inputs of a common product (e.g., by grouping the sets of inputs of a product with a div).

  2. Do not remove the inputs. You can use any logic instead of removing the inputs from the DOM. For example, you can hide the inputs and include a input hidden to indicate that the attribute has been removed. This is an easy solution, but it wastes a bit of bandwidth and memory as you well noted.

    <form:hidden path="products[${status.index}].remove" />
    
  3. Ajax: You can do operations dynamically in the background every time the user clicks to remove. This is a good solution thinking about keeping the atomic operations (each item in the list is updated individually), but it is important that you understand the trade-offs in terms of usability. By making an Ajax call every time someone clicks to remove from the Javascript side you are anticipating the removal operation to before the submit (what may or may not be desirable).
  4. Clear the list before using it on the server side: It’s ugly more works.
  5. Use a self-organizing collection. I marked an article in the references that implements a ShrinkableLazyList

References:

  1. Spring MVC and form Binding : how to remove an item from a List ?

  2. Dynamic Forms, Lazylist and Transparent items Removal

  • Excellent response!

  • Thank you very much to all the answers, they don’t know how much it helped. And let’s continue like this, learning and growing.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.