javascript - 使用js计算表单字段

标签 javascript jquery

我有这样的表格:

<form method="post" action="">
   <label for="id_count-count">Count:</label>
   <input id="id_count-count" type="number" name="count-count">
   <div class="extrafieldWrapper"></div>
   <input type="submit" value="Submit">
</form>

根据字段count 的数量,我添加或删除了几个新的字段itemitem2。例如:如果字段 count 的值为 2,它将生成两对字段 itemitem2

有这个字段:

<label for="id_items-0-item">Item:</label>
<input id="id_items-0-item" type="number" name="items-0-item">
<label for="id_items-0-item2">Item2:</label>
<input id="id_items-0-item2" class="children_age" type="number" name="items-0-item2" value="0">
<div class="extrafieldWrapperChAge"></div>

然后,根据字段 item2 的每个值,我添加调用 childrenage 的新字段。 childrenage 字段看起来如何:

<label for="id_childrenage-0-childrenage">ChildrenAge 1</label>
<input id="id_childrenage-0-childrenage" type="number" name="childrenage-0-childrenage" value="0">

这是 fiddle link . 这是我想要的和我已经得到的 link .

根据 item2 的值,childrenage 的 id 也在变化。例如,如果我将“3”作为 item2 的值,则我有 id_childrenage-0-childrenageid_childrenage-1-childrenageid_childrenage-2-childrenage。如果我有几个 item2 我有 childrenage 的新例子,从一开始就为每个 item2 计算他们的 id:

<label for="id_items-0-item2">Item2:</label>
<input id="id_items-0-item2" class="children_age" type="number" name="items-0-item2" value="2">
<div class="extrafieldWrapperChAge">
   <label for="id_childrenage-0-childrenage">ChildrenAge</label>
   <input id="id_childrenage-0-childrenage" type="number" name="childrenage-0-childrenage" value="0">
   <label for="id_childrenage-1-childrenage">ChildrenAge</label>
   <input id="id_childrenage-1-childrenage" type="number" name="childrenage-1-childrenage" value="0">
</div>
<label for="id_items-0-item2">Item2:</label>
<input id="id_items-0-item2" class="children_age" type="number" name="items-0-item2" value="1">
<div class="extrafieldWrapperChAge">
   <label for="id_childrenage-0-childrenage">ChildrenAge</label>
   <input id="id_childrenage-0-childrenage" type="number" name="childrenage-0-childrenage" value="0">
</div>

在上面的示例中,我有 2 个字段 item2,其中一个值为“2”,另一个值为“1”。根据这个,我有两个 childrenage 字段,第一个 item2 的 id id_childrenage-0-childrenageid_childrenage-1-childrenage ,一个字段 childrenage 用于第二个 ID 为 id_childrenage-0-childrenage 的字段。但我需要从第一个 item2 到最后一个 childrenage 的 id 计数,这是示例:

<label for="id_items-0-item2">Item2:</label>
<input id="id_items-0-item2" class="children_age" type="number" name="items-0-item2" value="2">
<div class="extrafieldWrapperChAge">
   <label for="id_childrenage-0-childrenage">ChildrenAge</label>
   <input id="id_childrenage-0-childrenage" type="number" name="childrenage-0-childrenage" value="0">
   <label for="id_childrenage-1-childrenage">ChildrenAge</label>
   <input id="id_childrenage-1-childrenage" type="number" name="childrenage-1-childrenage" value="0">
</div>
<label for="id_items-0-item2">Item2:</label>
<input id="id_items-0-item2" class="children_age" type="number" name="items-0-item2" value="1">
<div class="extrafieldWrapperChAge">
   <label for="id_childrenage-2-childrenage">ChildrenAge</label>
   <input id="id_childrenage-2-childrenage" type="number" name="childrenage-2-childrenage" value="0">
</div>

这是实现这个的js代码:

