javascript - 包含单选按钮的 jQuery .clone() HTML 表单 - 保留特定于克隆元素的单选事件

标签 javascript jquery html twitter-bootstrap clone

我正在使用 Bootstrap、jQuery、HTML 和 Django 后端处理一些前端表单。在表单中的某一点,用户应该添加“软件”信息,然后可以选择上传软件文件或使用指向其托管文件的 URL。 URL 选项允许文件可以从多个 URL 位置下载。还有一个添加多个软件包的选项,所以如果他们想添加另一个,有一个“添加”按钮可以克隆表单组并允许用户输入另一个软件包的信息。

我不确定如何在克隆数据获得自己的键值以在后端使用时动态化,但目前我最大的问题是当您单击 Add More Software.. . 按钮,被克隆的单选按钮只影响原始单选按钮,并且没有绑定(bind)到它们的 .switchClass() 事件来改变它们的外观。我一辈子都想不出如何让单选按钮绑定(bind)到它们被克隆的 HTML。我附上了一个 jsfiddle 来查看:

jQuery clone() and Radio Buttons

我的问题是如何使它更具动态性,以便按钮与与单选按钮一起被克隆的 HTML 一起工作,以及如何将克隆的表单组设置为动态的以获取背面的值 -结束?

<div class="software-container">
<div class="form-group">
    <label class="col-sm-2 control-label">
      * Files
    </label>
    <div class="col-sm-9">
      <div class="btn-group" data-toggle="buttons">
        <label id="software-upload-btn" for="software-upload" class="btn btn-default">
          <input id="software-upload" type="radio" name="software-upload" value="upload"> Upload
        </label>
        <label id="software-url-btn" for="software-upload" class="btn btn-default">
          <input id="software-url" type="radio" name="software-url" value="url"> URL
        </label>
      </div>
    </div>
  </div>
  <div id="software-upload-panel" class="hidden">
    <div class="form-group upload-container">
      <div class="col-sm-offset-2 col-sm-9">
        <input type="file" id='software-file' name="software-file" title="" placeholder="No File">
      </div>
    </div>
  </div>

  <div id="software-url-panel" class="hidden">
    <div class="form-group url-container">
      <div class="col-sm-offset-2 col-sm-9">
        <input type="url" id="software-file" name="software-file" class="form-control" placeholder="https://www.example.com/my-software-4.6.tar.gz" title="">
        <button class="close hidden" type="button">x</button>
      </div>
    </div>
    <div class="form-group add-url-container">
      <div class="col-sm-offset-2 col-sm-9">
        <button class="add-url btn btn-default" type="button">
          <i class="glyphicon glyphicon-plus"></i> Add Another URL...
        </button>
      </div>
    </div>
  </div>
</div>

<div class="form-group add-container">
  <label for="add-btn" class="col-sm-2 control-label">
    Add Software:
  </label>

  <div class="col-sm-9">
    <button id="add-software-btn" class="btn btn-default" type="button">
      <i class="glyphicon glyphicon-plus"></i> Add More Software...
    </button>
  </div>
</div>

还有我的js:

$(document).ready(function() {
  // Actions for URL/Upload button options
  $('#software-upload-btn').click(function() {
    if ($('.active')) {
      $('#software-upload-btn').switchClass('btn-default', 'btn-info', 0);
      $('#software-upload-panel').removeClass('hidden');
      $('#software-url-btn').switchClass('btn-info', 'btn-default', 0);
      $('#software-url-panel').addClass('hidden');
    }
  });

  $('#software-url-btn').click(function() {
    if ($('.active')) {
      $('#software-url-btn').switchClass('btn-default', 'btn-info', 0);
      $('#software-url-panel').removeClass('hidden');
      $('#software-upload-btn').switchClass('btn-info', 'btn-default', 0);
      $('#software-upload-panel').addClass('hidden');
    }
  });

  // Add button actions
  $(document).on('click', '.add-url:last', function() {
        $('.url-container:first').clone().insertAfter($('.url-container:last'))
            .find('.close').removeClass('hidden');

        $('.close').click(function() {
            $(this).closest('div.url-container').remove();
        });
    });

  $(document).on('click', '#add-software-btn:last', function() {
    $('.software-container:first').clone(true)
      .insertAfter($('.software-container:last'));
  });
});

最佳答案

更新

好的,为了向您展示这个的强大功能,我做了一些更改:

  • 为 2 个按钮添加了特殊类:.uplBtn.urlBtn
  • .software-container 类添加到 #software-container-1
  • var con = $(this).closest('.software-container'); 这就是每个 software-container 的隔离方式。
    • $(this) 是刚刚点击的特定按钮
    • .closest('.software-container') 将从 $(this) 开始一直到 .software-container.
  • var pkg = $('#' + con.attr('id')); 这很丑陋,但它确实有效。这将连接一串 .software-container id 并将其变成一个 jQuery 对象。

现在,当您单击一个按钮时,它只会打开它原本要打开的面板。顺便说一句,如果您注意到克隆有一个副作用,新克隆将根据克隆之前的状态以隐藏或!隐藏状态开始。也许您应该创建一个看不见且未触及的模板 #software-container-0。或者可能只重置新克隆上的隐藏类一次。

