File: Examples/Example_HSM_calculator.html

Recommend this page to a friend!
  Classes of Emmanuel Podvin  >  jQuery FSM  >  Examples/Example_HSM_calculator.html  >  Download  
File: Examples/Example_HSM_calculator.html
Role: Example script
Content type: text/plain
Description: Example
Class: jQuery FSM
Animate page elements using Finite State Machines
Author: By
Last change: Now compliant to jquery 3.2.0
Date: 4 years ago
Size: 10,076 bytes
 

Contents

Class file image Download
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>iFSM in action! a simple calculator managed with a FSM</title>
<script type="text/javascript" src="../extlib/jquery-3.2.0.min.js"></script>
<script type="text/javascript" src="../extlib/jquery.dotimeout.js"></script>
<script type="text/javascript" src="../extlib/jquery.attrchange.js"></script>
<script type="text/javascript" src="../iFSM.js"></script>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<style type="text/css">
html {
	font-family: Helvetica, Arial, sans-serif;
}

body {
	padding: 0 20px;
}

button {
	margin: 2px 2px;
	font-size: 20px;
	border: 1px solid #333;
	width: 70px;
	text-shadow: 0 -1px 0 #333;
	border-radius: 5px;
}

button.on {
	color: #dfd;
	background: #00aa00;
	background: -moz-linear-gradient(top, rgba(0, 153, 0, 1) 0%,
		rgba(0, 119, 0, 1) 100%);
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(0,
		153, 0, 1)), color-stop(100%, rgba(0, 119, 0, 1)));
	background: -webkit-linear-gradient(top, rgba(0, 153, 0, 1) 0%,
		rgba(0, 119, 0, 1) 100%);
	background: -o-linear-gradient(top, rgba(0, 153, 0, 1) 0%,
		rgba(0, 119, 0, 1) 100%);
	background: -ms-linear-gradient(top, rgba(0, 153, 0, 1) 0%,
		rgba(0, 119, 0, 1) 100%);
	background: linear-gradient(top, rgba(0, 153, 0, 1) 0%,
		rgba(0, 119, 0, 1) 100%);
}

button.off {
	color: #fdd;
	background: #CC0000;
	background: -moz-linear-gradient(top, rgba(204, 0, 0, 1) 0%,
		rgba(153, 0, 0, 1) 100%);
	background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(204,
		0, 0, 1)), color-stop(100%, rgba(153, 0, 0, 1)));
	background: -webkit-linear-gradient(top, rgba(204, 0, 0, 1) 0%,
		rgba(153, 0, 0, 1) 100%);
	background: -o-linear-gradient(top, rgba(204, 0, 0, 1) 0%,
		rgba(153, 0, 0, 1) 100%);
	background: -ms-linear-gradient(top, rgba(204, 0, 0, 1) 0%,
		rgba(153, 0, 0, 1) 100%);
	background: linear-gradient(top, rgba(204, 0, 0, 1) 0%,
		rgba(153, 0, 0, 1) 100%);
}

#result {
	background-color: #5BB75B;
	background-image: linear-gradient(to bottom, #62C462, #51A351);
	background-repeat: repeat-x;
	border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
	color: #FFFFFF;
	text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
	font-size: 20px;
	line-height: 25px;
	padding: 2px 6px;
	width: 200px;
}
</style>

