Search code examples
javascriptjqueryslideslidetoggle

Simplify jQuery code - slide and slideToggle


How can I simplify current JavaScript code? It looks too complicated.

// Data from AJAX response
var errorsJSON = {
    "name-pl": ["The name-pl field is required."],
    "name-en": ["The name-en field is required."]
}

var errorString = $(this).data('validate-multiple');
var errorNamesArray = errorString.split(", ");
var ul = $('<ul class="list-unstyled">');

$.each(errorNamesArray, function(key, value) {
    if (errorsJSON.hasOwnProperty(value)) {
        ul.append(`<li><span class="help-block">${errorsJSON[value]}</span></li>`);
    }
});

if (! $(this).is(':visible') && ul.children('li').length > 0) {
    $(this).find('div.controls').empty().append(ul);
    $(this).slideDown(500);
} else if ($(this).is(':visible') && ul.children('li').length === 0) {
    $(this).slideUp(500);
} else if ($(this).is(':visible') && ul.children('li').length > 0) {
    $(this).slideUp(500, function() {
        $(this).find('div.controls').empty().append(ul);
        $(this).slideDown(500);
    });
}

Here I pasted both html and js code http://jsfiddle.net/ecLjnnhm/ I would like to point out that errorsJSON can change and depends what user put in the input fields.


Solution

  • Readability: Use variables to store the conditions of your if statements instead of lengthy declarations each time.

    Efficiency: Cache $(this) as a variable so jQuery only has to do the work once.

    Personal preference: I'd suggest prefacing any jQuery object variables (like ul in your case) with a $ to indicate that they're a jQuery object.

    // Data from AJAX response
    var errorsJSON = {
        "name-pl": ["The name-pl field is required."],
        "name-en": ["The name-en field is required."]
    }
    
    var errorString = $(this).data('validate-multiple');
    var errorNamesArray = errorString.split(", ");
    var $ul = $('<ul class="list-unstyled">');
    var $t = $(this);
    var isVisible = $t.is(':visible');
    var hasErrors = false;
    
    $.each(errorNamesArray, function(key, value) {
        if (errorsJSON.hasOwnProperty(value)) {
            $ul.append(`<li><span class="help-block">${errorsJSON[value]}</span></li>`);
            hasErrors = true;
        }
    });
    
    if (!isVisible && hasErrors) {
        $t.find('div.controls').empty().append(ul);
        $t.slideDown(500);
    } else if (isVisible && !hasErrors) {
        $t.slideUp(500);
    } else if (isVisible && hasErrors) {
        $t.slideUp(500, function() {
            $t.find('div.controls').empty().append(ul);
            $t.slideDown(500);
        });
    }