<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <title>34884672</title>
  <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
  <link href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet" />
  <style>
  </style>
</head>

<body>
  <div id="software-container-1" class="software-container">
    <div class="form-group">
      <label class="col-sm-2 control-label">
        * Files
      </label>
      <div class="col-sm-9">
        <div class="btn-group" data-toggle="buttons">
          <label for="software-upload-btn" class="btn uplBtn btn-default">
            <input class="software-upload-btn" type="radio" name="software-upload" value="upload">Upload
          </label>
          <label for="software-url-btn" class="btn urlBtn btn-default">
            <input class="software-url-btn" type="radio" name="software-url" value="url">URL
          </label>
        </div>
      </div>
    </div>
    <div class="software-upload-panel hidden">
      <div class="form-group upload-container">
        <div class="col-sm-offset-2 col-sm-9">
          <input type="file" class='software-upload-file form-control' name="software-upload-file" title="" placeholder="No File">
        </div>
      </div>
    </div>

    <div class="software-url-panel hidden">
      <div class="form-group url-container">
        <div class="col-sm-offset-2 col-sm-9">
          <input type="url" class="software-url-file form-control" name="software-url-file" placeholder="https://www.example.com/my-software-4.6.tar.gz" title="">
          <button class="close hidden" type="button">x</button>
        </div>
      </div>
      <div class="form-group add-url-container">
        <div class="col-sm-offset-2 col-sm-9">
          <button class="add-url btn btn-default" type="button">
            <i class="glyphicon glyphicon-plus"></i> Add Another URL...
          </button>
        </div>
      </div>
    </div>
  </div>

  <div class="form-group add-container">
    <label class="col-sm-2 control-label">
      Add Software:
    </label>

    <div class="col-sm-9">
      <button class="add-software-btn btn btn-default" type="button">
        <i class="glyphicon glyphicon-plus"></i> Add More Software...
      </button>
    </div>
  </div>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
  <script>
    $(document).ready(function() {
      // Actions for URL/Upload button options
      $('label.uplBtn').click(function(event) {
        var con = $(this).closest('.software-container');
        var pkg = $('#' + con.attr('id'));
        console.log('pkg: ' + pkg);
        $(this).switchClass('btn-default', 'btn-info', 0).addClass('active');
        pkg.find('.software-upload-panel').removeClass('hidden');
        pkg.find('label.urlBtn').switchClass('btn-info', 'btn-default', 0).removeClass('active');
        pkg.find('.software-url-panel').addClass('hidden');

        event.stopPropagation();
      });

      $('label.urlBtn').click(function(event) {
        var con = $(this).closest('.software-container');
        var pkg = $('#' + con.attr('id'));
        console.log('pkg: ' + pkg);
        $(this).switchClass('btn-default', 'btn-info', 0).addClass('active');
        pkg.find('div.software-url-panel').removeClass('hidden');
        pkg.find('label.uplBtn').switchClass('btn-info', 'btn-default', 0).removeClass('active');
        pkg.find('div.software-upload-panel').addClass('hidden');

        event.stopPropagation();
      });

      // Add button actions
      $(document).on('click', '.add-url:last', function() {
        $('div[id^="url-container"]:first').clone().insertAfter($('div[id^="url-container"]:last'))
          .find('.close').removeClass('hidden');

        $('.close').click(function() {
          $(this).closest('div[id^="url-container"]').remove();
        });
      });

      $(document).on('click', '.add-software-btn:last', function() {
        var $div = $('div[id^="software-container"]:last');
        var num = parseInt($div.prop("id").match(/\d+/g), 10) + 1;
        var $software_container = $div.clone(true, true).prop('id', 'software-container-' + num);
        $div.after($software_container);

      });
    });
  </script>
</body>

</html>

我想你想克隆 #software-container 并给它们每个一个唯一的 id,这样你就可以从后端 Hook 它们。离开最近的 fiddle ,这是我得到的:https://jsfiddle.net/zer00ne/oay1zbva/

我不确定你是否想要 .clone(true) 但我记得你想保留事件......?

jQuery 变化

  $(document).on('click', '.add-software-btn:last', function() {
    var $div = $('div[id^="software-container"]:last');
    num = parseInt($div.prop("id").match(/\d+/g), 10);
    num++;
    //var $software_container = $div.clone().prop('id', 'software-container-'+num);
    //$div.after($software_container);
    $('.software-container:last').clone(true).insertAfter($('.software-container:last')).prop('id', 'software-container-' + num);;
  });
});

关于javascript - 包含单选按钮的 jQuery .clone() HTML 表单 - 保留特定于克隆元素的单选事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34884672/

相关文章:

javascript - storage.removeItem - 我如何使用它从值而不是键中删除多个项目

javascript - 这个 jquery 不工作

jquery - 如何防止事件处理程序出现在 jQuery 中目标元素内的嵌套元素中?

javascript - 用空字符串替换元素的单词

css - input type=search 不接受高度

javascript预加载图像 - 检查图像是否被缓存/加载以防止预加载

javascript - 如果存在其他类则隐藏类

javascript - 用于扩展信息框的 Leaflet 事件监听器

javascript - 如何使用scrollTop 滚动到页面末尾?

javascript - 从 "GET"参数中获取值 (JavaScript)