<script type="text/javascript" id="iFSMscript">
	var PC_OnBehaviour = {

		Operand1 : {
			enterState : {
				init_function : function() {
					this.opts.operand1 = '';
				},
			},
			setOperand : {
				next_state : 'Operand1Filled',
				propagate_event : true,
			},
			setCommaOperand : {
				next_state : 'Operand1WithCommaFilled',
				propagate_event : 'setOperand',
			},
			setOperator : {
				init_function : function() {
					this.opts.operand1 = this.opts.result
				},
				next_state : 'Operator',
				propagate_event : true,
			},
		},
		Operand1Filled : {
			setOperand : {
				init_function : function(p, e, operand) {
					this.opts.operand1 = this.opts.operand1 + operand;
					this.myUIObject
							.trigger('displayResult', this.opts.operand1);
				},
			},
			setCommaOperand : {
				init_function : function(p, e, operand) {
					this.opts.operand1 = this.opts.operand1 + operand;
					this.myUIObject
							.trigger('displayResult', this.opts.operand1);
				},
				next_state : 'Operand1WithCommaFilled',
			},
			setOperator : {
				next_state : 'Operator',
				propagate_event : true,
			},
		},
		Operand1WithCommaFilled : {
			setOperand : {
				init_function : function(p, e, operand) {
					this.opts.operand1 = this.opts.operand1 + operand;
					this.myUIObject
							.trigger('displayResult', this.opts.operand1);
				},
			},
			setOperator : {
				next_state : 'Operator',
				propagate_event : true,
			},
		},
		Operator : {
			setOperator : {
				init_function : function(p, e, operator) {
					this.opts.operator = operator;
				},
				next_state : 'Operand2',
				next_state_when : "this.opts.operator != '='",
			},
			setOperand : {
				next_state : 'Operand1',
				propagate_event : true,
			},
		},
		Operand2 : {
			enterState : {
				init_function : function() {
					this.opts.operand2 = '';
				},
			},
			setCommaOperand : {
				next_state : 'Operand2WithCommaFilled',
				propagate_event : 'setOperand',
			},
			setOperand : {
				next_state : 'Operand2Filled',
				propagate_event : true,
			},
		},
		Operand2Filled : {
			setOperand : {
				init_function : function(p, e, operand) {
					this.opts.operand2 = this.opts.operand2 + operand;
					this.myUIObject
							.trigger('displayResult', this.opts.operand2);
				},
			},
			setCommaOperand : {
				init_function : function(p, e, operand) {
					this.opts.operand2 = this.opts.operand2 + operand;
					this.myUIObject
							.trigger('displayResult', this.opts.operand2);
				},
				next_state : 'Operand2WithCommaFilled',
			},
			setOperator : {
				next_state : 'Result',
				propagate_event : true,
			},
		},
		Operand2WithCommaFilled : {
			setOperand : {
				init_function : function(p, e, operand) {
					this.opts.operand2 = this.opts.operand2 + operand;
					this.myUIObject
							.trigger('displayResult', this.opts.operand2);
				},
			},
			setOperator : {
				next_state : 'Result',
				propagate_event : true,
			},
		},
		Result : {
			setOperator : {
				init_function : function(p, e, operator) {
					this.opts.result = eval(this.opts.operand1
							+ this.opts.operator + this.opts.operand2);
					this.myUIObject.trigger('displayResult', this.opts.result);
					this.opts.operator = operator;
				},
				next_state : 'ResultDone'
			},
		},
		ResultDone : {
			enterState : {
				next_state : 'Operand1',
				next_state_when : "this.opts.operator == '='",
			},
			setOperand : {
				init_function : function() {
					this.opts.operand1 = this.opts.result
				},
				next_state : 'Operand2',
				propagate_event : true,
			},
			setCommaOperand : 'setOperand',
		},
		DefaultState : {
			start : {
				propagate_event : 'seton',
			},
			displayResult : {
				init_function : function(p, e, message) {
					this.myUIObject.html(message);
				},
			},
			seton : {
				init_function : function() {
					this.opts.result = '0';
					this.myUIObject.trigger('displayResult', '0');
				},
				prevent_bubble : true,
				next_state : 'Operand1',
			},
		}
	};

	var PocketCalculator = {

		On : {
			enterState : {
				init_function : function() {
					this.myUIObject.html('computer on');
				},
				propagate_event : 'seton',
			},
			delegate_machines : {
				delegate_machine_1 : {
					submachine : PC_OnBehaviour
				},
			},
			setoff : {
				next_state : 'Off'
			}
		},
		Off : {
			enterState : {
				init_function : function() {
					this.myUIObject.html('computer off');
				},
			},
			seton : {
				next_state : 'On',
			},
		},
		DefaultState : {
			start : {
				next_state : 'Off',
			},

		}
	};

	var ActionButton = {

		DefaultState : {
			click : {
				init_function : function() {
					this.opts.sendto.trigger(this.myUIObject
							.attr('data-action'));
				},
			}
		}
	};

	var OperandButton = {

		DefaultState : {
			click : {
				init_function : function() {
					this.opts.sendto.trigger('setOperand', this.myUIObject
							.html());
				},
			}
		}
	};

	var OperandCommaButton = {

			DefaultState : {
				click : {
					init_function : function() {
						this.opts.sendto.trigger('setCommaOperand', this.myUIObject
								.html());
					},
				}
			}
		};

	var OperatorButton = {

		DefaultState : {
			click : {
				init_function : function() {
					this.opts.sendto.trigger('setOperator', this.myUIObject
							.html());
				},
			}
		}
	};

	$(document).ready(function() {
		$("#result").iFSM(PocketCalculator);

		$("#controlsbuttons > button").iFSM(ActionButton, {
			sendto : $("#result")
		});

		$("#operandbuttons > button").iFSM(OperandButton, {
			sendto : $("#result")
		});

		$("#operandcommabutton > button").iFSM(OperandCommaButton, {
			sendto : $("#result")
		});

		$("#operatorbuttons > button").iFSM(OperatorButton, {
			sendto : $("#result")
		});

	});
