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
childconveniently. - Each child div can contain multiple divs with a class called
area. - Each div with a class called
areacan contain a single div with a class calledsection - Each div with a class called
sectioncan 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
});
}
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 won't 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.