Skip Navigation

[Resolved] Filter: Label field missing “for”

The Toolset Community Forum is closed, for technical support questions, please head on to our Toolset Professional Support (for paid clients), with any pre-sale or admin question please contact us here.

This thread is resolved. Here is a description of the problem and solution.

Problem: I would like to replace the standard checkboxes in my View filter with images. In order to do this, I need to apply a class to the checkbox's parent label that determines whether or not to show the checkmark in the checkbox. I am using AJAX to update my View results whenever an input is changed.

Solution:
Use some jQuery to modify the parent element whenever a checkbox is changed. Run the same jQuery when the page loads to ensure the checkboxes are set correctly before anything changes. Use the front-end events feature to listen for search results updates.

Relevant Documentation:
https://toolset.com/documentation/user-guides/front-page-filters/advanced-settings-custom-search/

This support ticket is created 7 years, 8 months ago. There's a good chance that you are reading advice that it now obsolete.
This is the community support forum for Types plugin, which is part of Toolset. Toolset is a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients and people who registered for Types community support can post in it.

Sun Mon Tue Wed Thu Fri Sat
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

This topic contains 19 replies, has 2 voices.

Last updated by Sammut 7 years, 7 months ago.

Assisted by: Christian Cox.

Author
Posts
#507810

I have added a filter to a view page. In adding some CSS to the filter I noticed that the labels are missing an accessibility reference "for ='' " to tie them to their requisite input field. Is there any way to add this in? The goal here is i am switching out checkboxes for graphics and in order to mark the "checked" state, the "for" is needed. Other suggestions are welcomed as well.

My CSS is :

label.selectit > input[type=checkbox].js-wpv-filter-trigger:checked {background-position: 0 -50px;}

E.g.,

<li id="category-1408">
<label class="selectit">
<input value="practitioners" type="checkbox" class="js-wpv-filter-trigger" name="wpvcategory[]" id="in-category-1408" checked="checked">
 A Practitioner of Yoga
</label>
</li>

Thank you!

#507988

Hi, we don't currently offer a way to set the "for" attribute for each label with PHP, but you could implement a bit of JavaScript to handle this. I just tested this with a few checkboxes and it works, but you should do a thorough test with any form inputs just in case.

jQuery(document).ready(function(){
  jQuery('.js-wpv-filter-form-567-TCPID568 .selectit').each(function(index, el) {
     $el = jQuery(el);
     $el.attr('for', $el.find('input').first().attr('id'));
  });
});

Swap out the unique class for your form instead of 567-TCPID568, and this should set up the appropriate "for" attribute. Make sure this executes before you do any fancy DOM replacement for your checkboxes, and you should be good to go.

#508031

Thank you. OK. I understand the approach.

The page is located here: hidden link
PW: a-test

I added the script via function to load it atop the page:

function mytheme_custom_scripts(){
 wp_register_script( 'courses-filter', get_stylesheet_directory_uri() . '/custom-js/courses-filter.js', array('jquery'));
    wp_enqueue_script( 'courses-filter' );
}

The script I have as follows:

jQuery(document).ready(function(){
  jQuery('.js-wpv-filter-form-25923-TCPID17031 .selectit').each(function(index, el) {
     $el = jQuery(el);
     $el.attr('for', $el.find('input').first().attr('id'));
  });
});

However, the checked function still does not work, so I figure I did something wrong somewhere.

Thank you for your help!

As a side note, the associated CSS is:

input[type=checkbox].js-wpv-filter-trigger {
							position:absolute; z-index:-1000; left:-1000px; overflow: hidden; clip: rect(0 0 0 0); height:1px; width:1px; margin:-1px; padding:0; border:0;
						}
						
						label.selectit,
						input[type=checkbox].js-wpv-filter-trigger + label.selectit {
							padding-left:55px;
							height:50px; 
							display:inline-block;
							line-height:50px;
							background-repeat:no-repeat;
							background-position: 0 0;
							font-size:50px;
							vertical-align:middle;
							cursor:pointer;

						}
					label.selectit:hover,
					/*label.selectit + input[type=checkbox].js-wpv-filter-trigger:checked,*/
					label.selectit > input[type=checkbox].js-wpv-filter-trigger:checked {
							background-position: 0 -50px;
						}

						label.selectit {
				background-image:url(/wp-content/uploads/css_ck_box1.png);
				-webkit-touch-callout: none;
				-webkit-user-select: none;
				-khtml-user-select: none;
				-moz-user-select: none;
				-ms-user-select: none;
				user-select: none;
			}