$(function(){
   $('#id_count-count').on('change', function(e){
      var n = $('#id_count-count').val() || 0;
      var html = "<input id='id_items-TOTAL_FORMS' type='hidden' value='" + n + "' name='items-TOTAL_FORMS'>"
         + "<input id='id_items-INITIAL_FORMS' type='hidden' value='0' name='items-INITIAL_FORMS'>"
         + "<input id='id_items-MIN_NUM_FORMS' type='hidden' value='0' name='items-MIN_NUM_FORMS'>"
         + "<input id='id_items-MAX_NUM_FORMS' type='hidden' value='15' name='items-MAX_NUM_FORMS'>";

      for (var i = 0; i < n; i++) {
         html += "<div>Items" + (i + 1) + "</div>"
            + "<br/><label for='id_items-" + i + "-item'>Item:</label>"
            + "<input id='id_items-" + i + "-item' type='number' name='items-" + i + "-item'/>"
            + "<label for='id_items-" + i + "-item2'>Item2:</label>"
            + "<input id='id_items-" + i + "-item2' type='number' value='0' name='items-" + i + "-item2' class='children_age'/>"
            + "<div class='extrafieldWrapperChAge'></div>";
      }
      $(".extrafieldWrapper").html(html);
   });
   $(".extrafieldWrapper").on('change', '.children_age', function(e){
      var n = $(this).val() || 0;
      var html = "<input id='id_childrenage-TOTAL_FORMS' type='hidden' value='" + n + "' name='childrenage-TOTAL_FORMS'>"
         + "<input id='id_childrenage-INITIAL_FORMS' type='hidden' value='0' name='childrenage-INITIAL_FORMS'>"
         + "<input id='id_childrenage-MIN_NUM_FORMS' type='hidden' value='0' name='childrenage-MIN_NUM_FORMS'>"
         + "<input id='id_childrenage-MAX_NUM_FORMS' type='hidden' value='15' name='childrenage-MAX_NUM_FORMS'>"; 

      for (var i = 0; i < n; i++) {
         html += "<br/><label for='id_childrenage-" + i + "-childrenage'>ChildrenAge "+(i+1)+"</label>"
            + "<input id='id_childrenage-" + i + "-childrenage' type='number' value='0' name='childrenage-" + i + "-childrenage' />";
      }
      $(this).next('.extrafieldWrapperChAge').html(html);
   });

});

希望你明白我的意思。 我是 java-script 的新手,你能帮我以正确的方式编写代码吗?非常感谢!

最佳答案

这个特定的答案变得不必要地冗长,所以我决定将其 chop 为当前答案。

代码

