jQuery 遍历表单并仅检索可见输入的字段标签和值 [英] jQuery loop through form and retrieve field labels and values of visible inputs only

查看:27
本文介绍了jQuery 遍历表单并仅检索可见输入的字段标签和值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下标记,其中我有一个用于动态内容的 holder div

.

<div class="page"><div data-name="holder"><div class="child"><div class="area"><div class="box"><div class="section"><div 数据类型=文本"class="widget_type_text hidden";><div><label for="child0name">全名</label>

<div><div class="validationMessage">输入名字

<div data-type="radio";class =widget_type_radio"><div><字段集><legend>性别</legend><span data-value=male"><input id=child0genderMale"类型=收音机"名称=孩子[0][性别]"value=male"><label for=child0genderMale">Male</label></span><span data-value=female"><input id=child0genderFemale"类型=收音机"名称=孩子[0][性别]"value=female"></fieldset>

<div class="隐藏区域"><div class="box"><div class="section"><div 数据类型=日期"class =widget_type_date"><div><label for="child0dob">出生日期</label>

<div><div class="validationMessage">输入出生日期

<input id="child0dob";类型=日期"名称=孩子[0][dob]";必需="title=输入出生日期">

<div 类=区域"><div class="box"><div class="section"数据访问=代理"><div 数据类型=文本"class="widget_type_text"><div><label for="child0school">School</label>

<div><div class="validationMessage">进入学校

<input id="child0school";类型=文本"名称=孩子[0][学校]";必需="title=进入学校">

具有 areasectiondata-type 属性的 div 的可见性可以通过包含 hidden类.

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

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

#main.guest [data-access="agent"] {显示:无;}#main.agent [数据访问=客人"] {显示:无;}

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

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

如果#main div 有guest 类,那么只会显示性别字段,因为隐藏了全名小部件,出生日期区域是隐藏的,学校部分div只有代理的数据访问权限.

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

因此,如果区域 div 具有与

无需再深入遍历,因为输入字段将被隐藏

类似的情况是带有节类的 div,最后是带有数据类型 attr 的 div.

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

