1

I've created a Custom Admin page on wordpress back-end, and have this basic html structure,

<ul data-status="available">
    <li class="available">AVAILABLE</li>
    <li class="onleave">ONLEAVE</li>
</ul>

When I use js code below, it works fine

$('ul').each( function() {
    var status = 'available';
    $(this).find('li.' + status ).addClass('active');
});

While this code below also works (it adds class on element), However it, produces an error

$('ul').each( function() {
    var status = $(this).data('status');
    $(this).find('li.' + status ).addClass('active');
});

Error on Console

Syntax error, unrecognized expression: li. load-scripts.php?c=0&load[]=jquery-core,jquery-migrate,utils&ver=4.4.1:2

(9 Errors) Cannot read property 'hasClass' of undefined load-scripts.php?c=0&load[]=hoverIntent,common,admin-bar,svg-painter,heartbeat,wp-auth-check,thickb…:246

Any clear explanation would be highly appreciated

FULL JS CODE

( function($) {
    'use strict';
    $(document).ready( function() {

        $('ul').each( function() {
            var status = $(this).attr('name');
            //$(this).find('li.' + status ).addClass('active');
        });      
        $('form').on('click', 'li', function() {
            var currentStatus = $(this).parent().attr('name');
            var id = $(this).parent().attr('id');
            var status = $(this).attr('name');
            var input = '<input id="model-'+id+'" type="hidden" name="'+id+'" value="'+status+'" />'
            if( currentStatus !== status || !currentStatus ) {
                $('form').prepend( input );
            } else {
                $('form').find('#model-'+id).remove();
            } 
            $(this).parent().find('li').removeClass('active');
            $(this).addClass('active');
        });
        $('form').submit( function(e) { 
            e.preventDefault();
            console.log( $( this ).serialize() );
        });
    });
})(jQuery);
3
  • You mention that the class gets correctly added but there is also an error. I am pretty sure that one of the uls you are looping through (maybe one not created by you) has an undefined data-status. Generally I think it is not the best practice to use html elements in .each() or .on(). It would be much better (and safer) to explicitly attach the handlers to specific elements through classes or ids. Commented Jan 30, 2016 at 21:32
  • has an undefined data-status -- thanks, this line gave me an idea, it could be that some UL doesn't have data-status value. I'll check the source code. since all these datas are pulled from database Commented Jan 30, 2016 at 21:43
  • You could add a conditional to jump out of the each if status is not defined: if (typeof status === 'undefined' || !status) { return; } than it should also work. Commented Jan 30, 2016 at 21:45

2 Answers 2

2

A quick (although not very nice solution) would be to check the value/type of status and jump out of the .each() loop if it is not defined:

$('ul').each( function() {
    var status = $(this).attr('name');
    if (typeof status === "undefined" || !status) {
        return false;
    };
    $(this).find('li.' + status ).addClass('active');
});

As I mentioned it is generally a bad idea to loop through ALL elements of a type on a page. It would be better to loop through a set of elements with a given class.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, It was kind of stupid on me,, lol .. I just realized some UL don't have the name value. there are actually more or less 50 UL's and only check mostly on the first 10 line while those that don't have value were at the last. Thanks again, can sleep now after 10 hours as all bugs are now fixed (rock)
by the way, my actual code uses up to 3 class of selector so you don't have to worry ;) I just use main type in here so its shorter ;)
0

Try with this:

$('ul').each( function() {
    var status = $(this).attr('data-status'); //note: data-status, not status
    $(this).find('li.' + status ).addClass('active');
});

.data() method is for setting/getting object level data not represented visually in the Dom. You, however, are using attributes, which has a different accessor in jQuery (.attr()).

See here: https://api.jquery.com/data/ and here http://api.jquery.com/attr/

3 Comments

I did try both attr and data, both aren't also working
@SymmetricsWeb - Hard to believe, given that the attr() call would result in the exact same string as it is hard-coded in the first example. Then it could be that you called attr with "status" instead of "data-status", or you have a bad data-status attribute on your ul's which leads to ill-formed (invalid) selectors when .find() is invoked. Did you call attr() with "status" or "data-status"?
I've added full JS code, only that comment line produces error, and i change data attribute to name and id but still got error on this line $(this).find('li.' + status ).addClass('active');

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.