$(function() {
  var fieldset = $('<fieldset>');
  var legend = $('<legend>');
  var input = $('<input>').prop('type', 'number');
  var hidden = $('<input>').prop('type', 'hidden');
  var label = $('<label>');
  var child_wrapper = $('<div class="child-wrapper">');
  /*
    Here we create a couple of new HTML elements. These elements are not a part of the 
    HTML DOM yet and can therefore be manipulated without any visual changes.
  */
  var create_hidden_fields = function(str, fields_arr) {
    var ret = [];
    //return array;
    $.each(fields_arr, function(i, obj) {
      //Loops through each field to set up the hidden values
      var h = hidden.clone();
      //Clones the hidden fields
      h.prop('id', 'id_' + str + '-' + obj.name).prop('name', str + '-' + obj.name).val(obj.value);
      //Sets the ID, name, and value.
      ret.push(h);
    });
    return ret;
  };

  $('#id_count-count').on('change', function(e) {
    var n = $(this).val() || 0;
    //Gets the id count value, or 0;

    var hidden_fields = [{
      name: 'TOTAL_FORMS',
      value: n
    }, {
      name: 'INITIAL_FORMS',
      value: 0
    }, {
      name: 'MIN_NUM_FORMS',
      value: 0
    }, {
      name: 'MAX_NUM_FORMS',
      value: 15
    }];
    //Hidden fields pre-build, makes life easier, since there seems to be a pattern

    var h_arr = create_hidden_fields('items', hidden_fields);
    //Hidden Array created
    if ($(this.form).children(':hidden')) {
      $(this.form).children(':hidden').remove();
      //Removes all the current hidden fields, because lazy.
    }
    $(this.form).prepend(h_arr); //adds in our created hidden fields.

    var form = $(this.form).children('.extra-field-wrapper');
    //Gets the fieldset wrapper.
    form.empty();
    //Empties any children there already. Otherwise extra children are added.

    for (var i = 0; i < n; i++) {
      var fs_clone = fieldset.clone(); //clones the fieldset element
      var l_clone = legend.clone().text("Item " + (i + 1));
      // clones the legend element and adds text
      var la_clone_1 = label.clone();
      //label clone 1
      var input_clone_1 = input.clone();
      //Input clone 1
      var child_wrapper_clone = child_wrapper.clone().prop('id', 'parent-' + (1 + i));
      //We use clones to keep our initial values safe. This way we can alter the clones without changing our defaults

      fs_clone.append(l_clone);
      //Adds our legend up top for readability;      
      la_clone_1.prop('for', 'id-items-' + i + '-item').html('Parent ' + (i + 1));
      //Adds the 'for' property with the correct ID, then sets the HTML. Item and Item2 were getting confusing
      input_clone_1.prop('value', 0).prop('id', 'id-items-' + i + '-item');
      //Sets the default value to 0, and the necessary ID for our label to work
      var la_clone_2 = label.clone().html('# of Children').prop('for', 'id-items-' + i + '-num-children');
      /*
       This is a lot in one line, it clones the label element, adds the HTML, and sets the property all in one.
      */
      var input_clone_2 = input.clone().prop('id', 'id-items-' + i + '-num-children').prop('value', 0).addClass('children_age');
      //See above comment. One difference is that this adds our class for our next function to work

      fs_clone.append([la_clone_1, input_clone_1, la_clone_2, input_clone_2, child_wrapper_clone]);
      //This could probably be cleaned up, but for now it works.

      form.append(fs_clone); //adds the fieldset clone to the form.
    } //End for

  });

  $(".extra-field-wrapper").on('change', '.children_age', function(e) {

    var n = $(this).val() || 0;
    // the current value of the item
    var append_array = [];
    //Add an HTML append array, lessens calls to the $(this).next().append();

    $(this).before(h_arr);
    //Adds the hidden elements before this element

    $(this).next('.child-wrapper').empty();
    //Clears the child elements

    for (var i = 0; i < n; i++) {
      var l_clone = label.clone().html('Children Age' + (i + 1));
      var i_clone = input.clone().addClass('child-age').prop('value', 0);

      append_array.push(l_clone);
      append_array.push(i_clone);
      //Adds the elements to the append_array since we are now done with them.
    }

    $(this).next('.child-wrapper').append(append_array);
    //Adds all created elements;

    var children_age = $('input.child-age').each(function(i, el) {
      var self = $(el);
      //Lazy handle
      var label = $(el).prev();
      //The label is the element in front of our current element.
      label.text("Child Age " + (i + 1)).prop('for', 'id_childrenage_' + i + '_childrenage');
      //Gives correct label number /re does the for property;
      self.prop('id', 'id_childrenage_' + i + '_childrenage');
      //give correct id now that changes have been made to the dom.
    });


    var hidden_fields = [{
      name: 'TOTAL_FORMS',
      value: children_age.length
    }, {
      name: 'INITIAL_FORMS',
      value: 0
    }, {
      name: 'MIN_NUM_FORMS',
      value: 0
    }, {
      name: 'MAX_NUM_FORMS',
      value: 15
    }];
    //We have to redeclare this function here in order for the value: n  to work correctly.
    if ($('#id_childrenage-TOTAL_FORMS').length == 0) {
      //This element does not exist yet in the DOM
      var hidden_fields = [{
        name: 'TOTAL_FORMS',
        value: children_age.length
      }, {
        name: 'INITIAL_FORMS',
        value: 0
      }, {
        name: 'MIN_NUM_FORMS',
        value: 0
      }, {
        name: 'MAX_NUM_FORMS',
        value: 15
      }];
      //We have to redeclare this function here in order for the value: n  to work correctly.

      var h_arr = create_hidden_fields('childrenage', hidden_fields);
      //creates the hidden fields
      $(this.form).prepend(h_arr);
    } else {
      $('#id_childrenage-TOTAL_FORMS').val(children_age.length);
    }


  });

});
label {
  font-weight: 800;
}
input[type="number"] {
  width: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="post" action="">
  <label for="id_count-count">Count:</label>
  <input id="id_count-count" type="number" name="count-count">
  <div class="extra-field-wrapper"></div>
  <input type="submit" value="Submit">
</form>

解释

我在这里做了一些事情,很可能有更好的方法,但我在自己的时间限制下做了最好的。

  1. 我创建要复制到 jQuery 中的项目,因为我是老派,我只是不记得 template 标签是如何工作的,所以我远离它的特殊魔法。字段集和图例只是为了可读性。在您的实际代码中,您可以只删除它们的引用以及 fs_clonel_clone,而是将项目直接附加到表单元素。
  2. 我创建了一个仅存在于我们的包装匿名函数领域内的函数,称为 create_hidden_​​fields,作为一名程序员、数学家和所有懒惰的人,我注意到了命名约定中的模式,这很有吸引力对我而言,每次我想创建一个字段时都必须手动创建和复制一堆项目。
  3. 我有 id_childrenage-TOTAL_FORMS(顺便说一下,这是我遇到过的最奇怪命名约定)表单本身。因为我们不需要超过 1 个输入副本。
  4. 在两个函数中重新声明 hidden_​​fields 数组的原因很简单:如果它在变量 n 之前声明,则 TOTAL_FORMS输入不会有正确的值。不好。
  5. 希望其他一切都可以通过我在代码中的评论来回答。

快乐编码。

关于javascript - 使用js计算表单字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37096809/

相关文章:

javascript - 如何捕获组中特定网格上的点击事件

javascript - 用于在集合中获取子项和孙子项的 Mongoose 查询

javascript - 使用 Vanilla javascript 将元素高度设置为等于宽度

JavaScript 模板

jquery - 链接 "siblings"和 "not"方法

javascript - JQuery:使用 JSON 填充 HTML 下拉菜单

javascript - Highchart 实时服务器示例使用大量 CPU

jquery 验证和 ajax.beginform

jquery - 动画结束后如何删除类(class)?

javascript - 为什么开发人员编写这些类型的脚本来嵌入,而一个简单的标签就可以做到?