Incdec1

Incdec1.html  [download]

<!DOCTYPE html>

<html>
<head>

<title>Comp 86 Incdec1 example</title>

<script type="text/javascript">

/*
 **************************************************
 * Incdec widget as a class
 **************************************************
 */
class Incdec {
	constructor () {
		/*
		 * 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 *Have* not *be* a panel

		/*
		 * 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.innerHTML = "+"
		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.innerHTML = "-"
		this._panel.appendChild (this._downButton); //*3

		// Install our callback for both buttons
		// "this" in callback is normally the HTML element,
		// but now "self" will be in scope when callback is called
		var self = this //*4 To use for callbacks
		this._upButton.onclick = function (e) { self._actionPerformed(e); } //*5 Callback for both buttons
		this._downButton.onclick = function (e) { self._actionPerformed(e); } //*5
	}

	getPanel () {return this._panel} //*2

	/*
	 * Common code fragment, extracted to here
	 */
	_refreshLabel () {
		this._label.innerHTML = this._value
	}

	/*
	 * Common callback for both buttons
	 * e = event, e.target = widget, this = incdec because we rigged it above
	 */
	_actionPerformed (e) { //*5
		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 New feature
}

/*
 **************************************************
 * Initialization
 **************************************************
 */
window.onload = function () {
	var maindiv = document.getElementById("maindiv")

	// Create some Incdec's for testing
	var id1 = new Incdec()
	maindiv.appendChild (id1.getPanel())

	// Demonstrate our setBorderColor
	var id2 = new Incdec()
	id2.setBorderColor("green")
	maindiv.appendChild (id2.getPanel())

	// And a button to report the data from the Incdec's, for testing
	var b = document.createElement ("button")
	b.innerHTML = "Get data"
	maindiv.appendChild (b)
	b.onclick = function (e) {
		alert ("Values = " + id1.value + //*6
			", " +  id2.value) //*6
	}
}

</script> 
</head>

<body>

<div id="maindiv" height="500px" width="100%">
</div>

</body>
</html>