This is a simple application I wrote, just to learn more about Seaside, and specifically to figure out onChange: actions, which makes use of Scriptaculous to create an AJAXy web application without much effort.
You can see the application at work at:
agoric.seasidehosting.st/cashdrawer
WAComponent subclass: #MoneyCounter instanceVariableNames: 'count myTotal mySlots' classVariableNames: '' poolDictionaries: '' category: 'MoneyChanger' total | total | total := 0.0. mySlots do: [ :each | total := total + each total ]. ^ total
total: amount "ignore" initialize super initialize. myTotal := 0. count := 0. mySlots := OrderedCollection new. mySlots add: (MoneySlot new createNew: 'pennies' withValue: 0.01); add: (MoneySlot new createNew: 'nickles' withValue: 0.05); add: (MoneySlot new createNew: 'dimes' withValue: 0.1); add: (MoneySlot new createNew: 'quarters' withValue: 0.25); add: (MoneySlot new createNew: 'dollars' withValue: 1.0); add: (MoneySlot new createNew: 'fives' withValue: 5.0); add: (MoneySlot new createNew: 'tens' withValue: 10.0); add: (MoneySlot new createNew: 'twenties' withValue: 20.0); add: (MoneySlot new createNew: 'fifties' withValue: 50.0); add: (MoneySlot new createNew: 'hundreds' withValue: 100.0); add: (MoneySlot new createNew: 'penny rolls' withValue: 0.50); add: (MoneySlot new createNew: 'nickle rolls' withValue: 2.0); add: (MoneySlot new createNew: 'dime rolls' withValue: 5.0); add: (MoneySlot new createNew: 'quarter rolls' withValue: 10.0)
updateRoot: anHtmlRoot super updateRoot: anHtmlRoot. anHtmlRoot title: 'MoneyCounter'. updateTotal myTotal := self total
renderContentOn: html html div class: 'main'; with: [ html heading: 'Money Counter'. self renderFormOn: html] renderFormOn: html html form id: 'f'; with: [ html table: [mySlots do: [:each | self renderRow: html forSlot: each]. html tableRow: [ html tableData: [ html text: 'TOTAL'; space]; tableData: [ html span id: 'total' ; with: self total ] ] ] ]
renderRow: html for: type html tableRow: [ html tableData: [ html text: type asString]; tableData: [ html textInput id: type asString; on: type asSymbol of: self; onChange: (html updater id: 'total'; triggerFormElement: type asString; callback: [ :r | self renderTotalOn: r]) ] ]
renderRow: html forSlot: aSlot html tableRow: [ html tableData: [ html text: aSlot name ]; tableData: [ html textInput id: aSlot name asString; on: #quantity of: aSlot; onChange: (html updater id: 'total'; triggerFormElement: aSlot name asString; callback: [ :r | self renderTotalOn: r ]) ] ] renderTotalOn: html html render: self total
style
^ 'span {font-weight: bold} body {margin-left: 5%} div.main {background-color: rgb(215,250,179);padding-left: 1em;width: 250px;border: 1px solid rgb(161,196,127)} input {width: 60px; text-align: center} table {margin-left: 1em; text-align: right}'
"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "
MoneyCounter class instanceVariableNames: '' canBeRoot ^true