Peanut
Peanut

Reputation: 3295

jQuery closest() not grabbing element

Ok the .closest() function is not grabbing the element correctly or AT ALL so the class is not being added to the div. What's wrong here?

HTML:

<div class="half control-group">
        <div class="form-status"></div>
        <?php
        echo form_label('Username', 'username');
        echo form_input(array('name' => 'username', 'maxlength' => 25, 'value' => set_value('username') ));
        ?>
    </div>

JQuery:

success: function(label) {
    $(label).text('');
    $(label).closest('div[class="form-status"]').addClass('success');
    //label.text('OK!').addClass('valid').closest('.control-group').addClass('success');
}

It's making the text go to blank correctly, but it's not changing the closest form-status div class... i even tried closest('.form-status') and it still won't grab it. I'm using the validate jQuery plugin. When you start typing it adds this HTML underneath the input bars:

<label for=​"name" generated=​"true" class=​"error valid" style>​​</label>​

FOR ANYONE LOOKING FOR THE CORRECT ANSWER, THIS WORKED:

label.closest('.control-group').find('div.form-status').addClass('success');

Upvotes: 0

Views: 641

Answers (3)

Ruan Mendes
Ruan Mendes

Reputation: 92274

Half the problem has been explained, you should use $.prev() because $.closest() doesn't look at siblings.

However, the second part of the problem lies here

// What type is label? Is it a string indicating what's in the 
// for="name"? Is it a jQuery object? a DOM object
success: function(label) {
    $(label).text('');
    $(label).closest('div[class="form-status"]').addClass('success');
    //label.text('OK!').addClass('valid').closest('.control-group').addClass('success');
}

If it's being passed a jQuery or HTMLElement object, the following would work http://jsfiddle.net/Rdpu7/1/

success: function(label) {
    $(label).prev('div.form-status').addClass('success');
    $(label).text('OK!').addClass('valid').closest('.control-group').addClass('success');        
}

If it's being passed the name that was passed into form_label, you can use the following http://jsfiddle.net/Rdpu7/3/

success: function(label) {
    var label = $("label[for='"+label+"']");
    label.prev('div.form-status').addClass('success');
    label.text('OK!').addClass('valid').closest('.control-group').addClass('success');  
}

If it's something else, you should improve your documentation, I particularly can't stand function where the parameters aren't documented, and I'm sure it's the reason for your confusion.

With regards to why the following line worked

$('label').prev('div.form-status').addClass('success')

That will do all the labels on your page, which is not likely what you want. It only works for the example with a single label. Your main problem is that you don't know what type of object label is in your success function

Upvotes: 0

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382150

closest only goes up the dom tree, it doesn't select siblings.

You need

$(label).prev('div.form-status').addClass('success');

or

$('.half.control-group label').prev('div.form-status').addClass('success');

depending of if the label var you get is a jQuery selector or not.

Note that as I commented before, there is a direct selector for classes both in jQuery and CSS so you should prefer 'div.form-status' over 'div[class="form-status"]'.

Upvotes: 3

Jai
Jai

Reputation: 74738

I have tested this one and working quite well:

$('label').text(''); 
$('label').prev('div[class="form-status"]').addClass('success');
// ---------^---------use this if you want to add class to just previous div at 
//--------------------same level

use this if you want to add class to all divs at same level

$('label').siblings('div[class="form-status"]').addClass('success');

Upvotes: 0

Related Questions