【问题标题】:jQuery loop through form and retrieve field labels and values of visible inputs onlyjQuery 循环遍历表单并仅检索可见输入的字段标签和值
【发布时间】:2021-03-10 14:11:33
【问题描述】:

我有以下标记,其中我有一个 div <div data-name="holder"></div> 用于动态内容。

<div id="main" class="agent">
  <div class="page">
  <div data-name="holder">

    <div class="child">
        <div class="area" >
           <div class="box">
              <div  class="section" >
                 <div data-type="text" class="widget_type_text hidden" >
                     <div>
                         <label for="child0name">Full name</label>
                     </div>
                     <div>
                        <div class="validationMessage">
                           Enter Name
                        </div>
                         <input id="child0name" type="text" name="child[0][name]" required="" title="Enter full name">
                     </div>
                 </div>
                 <div data-type="radio" class="widget_type_radio" >
                     <div>
                        <fieldset>
                            <legend>Gender</legend>
                            <span data-value="male"><input id="child0genderMale" type="radio" name="child[0][gender]" value="male"><label for="child0genderMale">Male</label></span>
                            <span data-value="female"><input id="child0genderFemale" type="radio" name="child[0][gender]" value="female"><label for="child0genderFemale">Female</label></span>
                        </fieldset>
                     </div>
                 </div>
             </div>
          </div>
        </div>
        <div class="area hidden">
          <div class="box">
             <div class="section">
                <div data-type="date" class="widget_type_date">
                    <div>
                       <label for="child0dob">Date of Birth</label>
                    </div>
                    <div>
                       <div class="validationMessage">
                           Enter Date of Birth
                       </div>
                       <input id="child0dob" type="date" name="child[0][dob]" required="" title="Enter date of Birth">
                    </div>
                </div>
             </div>
          </div>
        </div>
        <div class="area ">
          <div class="box">
             <div class="section" data-access="agent">
                <div data-type="text" class="widget_type_text">
                    <div>
                       <label for="child0school">School</label>
                    </div>
                    <div>
                       <div class="validationMessage">
                           Enter School
                       </div>
                       <input id="child0school" type="text" name="child[0][school]" required="" title="Enter school">
                    </div>
                </div>
             </div>
          </div>
        </div>
     </div>

  </div>
 </div>
</div>
  • 持有者可以有多个子 div,其中有一个名为 child 方便。
  • 每个子 div 可以包含多个 div,其类名为 area
  • 每个带有area 类的 div 可以包含一个带有 类名为section
  • 每个带有section类的div可以包含多个表单 位于具有数据类型属性的 div 内的输入小部件。

可以通过包含hidden 类来切换具有areasectiondata-type 属性的div 的可见性。

每个 div 的可见性也可以通过包含一个值为 agent 或 guest 的 data-access 属性来限制 - 这个 通过将代理或访客类添加到#main div 来工作。

因此,如果访客用户正在访问该站点,带有#main 的 div 将注入​​ guest 类,如果它是代理,它将具有 agent 类,然后使用以下 CSS 来切换每个的可见性分区。

#main.guest [data-access="agent"] {
    display: none;
}

#main.agent [data-access="guest"] {
    display: none;
}

我需要通过隐藏类或数据访问检索所有可见性未隐藏的表单输入的字段标签和值 属性,然后在另一个页面上重新显示它们,例如。摘要页。

所以在上面的例子中,如果#main div 有代理类,那么只有性别和学校字段会显示给用户,所以函数会 仅因为隐藏了全名小部件并且隐藏了出生日期区域,才检索这些字段的字段标签和值

如果#main div 有guest 类,则只会显示性别字段,因为全名小部件已隐藏, 出生日期区域是隐藏的,学校部门 div 只能访问代理的数据。

所以简而言之,我需要检查三个具有类区域、部分或数据类型 attr 的 div 以查看它们是否未隐藏。我还必须检查相同的 div 以查看它们是否包含数据访问属性并确保没有可见性 被它隐藏了。

