0

I have an HTML page with the following code:

<input type="number" maxlength="5" id="patrollerID.1.1" placeholder="ID Num" onchange="getPatroller(this.id)" />

I would like to move the JavaScript out of the html. The id changes based on change events. How can I keep all of the JavaScript in my .js file instead of inline?

Here is what I have:

function getPatroller(patroller) {
    var element = document.getElementById(patroller);
    /** @type {Date} */
    var date = new Date();
    /** @const */
    var ID = 2,
        LAST = 0,
        FIRST = 1,
        LEVEL = 3;
    /** @type {number} */
    var exists = 0;
    /** @type {string} */
    var level;
    /** @type {Array.<string>} */
    var elementId = patroller.split('.');
    for (var j = 0; j < patrollers.length; j++) {
        if (element.value == patrollers[j][ID]) {
            document.getElementById("patroller." + elementId[1] + "." + elementId[2]).innerHTML = "<h4>" + patrollers[j][FIRST] + " " + patrollers[j][LAST] + "</h4>";
            if (patrollers[j][LEVEL] == 1) {
                level = "Basic";
            } else if (patrollers[j][LEVEL] == 2) {
                level = "Senior";
            } else {
                level = "Certified";
            }
            document.getElementById("level." + elementId[1] + "." + elementId[2]).innerHTML = "<h4>" + level + "</h4>";
            var minutes = date.getMinutes();
            if (minutes < 10) {
                minutes = "0" + minutes;
            }
            document.getElementById("time." + elementId[1] + "." + elementId[2]).innerHTML = "<h4>" + date.getHours() + ":" + minutes + "</h4>";
            patrollers.splice(patrollers[j]--, 1); //remove array element
            elementId[2]++;
            /** @type {boolean} */
            var addTeam = setCounter(elementId[1]);
            if (addTeam === true) {
                addPatroller(elementId[1], elementId[2]);
            }
            exists = 1;
            break;
        }
    }
    if (exists == 0) {
        alert("PLEASE TRY AGAIN!");//Do something here if number already in use.
        element.value = '';
    }
}

function setCounter(teamNum) {
    /** @const */
    var MAX_TEAM = 4;
    if (teamNum == 1) {
        if (typeof t1Counter == 'undefined') {
            t1Counter = 1;
        }
        if (t1Counter < MAX_TEAM) {
            t1Counter++;
            return true;
        } else {
            return false;
        }
    } else if (teamNum == 2) {
        if (typeof t2Counter == 'undefined') {
            t2Counter = 1;
        }
        if (t2Counter < MAX_TEAM) {
            t2Counter++;
            return true;
        } else {
            return false;
        }
    } else if (teamNum == 3) {
        if (typeof t3Counter == 'undefined') {
            t3Counter = 1;
        }
        if (t3Counter < MAX_TEAM) {
            t3Counter++;
            return true;
        } else {
            return false;
        }
    } else if (teamNum == 4) {
        if (typeof t4Counter == 'undefined') {
            t4Counter = 1;
        }
        if (t4Counter < MAX_TEAM) {
            t4Counter++;
            return true;
        } else {
            return false;
        }
    }  else {
        if (typeof t5Counter == 'undefined') {
            t5Counter = 1;
        }
        if (t5Counter < MAX_TEAM) {
            t5Counter++;
            return true;
        } else {
            return false;
        }
    }
}
BackPacker777
  • 673
  • 2
  • 6
  • 21

1 Answers1

0

You use addEventListener, or attachEvent on older IE (IE8 and before).

In this case:

document.getElementById("patrollerID.1.1").addEventListener("change", function() {
    // Here, `this` refers to the element, so:
    getPatroller(this.id);
}, false);

This other answer has a hookEvent function you can use if you need to support older IE and don't want to use a DOM library like jQuery.


Re your comment:

I don't know if I'm being clear: The id changes for each change event, i.e. patrollerID.1.1 changes to patrollerID.1.2, etc

I think you mean, there are multiple elements with different ids, rather than that the id changes. :-)

In that case, you have two options:

  1. Use querySelectorAll (which returns a list) with a valid CSS selector that will select the elements ([id^=patroller], for instance, or perhaps something structural, or give them a class) and loop through the resulting list using addEventListener on each entry as above.

  2. Or, hook the change event on an element that contains all of these inputs, accept the event argument in your handler function, and look at the target property on it — that will be the input where the change occurred. This is called "event delegation."

Here's an addEventListener-only example of #2:

// Hook `change` on the container:
document.getElementById("container").addEventListener("change", function(e) {
  // Is it a patroller?
  if (e.target && e.target.id && e.target.id.substring(0, 9) === "patroller") {
    // yes
    alert("Patroller " + e.target.id + " changed to " + e.target.value);
  }
}, false);
<div id="container">
  <div>
    We care about these inputs, so when you change them, you'll see an alert:
    <br><input type="text" id="patroller1">
    <input type="text" id="patroller2">
    <input type="text" id="patroller3">
  </div>
  <div>
    We don't care about these ones, changing them doesn't do anything:
    <br><input type="text">
    <input type="text">
    <input type="text">
  </div>
</div>
Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • I don't know if I'm being clear: The id changes for each change event, i.e. patrollerID.1.1 changes to patrollerID.1.2, etc... – BackPacker777 Mar 18 '15 at 16:25