我有一个在rails中生成的表单,允许用户使用“添加对象”按钮添加对象的任意数量的实例。对象的每个实例都显示相同的表单。我希望该表单在选择输入中选择特定选项时动态显示字段。
我在当前的JS中遇到的问题是,当我在一个表单上更改我的选择输入时,页面上的其余表单反映了这一变化。我需要JS只反映正在修改的表单上的更改。
# HTML
<form id=edit_application>
<div class="fields">
<select class="asset_type">
<option value="Machinery">Machinery</option>
<option value="Equipment">Equipment</option>
<option value="Property">Property</option>
</select>
<div class="Machinery">
# input field
</div>
<div class="Equipment">
# input field
</div>
<div class="Property">
#input field
</div>
</div>
<div class="fields">
<select class="asset_type">
<option value="Machinery">Machinery</option>
<option value="Equipment">Equipment</option>
<option value="Property">Property</option>
</select>
<div class="Machinery">
# input field
</div>
<div class="Equipment">
# input field
</div>
<div class="Property">
#input field
</div>
</div>
</form>
对象表单的每个实例都包含在
中<div class="fields"></div>.
我用来在rails中生成嵌套对象表单的gem提供了一个触发器,我正在使用它(嵌套:fieldAdded)来在添加新实例时运行JS函数。
$(function() {
$(document).on('nested:fieldAdded', function(event){
$(".property").hide();
$(".equipment").hide();
$(".machinery").hide();
});
});
$(function() {
$('.asset_type').on('change', function () {
$( "select option:selected").each(function(){
if($(this).attr("value")=="Property"){
$(".property").show();
$(".equipment").hide();
$(".machinery").hide();
}
if($(this).attr("value")=="Machinery"){
$(".machinery").show();
$(".property").hide();
$(".equipment").hide();
}
if($(this).attr("value")=="Equipment"){
$(".property").hide();
$(".equipment").show();
$(".machinery").hide();
}
});
}).change();
});
我在上述函数背后的逻辑是,当添加对象的新实例时,应隐藏字段。当用户更改选择输入时,结果应显示正确的div,并确保隐藏其他div,但是当选择输入更改为“Property”时,它不应更改为每个显示的所有字段页面上的表格。
答案 0 :(得分:1)
我对html稍作修改,这样你就可以知道你正在查看哪个输入字段。在asset_type选项的change函数内部,我得到最接近的字段div。我使用该引用来过滤您想要显示的div
<form id=edit_application>
<div class="fields">
<select class="asset_type">
<option value="Machinery">Machinery</option>
<option value="Equipment">Equipment</option>
<option value="Property">Property</option>
</select>
<div class="Machinery">
# machinery input field
</div>
<div class="Equipment">
# equipment input field
</div>
<div class="Property">
# property input field
</div>
</div>
<div class="fields">
<select class="asset_type">
<option value="Machinery">Machinery</option>
<option value="Equipment">Equipment</option>
<option value="Property">Property</option>
</select>
<div class="Machinery">
# machinery input field
</div>
<div class="Equipment">
# equipment input field
</div>
<div class="Property">
# property input field
</div>
</div>
</form>
$(function() {
$(document).on('nested:fieldAdded', function(event){
$(".property").hide();
$(".equipment").hide();
$(".machinery").hide();
});
});
$(function() {
$('.asset_type').on('change', function () {
var foo = $(this).closest(".fields");
$( "select option:selected").each(function(){
if($(this).attr("value")=="Property"){
$(foo).children(".Property").show();
$(foo).children(".Equipment").hide();
$(foo).children(".Machinery").hide();
}
if($(this).attr("value")=="Machinery"){
$(foo).children(".Property").hide();
$(foo).children(".Equipment").hide();
$(foo).children(".Machinery").show();
}
if($(this).attr("value")=="Equipment"){
$(foo).children(".Property").hide();
$(foo).children(".Equipment").show();
$(foo).children(".Machinery").hide();
}
});
}).change();
});
答案 1 :(得分:0)
当你致电$(.className).show()
时,它会显示或隐藏具有该类名的所有元素。也许你应该为你想要隐藏的元素生成一些id。像<div class="Machinery" id="Machine1">
这样的东西,那么你的JS可能是
if($(this).attr("value")=="Machinery"){
$("#Machine1").show();
$("#prop1").hide();
$("#equip1").hide();
}
答案 2 :(得分:0)
更改您的代码,如下所示。在更改中获取具有类“字段”的选择框的.parent() div。现在你有了元素的对象,它是所有这些'属性'的父对象,'设备','领域'里面的'机械'。在这里使用jquery .find()函数,您可以在特定的父元素中找到子元素。
您还要检查Event delegation以将事件附加到动态创建的元素。 Event delegation允许我们将单个事件侦听器附加到父元素,该元素将为匹配选择器的所有后代触发,无论这些后代现在是存在还是将来添加。
检查DEMO
$(function() {
$(document).on('change','.asset_type',function () {
var OBJ = $(this).parent('div.fields')
if($(this).val()=="Property"){
OBJ.find(".Property").show();
OBJ.find(".Equipment").hide();
OBJ.find(".Machinery").hide();
}
if($(this).val()=="Machinery"){
OBJ.find(".Machinery").show();
OBJ.find(".Property").hide();
OBJ.find(".Equipment").hide();
}
if($(this).val()=="Equipment"){
OBJ.find(".Property").hide();
OBJ.find(".Equipment").show();
OBJ.find(".Machinery").hide();
}
}).change();
});
答案 3 :(得分:0)
不确定我理解你的问题,但这就是我要做的事情:
假设您的场景需要根据用户交互动态创建N个对象,并稍后操纵这些对象/其属性。如果创建新表单实例的代码创建具有完全相同ID或类的html对象,或者您可能愿意使用任何css选择器来处理特定元素或对象,那么实际上,引用给定的html元素ID或类最终将以所有形式选择所有这些现有元素,因为它们的css选择器完全相同。因此,最简单的解决方案是让计数器在每次生成表单的新实例时递增。
在表单中命名包装div“fields”时必须使用此计数器。
考虑用户刚刚点击触发创建新表单的任何输入选项 - 假设这是用户第三次这样做,您最终会得到以下结果:
<div class="fields1">
<div class="fields2">
<div class="fields3">
在“更改”事件处理程序中,您需要动态确定选择器,使用计数器值引用相应的表单对象。
因此,如果您想引用“机械”输入字段,您可以解决
$(".fields" + counterValue + " .Machinery").val()