css jQuery循环遍历表单,只检索可见输入的字段标签和值

busg9geu  于 2023-01-22  发布在  jQuery
关注(0)|答案(2)|浏览(159)

我有以下标记,其中有一个动态内容的holder 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的单个div
  • 每个div都有一个名为section的类,可以包含多个表单输入小部件,这些小部件位于一个div中,并具有一个data-type属性。

可以通过包含hidden类来切换具有类areasectiondata-type属性的div的可见性。
还可以通过包含一个值为agent或guest的data-access属性来限制每个div的可见性-这可以通过向#main div添加agent或guest类来实现。
因此,如果访客用户正在访问站点,带有#main的div将注入guest类,如果它是代理,则将注入agent类,然后使用以下CSS切换每个div的可见性。

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

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

我需要检索字段标签和所有表单输入的可见性没有隐藏的值,无论是通过隐藏类或数据访问属性,然后重新显示在另一个页面上,如摘要页。
因此,在上面的示例中,如果#main div的类为agent,则仅向用户显示性别和学校字段,因此函数将检索这些字段的字段标签和值,这是因为全名小部件和出生日期区域均被隐藏
如果#main div的class为guest,那么只有gender字段会显示,因为全名小部件是隐藏的,出生日期区域是隐藏的,学校部分div只有agent的数据访问权限。
因此,简而言之,我需要检查三个具有class area、section或data-type attr的div,看看它们是否隐藏,我还必须检查相同的div,看看它们是否包含数据访问属性,并确保可见性没有被隐藏。
因此,实际上,如果area div具有与<div id="main" class="agent">中的类不匹配的隐藏类或数据访问属性值,则无需进一步遍历,因为输入字段将被隐藏
类似地,带有section类的div以及最后带有数据类型attr的div也是如此。
如何循环遍历这样的标记,以仅提取那些已显示的表单元素的字段标签和值?
这是我目前掌握的情况:

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 

      });
 }

更新

holder div可以出现在<div class="page"> div中的多个页面上,当用户浏览表单时,前面页面的可见性会被隐藏。因此,简单地使用jQuery的:visible伪类将无法工作,因为前面页面上的项目将被隐藏,但仍需要在摘要页面上显示,因为它们将被显示给用户。

s71maibg

s71maibg1#

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

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
        });
    });
});
mspsb9vt

mspsb9vt2#

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>

相关问题