Updater examples with Scriptalicious & Seaside

The first of a series of coding vignettes in Seaside.

 Context: a web app with a form containing multiple input fields.  Instead of waiting to submit the form, I want the page to update another element every time an input is changed.  In this example, a total field.  Solution was used for a simple MoneyCounter application:

MoneyCounter>>renderContentOn: html html form id: 'f'; with: [

html table: [
    html tableRow:
     [html tableData: [html text: 'pennies'];
           tableData:
         [html textInput
           id: 'pennies';
 	   "on: #pennies of: self;"
           callback: [:value | self pennies: value];
 	   onChange: (html updater
                       id: 'total';
		       triggerFormElement: 'pennies';
 		       callback: [ :r  |  self renderTotalOn: r])
       ] ]

    etc.

    html tableRow:
      [html tableData: [html text: 'TOTAL'; space];
            tableData: [html span id: 'total' ; with: self total]]]]


MoneyCounter>>renderTotalOn: html

 html render: self total
MoneyCounter>>pennies: value
   pennies := value

MoneyCounter>>total
	^((pennies asInteger * 0.01) +  etc.   )

The real action demonstrated here is in onChange: . onChange will accept a Javascript function or an SUUpdater to automagically do the Javascript functioning. html updater returns just such an SUUpdater, and the two important things this updater does is a define a callback block of code – this block will be called everytime onChange is triggered – in this case, to renderTotalOn. Important, though, for this block to work correctly, is to also call triggerFormElement. This will trigger the callback block on the element itself, callback: [:value | self pennies: value], then also do the  updater callback. Without the triggerFormElement, calling renderTotalOn will update the total with the “old” value of pennies, instead of what the user had currently entered.

In simple English, whenever the input field is changed, update the value that is bound to the field, then update the Total field.

For this to work appropriately, it’s also important to set element ids correctly.   The updater also seems to require an id – and seemingly that id must be the same as the element that it is updating, but I’m not exactly clear on this yet.

Published by

kevin

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.