</script>
</head>
<body style="margin: 100px;">
	<p>
		Example inspired from <a
			href="http://en.wikipedia.org/wiki/UML_state_machine">http://en.wikipedia.org/wiki/UML_state_machine</a>
	</p>
	<p>Click on the "On/C" button, then you can do some simple
		calculations...</p>
	<section id="infobox">
		<h2>Result</h2>
		<div id="result"></div>
	</section>
	<section id="controlsbuttons">
		<h2>Controls</h2>
		<button class="onoff on" id="ONC" data-action="seton">On/C</button>
		<button class="onoff on" id="off" data-action="setoff">Off</button>
	</section>
	<section id="operandbuttons">
		<h2>Keyboard</h2>
		<button class="onoff on" id="k7">7</button>
		<button class="onoff on" id="k8">8</button>
		<button class="onoff on" id="k9">9</button>
		<br>
		<button class="onoff on" id="k4">4</button>
		<button class="onoff on" id="k5">5</button>
		<button class="onoff on" id="k6">6</button>
		<br>
		<button class="onoff on" id="k1">1</button>
		<button class="onoff on" id="k2">2</button>
		<button class="onoff on" id="k3">3</button>
		<br>
		<button class="onoff on" id="k0">0</button>
	</section>
	<section id="operandcommabutton">
		<button class="onoff on" id="kcomma">.</button>
	</section>
	<section id="operatorbuttons">
		<h2>Operators</h2>
		<button class="onoff on" id="kplus">+</button>
		<button class="onoff on" id="kminus">-</button>
		<button class="onoff on" id="kdivied">/</button>
		<button class="onoff on" id="kmultiply">*</button>
		<br>
		<button class="onoff on" id="kequal">=</button>
	</section>
	<pre>
        <br><br>
	<script>
		function escapeHtml(text) {
			var map = {
				'&' : '&amp;',
				'<': '&lt;',
		    '>' : '&gt;',
				'"' : '&quot;',
				"'" : '&#039;'
			};

			return text.replace(/[&<>"']/g, function(m) {
				return map[m];
			});
		}
		document.write(escapeHtml($('#iFSMscript').html()));
	</script>
    </pre>
	<p>
		provided by <a href="http://www.intersel.fr">Intersel</a>
	</p>
</body>
</html>