AndrewIngram / django-extra-views

Django's class-based generic views are awesome, let's have more of them.
MIT License
1.39k stars 172 forks source link

Creating and saving new inline forms in an UpdateWithInlinesView-based form. #245

Closed Maximost closed 2 years ago

Maximost commented 2 years ago

Good day.

I'm having trouble saving newly created inline forms in an UpdateWithInlinesView.

I wrote some basic javascript to do the following:

  1. Duplicate an existing inline form.
  2. Increment numbering in the cloned form for all for, id, and name elements.
  3. Remove the pre-existing object ID (but leave the foreign key id).
  4. increment the TOTALFORMS value.

What's strange is this script works just fine when used in conjunction with the CreateWithInlinesView to create and save one or more new inline forms to the database.

I'm wondering if I need to do something specific in the view.py update view to support creating/validating new objects (in addition to updating the existing ones)?

I've looked around for a solution but have not stumbled across anything that's been helpful. I tried setting the factory_kwargs: extra to 1 to see if there's something I'm missing, but this generates a RelatedObjectDoesNotExist error (which makes sense, since the parent id is not being passed to the new inline form).

Any insight you might have would be very much appreciated. I'm also happy to share the javascript here, once everything is working appropriately.

Thank you so much!

Maximost commented 2 years ago

I'm going to close this as it seems that perhaps this is not closely related to django-extra-views. Also, for those who stumble on this. I have included a refactored old script that accomplishes inline form cloning and saving:

$('.add_form_row').on('click', function(){

  // get inline form count
  var count = parseInt($('.form').length);

  // clone last inline form
  var new_form = $('.form:visible:last').clone().addClass('process');

  // paste clone after last inline
  $('.form').last().after(new_form);
  $('.process').find('form_set-1-id')

  // update cloned form and formcount
  processForm(count);
  updateFormCount(count+1);
  count = 0;
});

function processForm(num) {
  // Increment inline ID
  var cid = parseInt($('.process').attr('id'))+1;

  // Set cloned inline id
  $('.process').attr('id', cid);

  $('.process').find("*").each(function() {
    var form_id = $(this).attr('id');
    var form_for = $(this).attr('for');
    var form_name = $(this).attr('name');

    // replace id
    if (form_id != null) {
      var get_id = form_id.split('-');
      $(this).attr('id', get_id[0]+'-'+num+'-'+get_id[2]);
    }
    // replace for
    if (form_for != null) {
      var get_for = form_for.split('-');
      $(this).attr('for', get_for[0]+'-'+num+'-'+get_for[2]);
    } 
    // replace name
    if (form_name != null) {
      var get_name = form_name.split('-');
      $(this).attr('name', get_name[0]+'-'+num+'-'+get_name[2]);
    }
    // clear inline form id - if exists
    $(this).filter(function() {
      var task_id = (this.id.match(/-id/));
      if (task_id !== null) {
        $(this).removeAttr('value');
      }
    })

    // cleanup
    $('body').find('.process').removeClass('process');
  });
}

function updateFormCount(num) {
  $('#id_myform_set-TOTAL_FORMS').val(num);
}