jQuery .clone() HTML 包含单选按钮的表单 - 保留特定于克隆元素的单选事件
jQuery .clone() HTML forms that contain radio buttons - keep the radio events specific to the cloned elements
我正在使用 Bootstrap、jQuery、HTML 和 Django 后端处理一些前端表单。在表单中的某一点,用户应该添加 "Software" 信息,然后可以选择上传软件文件或使用 URL 到他们的托管文件。 URL 选项允许文件可以从多个 URL 位置下载。还有一个添加多个软件包的选项,所以如果他们想添加另一个,有一个 "add" 按钮可以克隆表单组并允许用户输入另一个软件包的信息。
我不确定如何在克隆数据获得自己的键值以供后端使用的情况下使此动态化,但目前我最大的问题是当您单击 Add More Software...
按钮时,被克隆的单选按钮只影响原始单选按钮,并且没有绑定到它们的 .switchClass() 事件来改变它们的外观。我这辈子都想不出如何让单选按钮绑定到 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'));
});
});
更新
好的,我做了一些改动,以向您展示 this
的威力:
- 向 2 个按钮添加了特殊的 classes:
.uplBtn
和 .urlBtn
- 将
.software-container
class 添加到 #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
。或者也许只在新克隆上重置隐藏的 classes 一次。
<!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,这样你就可以从 back-end 中挂钩它们。离开最近的 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);;
});
});
我正在使用 Bootstrap、jQuery、HTML 和 Django 后端处理一些前端表单。在表单中的某一点,用户应该添加 "Software" 信息,然后可以选择上传软件文件或使用 URL 到他们的托管文件。 URL 选项允许文件可以从多个 URL 位置下载。还有一个添加多个软件包的选项,所以如果他们想添加另一个,有一个 "add" 按钮可以克隆表单组并允许用户输入另一个软件包的信息。
我不确定如何在克隆数据获得自己的键值以供后端使用的情况下使此动态化,但目前我最大的问题是当您单击 Add More Software...
按钮时,被克隆的单选按钮只影响原始单选按钮,并且没有绑定到它们的 .switchClass() 事件来改变它们的外观。我这辈子都想不出如何让单选按钮绑定到 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'));
});
});
更新
好的,我做了一些改动,以向您展示 this
的威力:
- 向 2 个按钮添加了特殊的 classes:
.uplBtn
和.urlBtn
- 将
.software-container
class 添加到#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
。或者也许只在新克隆上重置隐藏的 classes 一次。
<!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,这样你就可以从 back-end 中挂钩它们。离开最近的 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);;
});
});