IncdecApp1: IncdecApp1.html

<!DOCTYPE html>

<html>
<head>

<title>Comp 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>
[download file]