JS为多个表单动态显示/隐藏div

时间:2015-03-18 19:06:15

标签: javascript jquery

我有一个在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”时,它不应更改为每个显示的所有字段页面上的表格。

4 个答案:

答案 0 :(得分:1)

我对html稍作修改,这样你就可以知道你正在查看哪个输入字段。在asset_type选项的change函数内部,我得到最接近的字段div。我使用该引用来过滤您想要显示的div

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">
            # 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>

JQuery的

$(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()