show and hide elements based on data-* attribute
Asked Answered
M

4

6

This seems like it should be trivial for JQuery to do, but this function is hiding the whole form... can someone point me in the right direction?

$('form')
        .children()
        .filter(function(){
            return $(this).data('show', 'pro')
        })
        .show();
$('form')
         .children()
         .filter(function(){
             return $(this).data('show', 'home')
         })
         .hide();
Meda answered 27/1, 2012 at 16:20 Comment(0)
N
9

You're passing 2 arguments to the data method, thereby setting it instead of retrieving the old value.

Use this instead:

$('form')
        .children()
        .filter(function(){
            return $(this).data('show') === 'pro';
        })
        .show();
$('form')
         .children()
         .filter(function(){
             return $(this).data('show') === 'home';
         })
         .hide();

You could also cache your selector for performance (or use end).

Notate answered 27/1, 2012 at 16:22 Comment(2)
$.data() appears to be undefined inside my filter. Also, your code still appears to be hiding the whole form.Meda
Scratch my last comment... i just threw together a minimalist fiddle at it is working, so something else is going on here.Meda
V
9

If the data-show values are in your HTML or set as attributes on each object, you can do this entirely with a selector:

$('form > [data-show="pro"]').show();
$('form > [data-show="home"]').hide();

By way of explanation:

  • The form obviously selects form elements
  • The > selects a child of the form object
  • The [data-show="pro"] selects only the children that have an attribute named data-show that is set to the value of "pro"
  • The .show() calls the show method on those selected objects

If your data-show values are set with the .data() jquery method so the previous method would not work, then you may be better off setting state as a class name rather than a data value that you can more easily use in a selector. If these values were set as class names instead of data, the code would look like this:

$('form > .pro').show();
$('form > .home').hide();

Remember, you can have multiple class names on an object and object state that is directly used to control the presentation of the object (CSS styles, visibility, formatting, etc..) is much, much better to represent as class names rather than data-xxx attributes because it's much easier to use it in selectors for CSS or jQuery operations.

Virelay answered 27/1, 2012 at 16:33 Comment(2)
interesting... not all are direct descendants, though. Would I use $("form [data-show='foo']").show() ? This seems much more efficient.Meda
@ChrisSobolewski - yes, if you aren't looking only for direct descendants (which your original code was), then you can remove the > and it will include all descendants, not just direct children.Virelay
D
0

not quite sure what you're trying to do from code.

to access "data-" with JQ, i use:

$(elementSelector).attr('data-XXX');

where data-XXX is the attribute of the tag. This works in all browsers back to IE7 that i've seen.

Disinherit answered 27/1, 2012 at 16:22 Comment(2)
That'll only select by the data attributes that are in the source html code. It won't select by data added through jQuery's data method!Notate
According to their website, since 1.4 JQuery .data() will look at the data- attributes.Meda
K
0

if one works with multiple words like data-aliases="foo bar baz" and one of multiple word must match then use this selector [data-aliases~=foo], substitute foo with alias variable

var alias = 'foo'; // get alias somehow
$('.selector[data-aliases~="'+alias+'"]').show();
Kilowatthour answered 13/6, 2023 at 22:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.