动态地从Django表单添加和删除字段

时间:2018-10-22 00:46:50

标签: javascript jquery django django-forms

我有一个带有内联表单集的django表单,我想为用户提供添加/删除字段“ approach_type”和“ approach_number”的功能

这是以下形式的代码段:

    <div class="form-group">
  <div class="input-group-sm">
    <label class="text-muted">Approaches</label>
    <div class="form-control pl-4 pt-2">


        <div class="row form-row">
          <input type="hidden" name="approach_set-TOTAL_FORMS" value="1" id="id_approach_set-TOTAL_FORMS" /><input type="hidden" name="approach_set-INITIAL_FORMS" value="0" id="id_approach_set-INITIAL_FORMS" /><input type="hidden" name="approach_set-MIN_NUM_FORMS" value="0" id="id_approach_set-MIN_NUM_FORMS" /><input type="hidden" name="approach_set-MAX_NUM_FORMS" value="1000" id="id_approach_set-MAX_NUM_FORMS" />

          <input type="hidden" name="approach_set-0-id" id="id_approach_set-0-id" />
          <div class="col pr-5>"><select name="approach_set-0-approach_type" class="form-control" id="id_approach_set-0-approach_type">
  <option value="" selected>---------</option>

  <option value="ILS">ILS</option>

  <option value="CATII">CAT II</option>

  <option value="CATIII">CAT III</option>
</select></div>
          <div class="col pr-5>"><input type="number" name="approach_set-0-number" min="0" class="form-control" id="id_approach_set-0-number" /> </div>
          <div class="input-group-append">
            <button class="btn btn-success add-form-row">+</button>
          </div>
          <!-- <div class="col pr-5>"><input type="checkbox" name="approach_set-0-DELETE" class="form-control" id="id_approach_set-0-DELETE" /></div> -->
       </div>

,这是本教程中的JS: https://medium.com/@taranjeet/adding-forms-dynamically-to-a-django-formset-375f1090c2b0

    <script type='text/javascript'>
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 cloneMore(selector, prefix) {
    var newElement = $(selector).clone(true);
    var total = $('#id_' + prefix + '-TOTAL_FORMS').val();
    newElement.find(':input').each(function() {
        var name = $(this).attr('name').replace('-' + (total-1) + '-', '-' + total + '-');
        var id = 'id_' + name;
        $(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
    });
    total++;
    $('#id_' + prefix + '-TOTAL_FORMS').val(total);
    $(selector).after(newElement);
    var conditionRow = $('.form-row:not(:last)');
    conditionRow.find('.btn.add-form-row')
    .removeClass('btn-success').addClass('btn-danger')
    .removeClass('add-form-row').addClass('remove-form-row')
    .html('<span class="glyphicon glyphicon-minus" aria-hidden="true"></span>');
    return false;
}
function deleteForm(prefix, btn) {
    var total = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
    if (total > 1){
        btn.closest('.form-row').remove();
        var forms = $('.form-row');
        $('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
        for (var i=0, formCount=forms.length; i<formCount; i++) {
            $(forms.get(i)).find(':input').each(function() {
                updateElementIndex(this, prefix, i);
            });
        }
    }
    return false;
}
$(document).on('click', '.add-form-row', function(e){
    e.preventDefault();
    cloneMore('.form-row:last', 'form');
    return false;
});
$(document).on('click', '.remove-form-row', function(e){
    e.preventDefault();
    deleteForm('form', $(this));
    return false;
});
</script>

此行是当前问题:

var name = $(this).attr('name').replace('-' + (total-1) + '-', '-' + total + '-');

对不起,但我只了解一点点JS。

1 个答案:

答案 0 :(得分:1)

因此,正如您在评论中指出的那样,问题在于$(this).attr('name')返回的是未定义的。看起来由于某种原因,您的查询也返回了按钮,如果您查看jquery documentation,这有点意义...尽管我不知道 I 是否会将按钮视为自动输入,但他们可以。我也不是100%知道要执行的操作,但是要解决此问题,您可以将该代码块包装在if块中,以检查名称attr是否未定义,将输入的查询更改为更严格,或过滤掉正在运行的列表。这是一个codepen,我认为正在按预期的方式工作,但同样,由于没有阅读整篇中篇文章,因此没有任何承诺。相关部分在这里:

 newElement.find(':input')
  .filter(function(){
    return $(this).attr('name');
})
  .each(function(){
    ...
  })

过滤器功能实质上是说过滤掉所有未定义name属性的结果。

让我知道这是否符合您的期望!祝您学习Java脚本好运!我保证您现在正在处理的事情会更加有趣。特别是如果您开始使用ES6