views:

100

answers:

5

Hello,

Most examples I can find showing how to work with attributes show how to set them and not how to retrieve them. In my case, I am trying to get the class of an and then parse it to determine its parent value.

HTML:

<select class='parent' name='parent' size='10'>
    <option value='1'>Category 1 -></option>
    <option value='2'>Category 2 -></option>
</select>

<select class='child' id='child' size='10'>
    <option class='sub_1' value='5'>Custom Subcategory 1.1</option>
    <option class='sub_1' value='3'>Subcategory 1.1</option>
    <option class='sub_2' value='4'>Subcategory 2.1</option>
</select>

For any given option from the child list, I need to look at the class attribute, parse the name looking for the number (“sub_[n]”) and then grab the value of the option in the parent list.

My code so far (childVal has a value of “5” in my test case):

var class = child.find("option[value=" + childVal + "]").attr("class");

The above class variable is coming back “undefined.” I know the .find is working because I can use it for other things. The problem is getting at the class name.

Once I get the class name, I can strip out the “sub_” to get at the id number.

Is there a better way to do this? Why is .attr(“class”) returning undefined?

Here's a Fiddle link http://jsfiddle.net/n6dZp/8/ to a broken example.

Thank you,

Rick

This is the full function I am working on. It's a cascading select list.

<script type="text/javascript">
    function cascadeSelect(parent, child, childVal) {
        var childOptions = child.find('option:not(.static)');
        child.data('options', childOptions);

        parent.change(function () {
            childOptions.remove();
            child
                    .append(child.data('options').filter('.sub_' + this.value))
                    .change();
        })

        childOptions.not('.static, .sub_' + parent.val()).remove();

        if (childVal != '') {
            var className = child.find("option[value=" + childVal + "]").attr("class"); 

            ** need code here to select the parent and the child options based
            on childVal **
        }
    }

    $(function () {
        $('.categoryform').find('.child').change(function () {
            if ($(this).val() != null) {
                $('.categoryform').find('#CategoryId').val($(this).val());
            }
        });
    });

    $(function () {
        cascadeForm = $('.categoryform');
        parentSelect = cascadeForm.find('.parent');
        childSelect = cascadeForm.find('.child');

        cascadeSelect(parentSelect, childSelect, "5");
    });
</script>
+2  A: 

To obtain the class attribute:

var classAttribute =  $('#child').find('option[value="' + childVal + '"]:first').attr('class');

To obtain the 'n' value you can parse the class attribute with a RegEx:

var nValue = /\bsub_([\S]*)\b/.exec( classAttribute )[1];

Hope it helps you.

SDReyes
That seems rather over-coded -- what's wrong with `var nValue = classAttribute.replace('sub_','');`?
lonesomeday
@lonesomeday - That's still overcoded. I'd go with `var nValue = classAttribute.substr(4);`
Ender
@Ender A very good point!
lonesomeday
I still get "undefined" on your .find example. :(
rboarman
I updated my post to show the whole function. Thank you for taking the time to help.
rboarman
@lonesomeday: Hi lonesomeday, lets imagine we add more classes to the element. in this case this proposal is resilient -it's not going to break up unexpectedly- that's why I suggest RegEx :)
SDReyes
@SDReyes That's a reasonable point. I think you could argue this one either way...
lonesomeday
The .find is still returning undefined. :(
rboarman
@rboarman: I updated the code, please test it :)
SDReyes
No go. I updated the Fiddle example so you can see. http://jsfiddle.net/n6dZp/8/ When the page comes up, sub-category 2.1 should be selected on the right and category 2 on the left. I added an alert so you can see the results of the find. Keep in mind that I am trying to use child.find and not #child. Thanks for helping! This is driving me nuts.
rboarman
Update line 12: 'childOptions.not('.static, .sub_' + parent.val()).remove();' -> 'childOptions.find('.static, .sub_' + parent.val()).remove();'
SDReyes
you were removing all the elements of the collection before applying the selector :) -I understand you want to remove just the invalid elements-. hope it helps you.
SDReyes
I got it working by moving the "childOptions.not('.static, .sub_' + parent.val()).remove();" after the if test. Thanks for the help!
rboarman
You're welcome :)
SDReyes
+3  A: 

class is a reserved word in Javascript, so you can't have a variable with that name. Try

var className = child.find("option[value=" + childVal + "]").attr("class");
lonesomeday
Still returns undefined
rboarman
Are you sure you have defined `child` (presumably as `$('#child')` and `childVal`? I have run this code against the HTML you provide and it works as it should.
lonesomeday
I updated my post to show the whole function. Thank you for taking the time to help.
rboarman
A: 

For a start you are missing the $

You need:

var class = $(".child").find("option[value=" + childVal + "]").attr("class");
Liam Bailey
+3  A: 

Don't use class as a variable name. Kills IE.

This will work but what is child variable equal to?

methodin
"child" is the child select list as represented by the html in my post.
rboarman
+1  A: 

My apologies, I didn't read your question very carefully at first. Here's my take on what you should do:

var parentVal = $('.child option[value=' + childVal + ']').attr('class').substr(4);

OLD ANSWER

This should do the trick for you:

$(function() {
    $('#child').change(function() {  $('.parent').val($(this).children(':selected').attr('class').substr(4));
    });
});

Here's a live demo: http://jsfiddle.net/n6dZp/

Ender