title: How to update prefix id of a formset
body: <p>I'm new at python, but no at programing. I'm using Django to create a webapp and in some part, I have to create products. A product has a name, brand and type, but this product can have many "inventories". For example: The product Iphone has a brand Apple, type Phone and since I have 3 in my stock, there is another table that saves 3 individual codes for them (and the price and state as well).
  For this solution I have used formsets, and it was working fine without the JS. What I mean is that the process is ok, but when I want to dinamically add a new row to add a new Inventory, is added visually but then when I tried to save it, it just saves the last row. I have looked into the debug console of chrome and it seems that the problem is that the name and ID, of the new row, remains the same as the original one (the prefix I believe), but I don't know how to change it.  Here is my code: <a href="https://i.stack.imgur.com/7eMZd.png" rel="nofollow noreferrer">Note in this image that the prefix of the second row is 0</a></p>
  
  <p>views.py:</p>
  
  <pre><code>class ProductoInline(InlineFormSetFactory):
  model= Inventario
  fields = ['codigo', 'Producto', 'Precio', 'Estado']
  factory_kwargs = {'extra':1 , 'max_num': 10,
                    'can_order': False, 'can_delete': False}
  
  
  class InventarioCreateView(LoginRequiredMixin, CreateWithInlinesView):
  model = Producto
  inlines = [ProductoInline]
  fields = '__all__'
  factory_kwargs = {'extra': 3, 'max_num': 10,'can_order': False, 
  'can_delete': False}
  template_name = 'ventas/inventario_form.html'
  
  def form_valid(self, form):
      form.instance.author = self.request.user
      return super().form_valid(form)
  </code></pre>
  
  <p>inventario_form.html:</p>
  
  <pre><code>  {%extends "ventas/base.html" %}
    {% load staticfiles %}
    {% load crispy_forms_tags %}
  
    {%block content %}
  
   &lt;section class="card"&gt;
  
   &lt;header class="card-header"&gt;Crea/actualiza producto&lt;/header&gt;
  &lt;div class="card-body"&gt;
      &lt;form method="POST"&gt;
          {% csrf_token %}
          {{ form|crispy }}
  
          {% for formset in inlines %}
  
              &lt;table class="table table-bordered table-responsive-md table-striped text-center"&gt;
  
                  &lt;tr&gt;
                  &lt;th class="text-center"&gt;Código&lt;/th&gt;
                  &lt;th class="text-center"&gt;Precio&lt;/th&gt;
                  &lt;th class="text-center"&gt;Estado&lt;/th&gt;
                  &lt;th class="text-center"&gt;Eliminar&lt;/th&gt;
                  &lt;/tr&gt;
  
              {{formset.management_form}}
  
                  &lt;tbody&gt;
                          {% for form2 in formset %}
                          &lt;tr id="{{ form2.prefix }}-row" class="dynamic-form"&gt;
  
                              &lt;td&gt;{{ form2.codigo }}&lt;/td&gt;
                              &lt;td&gt;{{ form2.Precio }}&lt;/td&gt;
                              &lt;td&gt;{{ form2.Estado }}&lt;/td&gt;
                              &lt;td&gt;&lt;a id="remove-{{ form2.prefix }}-row" href="javascript:void(0)" class="delete-row"&gt;Eliminar&lt;/a&gt;&lt;/td&gt;
  
                          &lt;/tr&gt;
                          {% endfor %}
  
                          &lt;tr&gt;
                              &lt;td colspan="4"&gt;&lt;a href="javascript:void(0)" class="add-row"&gt;Añadir producto&lt;/a&gt;&lt;/td&gt;
                          &lt;/tr&gt;
                  &lt;/tbody&gt;
              &lt;/table&gt;
  
          {% endfor %}
          &lt;button type="submit"&gt;Crear producto&lt;/button&gt;
  
      &lt;/form&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>
  {%endblock content %}</p>
  
  <p>formset.js:</p>
  
  <pre><code>    function updateElementIndex(el, prefix, ndx) {
      var id_regex = new RegExp('(' + prefix + '-\\d+)');
      var replacement = prefix + '-' + ndx;
      if ($(el).attr("for")) $(el).attr("for", 
      $(el).attr("for").replace(id_regex, replacement));
      if (el.id) el.id = el.id.replace(id_regex, replacement);
      if (el.name) el.name = el.name.replace(id_regex, replacement);
   }
  
  function addForm(btn, prefix) {
      var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
      var row = $('.dynamic-form:first').clone(true).get(0);
      $(row).removeAttr('id').insertAfter($('.dynamic-form:last')).children('.hidden').removeClass('hidden');
      $(row).children().not(':last').children().each(function() {
          updateElementIndex(this, prefix, formCount);
          $(this).val('');
      });
      $(row).find('.delete-row').click(function() {
          deleteForm(this, prefix);
      });
      $('#id_' + prefix + '-TOTAL_FORMS').val(formCount + 1);
      return false;
  }
  
  function deleteForm(btn, prefix) {
      $(btn).parents('.dynamic-form').remove();
      var forms = $('.dynamic-form');
      $('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
      for (var i=0, formCount=forms.length; i&lt;formCount; i++) {
          $(forms.get(i)).children().not(':last').children().each(function() {
              updateElementIndex(this, prefix, i);
          });
      }
      return false;
  }
  </code></pre>