如果区域 div 具有与 &lt;div id="main" class="agent"&gt; 中的类不匹配的隐藏类或数据访问属性值,则无需更深入地遍历,因为输入字段将被隐藏

类似的情况是 div 具有 section 类,最后是 div 具有数据类型 attr。

如何循环遍历此类标记以仅提取那些已显示的表单元素的字段标签和值?

这是我目前所拥有的:

 if ($("[data-name='holder']").children().length > 0 ) {
 
      $('.child').each(function(index, element) {

          //pseudo code
          for each div with class area 
             if div does not have class hidden or if div has data-access attribute and $( "#main" ) has class with same value then
                   if div with class section does not have class hidden or if div has data-access attribute and $( "#main" ) has class with same value then
                         for each div with data-type attribute 
                              if div does not have class hidden or if div has data-access attribute and $( "#main" ) has class with same value then
                                   save the field label and field value in array
                              end if

                         end for 
                   end if

             end if

          endfor 

      });
 }

努力将伪代码转换为 jQuery。任何帮助表示赞赏。

*** 更新 ***

持有人 div 可以出现在 &lt;div class="page"&gt; div 内的多个页面上,并且当用户逐步浏览表单时,先前页面的可见性被隐藏。所以简单地使用 jQuery 的 :visible 伪类无法工作,因为以前页面上的项目将被隐藏,但仍需要在摘要页面上显示,因为它们已呈现给用户。

