Search code examples
javascriptgreasemonkeyfirefox2

How do I stop certain values of input, based on text elsewhere in the page?


I have an existing script which is running perfectly! It is coded for Firefox 2.x and Greasemonkey 0.8.x and I can't use jQuery!

OLD WORKING SCRIPT:

//--- Make sure this list of names is all uppercase.
var usersWhoCanSetPriority = ['JOHN', 'LUKE', 'JEFF', 'MAX', 'ANDY'];

var bDisablePrio    = true;
var tdNodes         = document.getElementsByTagName ("TD");
for (var J = tdNodes.length - 1;  J >= 0;  --J) {
    var tdNode      = tdNodes[J];
    if (tdNode.className == "user") {
        var userName        = tdNode.textContent.replace (
            /^(?:.|\n|\r)+\(User:\s+([^)]+)\)(?:.|\n|\r)+$/i, "$1"
        ).toUpperCase ();

        if (usersWhoCanSetPriority.indexOf (userName) > -1) {
            bDisablePrio    = false;
        }
    }
}

if (bDisablePrio) {
    var oldInput = document.getElementsByName ("prio");
    oldInput[0].setAttribute ("disabled", "disabled");
}


  1. Here's a fiddle of how it looks/acts when the user is not in usersWhoCanSetPriority.

  2. Here's a fiddle of how it looks/acts when the user has full access.


NEW SCRIPT EXAMPLE:

Now, if the destination input is present, privileged users should be able to set any value.
But unprivileged users should be blocked from setting 12 and 22.

  1. Privileged user, with Destination field.

  2. Restricted user, with Destination field.

That is, if the user is NOT -> 'JOHN', 'LUKE', 'JEFF', 'MAX', 'ANDY' (from footer) then disable the prio input, and stop the input when user is entering "12" or "22", and write an error message.

You have to know that Steve ("not-allowed user") is allowed to enter for example 120, 121, 220, 222 and all other numbers but not the 12 and 22! I don't know if it is a problem because the 12 is also in 120! 'JOHN', 'LUKE', 'JEFF', 'MAX', 'ANDY' are allowed to enter all numbers into the input.

The old script runs on different pages like site-one.html and site-two.html However the destination input is on site-one.html and on site-three.html - it means sometimes I have only the prio-input and sometimes I have both the prio-input and destination-input.

How do I do all that?

Regards, Bernte


Solution

  • User user1653020's answer is close, but it has several problems:

    1. It will fail in Greasemonkey 0.8! See "Pitfall #2: Event Handlers".
    2. It will crash when destination is not present.
    3. It is not very user-friendly. (Doesn't let the user know what she is doing wrong.)
    4. Allows for the user to submit invalid values.

    Go to jsfiddle.net/P2VeG, enter 12 for the destination and press Enter or click the "Submit" button. You'll see that the form gets sent to the server, and with an invalid Destination value and no warning to the user!

    The following code should overcome all of those problems. (But it's untested in GM 0.8 and FF2, for obvious reasons.)

    See the code in action at jsfiddle.net/P2VeG/2.

    //--- Make sure this list of names is all uppercase.
    var usersWhoCanSetPriority  = ['JOHN', 'LUKE', 'JEFF', 'MAX', 'ANDY'];
    var excludedDestinations    = ['12', '22'];
    
    var bDisablePrio    = true;
    var tdNodes         = document.getElementsByTagName ("TD");
    for (var J = tdNodes.length - 1;  J >= 0;  --J) {
        var tdNode      = tdNodes[J];
        if (tdNode.className == "user") {
            var userName        = tdNode.textContent.replace (
                /^(?:.|\n|\r)+\(User:\s+([^)]+)\)(?:.|\n|\r)+$/i, "$1"
            ).toUpperCase ();
            if (usersWhoCanSetPriority.indexOf (userName) > -1) {
                bDisablePrio = false;
            }
        }
    }
    
    if (bDisablePrio) {
        var oldInput    = document.getElementsByName ("prio");
        if (oldInput  &&  oldInput.length) {
            oldInput[0].setAttribute ("disabled", "disabled");
        }
    
        var destInput   = document.getElementsByName ("dest");
        if (destInput  &&  destInput.length) {
            destInput[0].addEventListener (
                "change",
                function (zEvent) {
                    bCheckdestinationValue (destInput[0]);
                },
                false
            );
    
            //--- Extra added to try and get FF2 to behave as later versions do.
            destInput[0].addEventListener (
                "keydown",
                function (zEvent) {
                    if (zEvent.keyCode == 13) {
                        if ( bCheckdestinationValue (destInput[0]) ) {
                            zEvent.preventDefault ();
                            zEvent.stopPropagation ();
                            return false;
                        }
                    }
                },
                true
            );
    
            destInput[0].form.addEventListener (
                "submit",
                function (zEvent) {
                    var destValue   = destInput[0].value;
                    if (    destValue === ''
                            ||  excludedDestinations.indexOf (destInput[0].value) > -1
                    ) {
                        //--- Stop the submit
                        /*--- According to:
                            http://www.webdevout.net/browser-support-dom#dom2events
                            preventDefault() and stopPropagation() are supported by FF2
                        */
                        zEvent.preventDefault ();
                        zEvent.stopPropagation ();
                        return false;
                    }
                },
                true
            );
        }
    }
    
    function bCheckdestinationValue (destInputNd) {
        //--- Returns true if value is bad.
        if (excludedDestinations.indexOf (destInputNd.value) > -1) {
            destInputNd.value = ''; // Blank input
    
            //--- Add or show Error message.
            var destErrNode = document.getElementById ("gmDestErrorDisp");
            if (destErrNode) {
                destErrNode.style.display = "inline";
            }
            else {
                destErrNode             = document.createElement ('b');
                destErrNode.id          = "gmDestErrorDisp";
                destErrNode.style.color = "red";
                destErrNode.textContent = "12 and 22 are forbidden";
                destInputNd.parentNode.appendChild (destErrNode);
            }
            //--- Uncomment this alert(), if all else fails in FF2.
            ////alert ('Destination cannot be 12 or 22.');
            return true;
        }
        else {
            var destErrNode = document.getElementById ("gmDestErrorDisp");
            if (destErrNode) {
                destErrNode.style.display = "none";
            }
        }
        return false;
    }