我有一个可以使用基于this script的js脚本动态更新的表单。动态生成选择列表以允许选择动态生成的字段的属性。但是,该列表包含数百个唯一属性,因此我想添加一个“搜索”框,以便更容易选择。我一直在使用Jquery-ui自动完成功能,当输入框在动态更新的表单之外时它工作正常,但是,一旦我把它放在表单中它就不起作用。以下div动态插入到表单中:
<div id="readroot" style="display: none">
<select name="_name">
<option value="1">1</option>
<option value="2">2</option>
//many more options...
</select>
First text
<input type="text" size="15" name="xyz" /> Second text
<input type="text" size="15" name="xyz2" />
<input type="button" value="Remove trait" onclick="this.parentNode.parentNode.removeChild(this.parentNode);" />
</div>
表格:
<form method="post" name="disForm" target="_blank" id="disForm">
<div id="writeroot"></div>
<input type="button" value="Add trait" onclick="moreFields();" />
</form>
以下是将新字段(“readroot”div)添加到“writeroot”-div的脚本:
<script type="text/javascript">
var counter = 0;
function moreFields() {
counter++;
var newFields = document.getElementById('readroot').cloneNode(true);
//newFields.id = '';
newFields.style.display = 'block';
var newField = newFields.childNodes;
for (var i = 0; i < newField.length; i++) {
var theName = newField[i].name
if (theName)
newField[i].name = theName + counter;
newField[i].title = theName + counter;
}
var insertHere = document.getElementById('writeroot');
insertHere.parentNode.insertBefore(newFields, insertHere);
}
window.onload = moreFields;
</script>
以下是自动填充的输入和脚本:
<input title="autocomplete" name="autocomplete">
<script>
$("[title^='autocomplete']").autocomplete({
source: ["...many values..."]
});
</script>
我正在使用Autocomplete 1.11.4
中的jQuery UI jqueryui.com
。只是为了重复一遍,这个脚本在“readroot
”div之外时可以工作,但在“readroot
” - div内部则不行。为什么它不在“readroot
”div中工作?
更新我已根据pablito.aven的建议更正了代码。添加其他类型的可搜索列表(例如chosenjs)也可以在“readroot”div之外工作,但不在内部。自动完成脚本的工作方式如下:
<div id="readroot" style="display: none">
<select name="_name">
<option value="1">1</option>
<option value="2">2</option>
//many more options...
</select>
First text
<input type="text" size="15" name="xyz" /> Second text
<input type="text" size="15" name="xyz2" />
<input type="button" value="Remove trait" onclick="this.parentNode.parentNode.removeChild(this.parentNode);" />
</div>
<input title="autocomplete" name="autocomplete">//input is outside readroot, Works!
<script>
$("[title^='autocomplete']").autocomplete({
source: ["...many values..."]
});
</script>
但不喜欢这样:
<div id="readroot" style="display: none">
<select name="_name">
<option value="1">1</option>
<option value="2">2</option>
//many more options...
</select>
First text
<input type="text" size="15" name="xyz" /> Second text
<input type="text" size="15" name="xyz2" />
<input type="button" value="Remove trait" onclick="this.parentNode.parentNode.removeChild(this.parentNode);" />
<input title="autocomplete" name="autocomplete"> //input is inside 'readroot' Does not work :(
</div>
<script>
$("[title^='autocomplete']").autocomplete({
source: ["...many values..."]
});
</script>
答案 0 :(得分:1)
我想我现在找到了答案。
当您使用函数moreFields()
添加新选择时,您可以使用readroot
中的代码并在writeroot
之前复制它。您正在复制代码,生成新元素。但是,生成自动完成的脚本已经运行。
<script>
$("[title^='autocomplete']").autocomplete({
source: ["...many values..."]
});
</script>
因此,自动完成功能仅适用于运行脚本时已存在的元素。
我可能会猜测,如果您从display:none
移除readroot
,则自动填充功能会在其中生效,但仍然无法处理动态生成的选择。
您需要做的是在添加更多字段时再次运行该脚本,以便它绑定到新生成的字段。这样的事可能有用:
<script type="text/javascript">
function initializeAutocomplete(){
$("[title^='autocomplete']").autocomplete({
source: ["...many values..."]
});
}
var counter = 0;
function moreFields() {
counter++;
var newFields = document.getElementById('readroot').cloneNode(true);
//newFields.id = '';
newFields.style.display = 'block';
var newField = newFields.childNodes;
for (var i = 0; i < newField.length; i++) {
var theName = newField[i].name;
if (theName){
newField[i].name = theName + counter;
newField[i].title = theName + counter;
}
}
var insertHere = document.getElementById('writeroot');
insertHere.parentNode.insertBefore(newFields, insertHere);
initializeAutocomplete();
}
window.onload = moreFields;
</script>
我还将{}
添加到if
语句,以及一个或两个丢失的分号。
如果这样有效,如果你赞成我的答案,我将感激不尽。如果它没有,我们将不得不继续尝试。
答案 1 :(得分:0)
如果在<select>
内有一个搜索框,我会使用angularJS,它会自动创建搜索框,非常简单友好。
这样的事情就是
<select ng-app="moduleName" ng-controller="controllerName" name="_name" id="unique_id" class="chosen-select" required>
<option ng-repeat="x in options" value="{{x.val}}">{{x.name}}</option>
</select>
你必须用javascript初始化它。
angular.module('moduleName', []).controller('controllerName', function($scope){
$scope.options = [
{val: 'value 1, 'name:'name 1'},
{val: 'value 2', name:'name 2'},
{val: 'value 3', name:'name 3'}
];
});
当你的表单加载dinamically时,你所要做的就是弄清楚如何从你的js脚本填充控制器中$ scope变量的选项
为了使其正常工作,您必须包含angularJS源代码。
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
如果您想了解更多有关angularJS的工作原理,我建议您阅读它here,它不会花太多时间
答案 2 :(得分:0)
您的代码<input type="button" id="moreFields" value="Add trait" onclick="init(this);" />
存在轻微问题
在这里,您可以使用参数调用init函数。在它的定义中,它不需要参数。
function init() {
document.getElementById('moreFields').onclick = moreFields;
moreFields();
}
并且,我不明白为什么在你的html中已经有onclick属性的那个init函数你将点击事件绑定到#moreFields。这个功能不是不必要的吗?也许你可以做<input type="button" id="moreFields" value="Add trait" onclick="moreFields();" />
此外,您的<!--
代码中还有一条html评论专栏(<script></script>
)。我认为你应该删除它,它可能会造成一些麻烦。如果您想对javascript代码发表评论,则应使用//commented line
或/*commented block*/