【问题讨论】:

    标签: javascript html jquery css


    【解决方案1】:

    如果类(例如:代理、访客)是固定的,并且您知道所有可能的组合是什么,您可以像这样进行选择

    var $main = $('#main');
        
    // filter all the class that are not in the main
    var aClasses = ['agent', 'guest'].filter(function(cl) {
        return !$main.hasClass(cl)
    });
    
    // build the selector
    var selector = ':not(.hidden)';
    aClasses.forEach(function(cl) {
        selector += ':not([data-access="' + cl + '"])'
    })
    
    $('div.area' + selector).each(function(i, el) {
        $('div.section' + selector, el).each(function(_i, _el) {
            $('div[data-type]' + selector, _el).each(function(__i, __el) {
                // you are inside the visible 'div[data-type]' here; do your stuff
            });
        });
    });
    

    或者,像这样一举完成:

    $(
        'div.area' + selector 
        + ' div.section' + selector 
        + ' div[data-type]' + selector
    ).each( function(i, el) {
        // your stuff
    }
    

    或者,如果您真的不想根据具有类(例如:代理、访客)的主 div 进行选择并检查完全相同,您可以尝试

    var $main = $('#main');
        
    // get the main div's class
    var sClass = (['agent', 'guest'].filter(function(cl) {
        return $main.hasClass(cl)
    })[0];
    
    // make the two selector combination
    var s1 = ':not(.hidden):not([data-access])';
        s2 = '[data-access="' + sClass + '"]:not(.hidden)';
        
    $('div.area' + s1 + ',div.area' + s2).each(function(i, el) {
        $('div.section' + s1 + ',div.section' + s2, el).each(function(_i, _el) {
            $('div[data-type]' + s1 + ',div[data-type]' + s2, el).each(function(__i, __el) {
                // your stuff
            });
        });
    });
    

    但在这里,要一口气写完所有内容,您必须使用 8 种不同的组合

    例如:

    // area-s1 sect-s1 div-s1, 
    // area-s1 sect-s1 div-s2, 
    // area-s1 sect-s2 div-s1,
    // area-s1 sect-s2 div-s2,
    // area-s2 sect-s1 div-s1,
    // area-s2 sect-s1 div-s2, 
    // area-s2 sect-s2 div-s1,
    // area-s2 sect-s2 div-s2,
    
    // ie:
    
    $(
        'div.area' + s1 + ' div.section' + s1 + ' div[data-type]' + s1
        + ',div.area' + s1 + ' div.section' + s1 + ' div[data-type]' + s2
        + ',div.area' + s1 + ' div.section' + s2 + ' div[data-type]' + s1
        + ',div.area' + s1 + ' div.section' + s2 + ' div[data-type]' + s2
        + ',div.area' + s2 + ' div.section' + s1 + ' div[data-type]' + s1
        + ',div.area' + s2 + ' div.section' + s1 + ' div[data-type]' + s2
        + ',div.area' + s2 + ' div.section' + s2 + ' div[data-type]' + s1
        + ',div.area' + s2 + ' div.section' + s2 + ' div[data-type]' + s2
    ).each(function(i, el) {
        // your stuff
    })
    

    所以最好使用嵌套循环本身。

    示例

    // assume the classes are (agent, guest) and main div is having class 'agent' then
    
    /* First approch */
    $('div.area:not(.hidden):not([data-access="guest"] div.section:not(.hidden):not([data-access="guest"] div[data-type]:not(.hidden):not([data-access="guest"]').each(function(index, elem) {
        //your stuff
    })
    
    // using nested loops
    $('div.area:not(.hidden):not([data-access="guest"]').each(function(i, el) {
        $('div.section:not(.hidden):not([data-access="guest"'], el).each(function(_i, _el) {
            $('div[data-type]:not(.hidden):not([data-access="guest"'], _el).each(function(__i, __el) {
                // you are inside the visible 'div[data-type]' here; do your stuff
            });
        });
    });
    
    
    /* Second approch */
    $(
        'div.area:not(.hidden):not([data-access]) div.section:not(.hidden):not([data-access]) div[data-type]:not(.hidden):not([data-access]), '
        + 'div.area:not(.hidden):not([data-access]) div.section:not(.hidden):not([data-access]) div[data-type][data-access="agent"]:not(.hidden), '
        + ...
    ).each(function(i, el) {
        //your stuff
    })
    
    // using nested loops
    $('div.area:not(.hidden):not([data-access]), div.area[data-access="agent"]:not(.hidden)').each(function(i, el) {
        $('div.section:not(.hidden):not([data-access]), div.section[data-access="agent"]:not(.hidden)', el).each(function(_i, _el) {
            $('div[data-type]:not(.hidden):not([data-access]), div[data-type][data-access="agent"]:not(.hidden)', _el).each(function(__i, __el) {
                // your stuff
            });
        });
    });
    

    【讨论】:

    • 你有没有使用 ES6 的例子,因为我的 jquery 非常基础。?
    • @adam78 还添加了示例。
    • 以下是否意味着它和条件$('div.area:not(.hidden):not([data-access="guest"] 即区域未隐藏且数据访问不是访客?您如何使其成为 OR 条件,即区域未隐藏或数据访问不是访客?
    • 使用逗号。见第二种方法。例如:$('div.area:not(.hidden), div.area:not([data-access="guest"])
    • 第二种方法有效,但我遇到了另一个问题,如果我有其他 &lt;div class="area"&gt;&lt;div class="section"&gt;&lt;div data-type="text"&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; 嵌套在父部分 div 中怎么办。我注意到在这种情况下,第二种方法重复了结果,即它多次循环同一个 div?
    【解决方案2】:

    jQuery 的:visible 伪类将只过滤用户可见的[data-type] 元素。

    因此,根据您的描述在选择器上使用它就足够了:

    <script>
    $(function () {
        function fetchFormData() {
            var result = [];
    
            $('[data-name=holder] [data-type]:visible').each(function (idx, elem) {
                var $elem = $(elem);
                var type = $elem.data('type');
                var label, value;
    
                // specific case: radio input
                if (type === 'radio') {
                    label = $elem.find('legend').text();
                    value = $elem.find('input[type=radio]:checked').val();
    
                    result.push({label: label, value: value});
    
                    // done with this item, skip to next one
                    return true; // continue;
                }
    
                // generic case, works with most inputs
                label = $elem.find('label').text();
                value = $elem.find('input').val();
    
                result.push({label: label, value: value});
            });
    
            return result;
        }
    
    
        // add this to an event handler
        console.log(fetchFormData());
    });
    </script>
    

    【讨论】:

    • 这行不通。请参阅我更新的帖子,因为持有者 div 包含在页面 div 中,其可见性通过表单隐藏为用户页面。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多