这是我目前所拥有的:

 if ($("[data-name='holder']").children().length > 0 ) {$('.child').each(function(index, element) {//伪代码对于每个带有类区域的 div如果 div 没有隐藏类或者如果 div 具有数据访问属性并且 $( "#main" ) 具有具有相同值的类,则如果带有类部分的 div 没有隐藏类,或者如果 div 具有数据访问属性并且 $( "#main") 具有具有相同值的类,则对于每个具有数据类型属性的 div如果 div 没有隐藏类,或者如果 div 具有数据访问属性并且 $( "#main" ) 具有具有相同值的类,则将字段标签和字段值保存在数组中万一结束于万一万一结束});}

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

*** 更新 ***

holder div 可以出现在 <div class="page"> div 内的多个页面上,并且当用户逐步浏览表单时,之前的页面可见性被隐藏.所以简单地使用jQuery 的 :visible 伪类将不起作用,因为之前页面上的项目将被隐藏,但仍需要在摘要页面上呈现,因为它们将呈现给用户.

解决方案

如果类(例如:agent、guest)是固定的,并且你知道所有可能的组合,你可以像这样进行选择

var $main = $('#main');//过滤掉所有不在 main 中的类var aClasses = ['agent', 'guest'].filter(function(cl) {返回 !$main.hasClass(cl)});//构建选择器var 选择器 = ':not(.hidden)';aClasses.forEach(function(cl) {选择器 += ':not([data-access="' + cl + '"])'})$('div.area' + 选择器).each(function(i, el) {$('div.section' + 选择器, el).each(function(_i, _el) {$('div[data-type]' + selector, _el).each(function(__i, __el) {//你在可见的 'div[data-type]' 里面;做你的事});});});

或者,一举完成:

$('div.area' + 选择器+ 'div.section' + 选择器+ 'div[数据类型]' + 选择器).each(函数(i, el) {//你的东西}

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

var $main = $('#main');//获取主div的类var sClass = (['agent', 'guest'].filter(function(cl) {返回 $main.hasClass(cl)})[0];//使两个选择器组合var s1 = ':not(.hidden):not([数据访问])';s2 = '[数据访问 =''+ 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) {//你的东西});});});

但是在这里,要一口气写下所有内容,您必须使用 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[数据类型]' + s1+ ',div.area' + s1 + 'div.section' + s1 + 'div[数据类型]' + s2+ ',div.area' + s1 + 'div.section' + s2 + 'div[数据类型]' + s1+ ',div.area' + s1 + 'div.section' + s2 + 'div[数据类型]' + s2+ ',div.area' + s2 + 'div.section' + s1 + 'div[数据类型]' + s1+ ',div.area' + s2 + 'div.section' + s1 + 'div[数据类型]' + s2+ ',div.area' + s2 + 'div.section' + s2 + 'div[数据类型]' + s1+ ',div.area' + s2 + 'div.section' + s2 + 'div[数据类型]' + s2).each(function(i, el) {//你的东西})

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

示例

//假设类是 (agent, guest) 并且主 div 有类 'agent' 然后/* 第一次接近 */$('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) {//你的东西})//使用嵌套循环$('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) {//你在可见的 'div[data-type]' 里面;做你的事});});});/* 第二个方法 */$('div.area:not(.hidden):not([data-access]) div.section:not(.hidden):not([data-access]) div[data-type]:not(.hidden):不([数据访问]),'+ 'div.area:not(.hidden):not([data-access]) div.section:not(.hidden):not([data-access]) div[data-type][data-access="代理"]:不(.隐藏),'+ ...).each(function(i, el) {//你的东西})//使用嵌套循环$('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) {//你的东西});});});

I have the following markup where I have a holder div <div data-name="holder"></div> for dynamic content.

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

  • The holder can have multiple child divs which has a class called child conveniently.
  • Each child div can contain multiple divs with a class called area.
  • Each div with a class called area can contain a single div with a class called section
  • Each div with a class called section can contain multiple form input widgets that sit inside a div with a data-type attribute.

visibility of a div with class area, section or data-type attribute can be toggled by including a hidden class.

visibility of each of these divs can also be restricted by including a data-access attribute with a value of either agent or guest - this works by adding either agent or guest class to the #main div.

So if a guest user is accessing the site, div with #main will have the guest class injected and if its an agent it will have a agent class and then the following CSS is used to toggle visibility of each div.

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

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

I need to retrieve the field labels and values for all form inputs whose visibility is not hidden, either by the hidden class or the data-access attributes and then re-display them on another page eg. summary page.

So in the above example if the #main div has class of agent then only the gender and school fields have been displayed to user so function would retrieve the field label and value of those fields only because the full name widget is hidden and the date of birth area is hidden

If the #main div had class of guest then only the gender field would have been displayed because the full name widget is hidden, the date of birth area is hidden and school section div has data-access of agent only.

So in short I need to check three divs which have either class area, section or data-type attr to see if they are not hidden. I also have to check the same divs to see if they contain a data-access attribute and ensure visibility has not been hidden by that.

so really if the area div has either a hidden class or data-access attribute value that does not match the class in <div id="main" class="agent"> there is no need to traverse any deeper as the input field will have been hidden

similarly would be the case with the div with section class and finally the div with data-type attr.

How do I loop through such markup to pull out field labels and values of only those form element that have been displayed?

This is what I have so far:

 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 

      });
 }

Struggling to transform the pseudo code into jQuery. any help appreciated.

*** UPDATE ***

The holder div can appear on multiple pages inside <div class="page"> div and as user steps through the form, the previous pages visibility is hidden. So simply using jQuery's :visible pseudo class wont work as items on previous pages will be hidden but still need to be presented on summary page as they will have been presented to user.

解决方案

If the classes (eg: agent, guest) are fixed and you know what are all the possible combination you can do the selecting like this

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

or, do it in one big swoop like:

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

Or if you really wan't to do the selecting based on the main div having a class (eg: agent, guest) and checking the exact same, you could try

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

but here, to write everything in one big swoop, you would have to use 8 different combination

eg:

// 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
})

so it would be best to use the nested loop itself.

Example

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

这篇关于jQuery 遍历表单并仅检索可见输入的字段标签和值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