Cash Drawer Counter in Seaside

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:

WAComponent subclass: #MoneyCounter
instanceVariableNames: 'count myTotal mySlots'
classVariableNames: ''
poolDictionaries: ''
category: 'MoneyChanger'

| total |
  total := 0.0.
  mySlots do: [ :each | total := total + each total ].
^ total
total: amount


  super initialize.
  myTotal := 0.
  count := 0.
  mySlots := OrderedCollection new.
  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'.


  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];
    [ html textInput
        id: type asString;
        on: type asSymbol of: self;
          (html updater id: 'total';
                triggerFormElement: type asString;
                callback: [ :r  |  self renderTotalOn: r])
   ] ]
renderRow: html forSlot: aSlot
  html tableRow:
    [ html
      tableData: [ html text: aSlot name ];
        [ html textInput
          id: aSlot name asString;
          on: #quantity
          of: aSlot;
            (html updater
                  id: 'total';
                  triggerFormElement: aSlot name asString;
                  callback: [ :r | self renderTotalOn: r ]) ] ]

renderTotalOn: html
  html render: self total
^ '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: ''


Published by


I'm the founder of Agoric Source, co-organizer of the Houston Python Meetup, director of technology at Newspaper Subscription Services, LP, technology advisor to InstaFuel, active board member of the Houston Area Model United Nations, and occasional volunteer to the Red Cross (during hurricanes or other local emergencies). I'm first and foremost still a software hacker, but with my economics background and business experience, I serve well as a project or program manager, technical visionary, etc.