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 and president of Agoric Source, LLC, co-organizer of the Houston Python Meetup, and active board member of several local non-profit organizations, including Ten Thousand Villages Houston, the Houston Area Model United Nations, and the Weekley Family YMCA. 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. I'm opinionated, but hopefully reasonable so. My blog is just a chance for me to keep up with my writing skills, and expound upon various technology and policy subjects. I especially try to keep up with the Houston software community.