<!DOCTYPE html>
<html>
<head>
<title>CS 86 Incdec1 example</title>
<script>
/*
**************************************************
* Main class
**************************************************
*/
class Main {
constructor () {
// Create some Incdec's for testing
this._id1 = new Incdec()
maindiv.appendChild (this._id1.getPanel())
// Demonstrate our setBorderColor
this._id2 = new Incdec()
this._id2.setBorderColor("green")
maindiv.appendChild (this._id2.getPanel())
// And a button to report the data from the Incdec's, for testing
let b = document.createElement ("button")
b.textContent = "Get data"
maindiv.appendChild (b)
b.addEventListener("click", //*6 New feature
() => alert ("Values = " + this._id1.value + //*6
", " + this._id2.value)) //*6
}
}
/*
**************************************************
* Incdec widget as a class
**************************************************
*/
class Incdec { //*1 *Have* not *be* a panel
constructor () { //*1
/*
* We will *have* a captive HTML panel (div), not *be* a panel
* also provide public access function to the panel
*/
this._panel = document.createElement ("div") //*1
/*
* Our data, initialized inline here
*/
this._value = 0 //*2 Our "private" ivars
this._min = 0 //*2
this._max = 100 //*2
this._incr = 1 //*2
// Put a border on our panel
// default color, user can modify later
this._panel.style.borderStyle = "solid"
this._panel.style.borderColor = "red"
this._panel.style.borderWidth = "1px"
// And some spacing
this._panel.style.width = "30px"
this._panel.style.margin = "4px"
this._panel.style.padding = "2px"
/*
* Our internal widgets, we will save them in ivars
*/
// Our up button
this._upButton = document.createElement("button"); //*3 Create our internal HTML widgets
this._upButton.textContent = "+" //*3
this._panel.appendChild (this._upButton); //*3
// Our label widget
this._label = document.createElement("div"); //*3
this._refreshLabel ();
this._panel.appendChild (this._label); //*3
// Our down button
this._downButton = document.createElement("button"); //*3
this._downButton.textContent = "-"
this._panel.appendChild (this._downButton); //*3
// Install our callback for both buttons.
// Uses "=>" style function def so that "this" will be our object
// rather than the HTML button element
this._upButton.addEventListener("click", //*4 Callback for both buttons, using arrow syntax
(e) => this._actionPerformed (e)) //*4
this._downButton.addEventListener("click", //*4
(e) => this._actionPerformed (e)) //*4
}
getPanel () {return this._panel} //*2
/*
* Common code fragment, extracted to here
*/
_refreshLabel () {
this._label.textContent = this._value
}
/*
* Common callback for both buttons, as an actual method
* e = event, e.target = button widget, this = Incdec because we rigged it above
*/
_actionPerformed (e) { //*5 Callback method for both buttons
if (e.target==this._upButton) this._value += this._incr; //*5
else if (e.target==this._downButton) this._value -= this._incr; //*5
// Clamp at bounds
if (this._value > this._max) this._value = this._max;
if (this._value < this._min) this._value = this._min;
// Update our label widget to match
this._refreshLabel (); //*5
}
/*
* Just as an example, we let user customize border color here
* Public method, no "_"
*/
setBorderColor (color) {
this._panel.style.borderColor = color
}
// New special "getter" syntax
// (would work for getPanel() above also)
get value () { return this._value; } //*6
}
/*
**************************************************
* Initialization
**************************************************
*/
window.onload = function () {
new Main ()
}
</script>
</head>
<body>
<div id="maindiv" height="500px" width="100%">
</div>
</body>
</html>