Search code examples
javascriptprototypejs

class vs addClassName jscript


what is the difference, in using class vs addClassName jscript?

in a for loop, whenever I was adding a class to the existing class, then after each loop cycle it was adding new class to it. So condition to enter the loop was changing after each time.

when I used class instead of addClassName then everything started to work as it should be. Which is after each reverse session the loop was matching the condition.

How it can be explained?

WORKING VERSION:

    for (var i = 0; i < fields.length; i++) //instead of .each
    {
            alert(0.5);
            alert(fields[i].className);


        if (fields[i].className == 'text' || fields[i].className == 'date' || fields[i].className == 'number' || fields[i].className == 'text error' || fields[i].className == 'date error' || fields[i].className == 'number error' || fields[i].className == 'text valid' || fields[i].className == 'date valid' || fields[i].className == 'number valid' || fields[i].className == 'text valid error' || fields[i].className == 'date valid error' || fields[i].className == 'number valid error' )
        {
        alert(0.3);

        var val = fields[i];        


        var classname = "";
        if(val.value.length <= 4) {
            classname = fields[i].className + " error";


            fields[i].class = classname;

            Effect.Shake(fields[i], { times:3 }, 50);
            errorString = 'Please complete all required fields.';

           alert(0.6);
           alert(val.value);
           alert(0.66);
           alert(fields[i].name);
           alert(val.value.class);
           //error++;
        }  


        else {

            classname = fields[i].className + " valid";
            fields[i].class = classname;
            alert(8.5);
           alert(val.value.class);

        }

        } 
        alert(8.8);
            alert(fields[i].class); 
    }  

VERSION WHICH IS NOT WORKING:

            for (var i = 0; i < fields.length; i++) //instead of .each
    {

        if (fields[i].className == 'text' || fields[i].className == 'date' ||      fields[i].className == 'number' || fields[i].className == 'text error' || fields[i].className == 'date error' || fields[i].className == 'number error' )
        {
        var val = fields[i];        



        if(val.value.length <= 4) {             
            fields[i].addClassName('error');

            Effect.Shake(fields[i], { times:3 }, 50);
            errorString = 'Please complete all required fields.';

            error++;
        } else {
            fields[i].addClassName('valid');

        }

        }

    }  

Solution

  • Explanation

    class is a reserved keyword (for possible future use), therefore it should not be used as object attribute (like someobject.reservedKeyword) and therefore className instead of class is used as nnnnnn points out in the comment to your question.

    In your code, this won't work:

    fields[i].class = classname
    

    ...but this one will

    fields[i].className = classname
    

    This is the source code of prototypejs addClassName

    function addClassName(element, className) {
        if (!(element = $(element))) return;
    
        if (!hasClassName(element, className))
          element.className += (element.className ? ' ' : '') + className;
    
        return element;
    }
    

    see the prototypejs link

    Solution

    Therefore use addClassName, removeClassName and hasClassName. In your code:

    for (var i = 0; i < fields.length; i++) {
        if(fields[i].hasClassName("text") || fields[i].hasClassName("number") || fields[i].hasClassName("date")) {
            if(fields[i].value.length<=4) {
                fields[i].addClassName("error");
                fields[i].removeClassName("valid");
                Effect.Shake(fields[i], { times:3 }, 50);
                errorString = 'Please complete all required fields.';
            }
            else {
                fields[i].addClassName("valid");
                fields[i].removeClassName("error");
            }
        }
    }
    

    Note: in modern browsers we use classList attribute instead:

    prototype.js                         | modern browsers
    ---------------------------------------------------------------------
    element.hasClassName("someclass")    | element.classList.contains("someclass")
    element.addClassName("someclass")    | element.classList.add("someclass")
    element.removeClassName("someclass") | element.classList.remove("someclass")