THANK YOU!

#508640

Hi, it appears the page is protected behind a login. Would you mind sharing access with me? I can enable a private reply here to keep your details out of public access.

#508672

However, the checked function still does not work, so I figure I did something wrong somewhere.

Hi, can you share this function? Where can I find it, is it in another js file, or embedded on the page somewhere? It appears the "for" attributes are added as expected, so there's probably just a timing issue.

#508704

Thank you, yes, sure.

In the function file of the theme I have:

function mytheme_custom_scripts(){
    wp_register_script( 'courses-filter', get_stylesheet_directory_uri() . '/custom-js/courses-filter.js', array('jquery'));
    wp_enqueue_script( 'courses-filter' );
}
add_action('wp_enqueue_scripts', 'mytheme_custom_scripts');

Inside that.js file is:

jQuery(document).ready(function(){
  jQuery('.js-wpv-filter-form-25923-TCPID17031 .selectit').each(function(index, el) {
     $el = jQuery(el);
     $el.attr('for', $el.find('input').first().attr('id'));
  });
});

The JS files is being pishedout on line 114:
<script type='text/javascript' src='hidden link;

THANK YOU!!

#508709

Hi, I'm a bit confused. You said:
However, the checked function still does not work, so I figure I did something wrong somewhere.

The code I provided, which you implemented:

$el.attr('for', $el.find('input').first().attr('id'));

This code does not cause anything to become "checked", it only adds the "for" attribute to the parent label element. So if you're expecting something to become "checked" this code won't do that. Can you elaborate on what should be "checked", and how you expect to set it "checked"?

#508712

Right, yes, my apologies. Within the CSS of this particular view's filter, I have:

input[type=checkbox].js-wpv-filter-trigger {
							position:absolute; z-index:-1000; left:-1000px; overflow: hidden; clip: rect(0 0 0 0); height:1px; width:1px; margin:-1px; padding:0; border:0;
						}
						
						label.selectit,
						input[type=checkbox].js-wpv-filter-trigger + label.selectit {
							padding-left:55px;
							height:50px; 
							display:inline-block;
							line-height:50px;
							background-repeat:no-repeat;
							background-position: 0 0;
							font-size:50px;
							vertical-align:middle;
							cursor:pointer;

						}
					label.selectit:hover,
					label.selectit > input[type=checkbox].js-wpv-filter-trigger:checked {
							background-position: 0 -50px;
						}

				label.selectit {
				background-image:url(/wp-content/uploads/css_ck_box1.png);
				-webkit-touch-callout: none;
				-webkit-user-select: none;
				-khtml-user-select: none;
				-moz-user-select: none;
				-ms-user-select: none;
				user-select: none;
			}

With the expectation that this:

					label.selectit:hover,
					label.selectit > input[type=checkbox].js-wpv-filter-trigger:checked {
							background-position: 0 -50px;
						}

would do the trick to keep the graphic highlighted when checked.

THANK YOU!

#508714

There's no such thing as a parent selector in CSS, but it appears that is what you need. Look at this code:

label.selectit > input[type=checkbox].js-wpv-filter-trigger:checked {
        background-position: 0 -50px;
    }

You are applying the "background-position" style to the <input> tag, instead of the label where it should be applied. That's why your checkmarks are not showing up as expected. If you would like to apply a class to the parent element when you also set the "for" attribute, that might do that trick. Then you could modify this CSS to target 'label.selectit.checked'. Make sense?

#508957

Thank you! I will need to take a closer look. It makes "kinda" sense.

The above CSS works fine on mobile and tablet but fails on desktop.

#509033

Ok I'll stand by for your results. If you need help, I'll be glad to assist. It's strange that it works on mobile but not desktop - be sure to clear your cache on the mobile device.

#509094

Thank you so very much! I must admit, I am at a loss as my typical approach seems to not be working. Any advice or further direction is very much appreciated!!! THANK YOU!

#509138
Screen Shot 2017-04-03 at 5.32.17 PM.png

Okay let's make some changes. Here is the code I want you to use in courses-filter.js:

jQuery(document).ready(function(){
  jQuery('.js-wpv-filter-form-25923-TCPID17031 .selectit').each(function(index, el) {
    // set the label classes on page load based on the input checked status
    $el = jQuery(el);
    $el.attr('for', $el.find('input').first().attr('id'));
    var isChecked = $el.find('input[type="checkbox"]').first().attr('checked') != undefined;
    $el.toggleClass('checked', isChecked); 
  });
  jQuery(document).on('change', '.js-wpv-filter-form-25923-TCPID17031 .selectit input[type="checkbox"]', function(e) {
    // set the label classes any time a checkbox is checked
    $el = jQuery(e.target);
    var isChecked = $el.find('input[type="checkbox"]').first().attr('checked') != undefined;
    $el.closest('.selectit').toggleClass('checked', isChecked);
  });
});

Then, in your View editor, look for the section "Filter Editor" and open JS panel. Click the button "Front-end events" and choose the event when the AJAX results are complete. A template will be generated for you. Then inside the template, paste the following code:

// set the label classes based on the input checked status after results update
jQuery('.js-wpv-filter-form-25923-TCPID17031 .selectit').each(function(index, el) {
    $el = jQuery(el);
    $el.attr('for', $el.find('input').first().attr('id'));
    var isChecked = $el.find('input[type="checkbox"]').first().attr('checked') != undefined;
    $el.toggleClass('checked', isChecked); 
  });

Screenshot attached.

Finally, add the class definition to your CSS:

label.selectit.checked {
  background-position: 0 -50px;
}

Let me know how it goes!

#509340

Thank you! It is integrated but the checkbox is not staying checked. However, I did notice that if you click a checkbox and then do a full page refresh it does stay checked.

For instance, if you go to this page hidden link you will see the checkbox is checked. However, if you click another filter the checkbox disappears. It appears the code works on full page refresh?

Thank you again for help and guidance!

#509823

Sorry for the inconvenience. Please update your courses-filter.js :

jQuery(document).ready(function(){
  jQuery('.js-wpv-filter-form-25923-TCPID17031 .selectit').each(function(index, el) {
    // set the label classes on page load based on the input checked status
    $el = jQuery(el);
    $el.attr('for', $el.find('input').first().attr('id'));
    var isChecked = $el.find('input[type="checkbox"]').first().attr('checked') != undefined;
    $el.toggleClass('checked', isChecked); 
  });
  jQuery(document).on('change', '.js-wpv-filter-form-25923-TCPID17031 .selectit input[type="checkbox"]', function(e) {
    // set the label classes any time a checkbox is checked
    $el = jQuery(e.target);
    var isChecked = $el.attr('checked') != undefined;
    $el.closest('.selectit').toggleClass('checked', isChecked);
  });
});

Then in your Filter Editor JS panel, update the code:

jQuery( document ).on( 'js_event_wpv_parametric_search_results_updated', function( event, data ) {
jQuery('.js-wpv-filter-form-25923-TCPID17031 .selectit').each(function(index, el) {
    // set the label classes on page load based on the input checked status
    $el = jQuery(el);
    $el.attr('for', $el.find('input').first().attr('id'));
    var isChecked = $el.find('input[type="checkbox"]').first().attr('checked') != undefined;
    $el.toggleClass('checked', isChecked); 
  });});

Please let me know the results.

The forum ‘Types Community Support’ is closed to new topics and replies.