[Seaside] A bit of help with Seaside
Avi Bryant
avi at beta4.com
Fri Feb 14 17:46:04 CET 2003
On Fri, 14 Feb 2003, [iso-8859-1] Germ=E1n S. Arduino wrote:
> By example: I would to have a html grid showing people records, then by
> means of a check box in each row I want to be able to select a record and
> modify or delete. Also I must to add records. But I can't figure how to
> build that grid (table), how to populate with my objects, and so.
German,
Start with a WAComponent subclass that will display this grid. Let's call
it RecordList:
WAComponent subclass: #RecordList
=09instanceVariableNames: ''
=09classVariableNames: ''
=09poolDictionaries: ''
=09category: 'German-Example'
RecordList will need some method, say, #records that will get a list of
all the records you want it to show. I don't know where you have these
stored, so I'll just assume you have a global for them somewhere (not
that I endorse that approach - really, this should probably be something
that's passed into the component when it's created).
RecordList>>records
^ AllRecords
The main responsibility of the RecordList is to implement
#renderContentOn:, which will display the list and create the links, etc,
that you need. It'll start quite simply: creating a table, and then
calling a second method to render a table row for each record.
RecordList>>renderContentOn: html
html table: [
self records do:
[:record |
self renderRowForRecord: record on: html]
]
We can now implement #renderRowForRecord:on:. I'll leave out the
checkboxes for now, and just have it create a 'modify' and 'delete' link
for each record.
RecordList>>renderRowForRecord: aRecord on: html
html tableRow: [
"one column describing the record"
html tableData: [html text: aRecord printString].
"one column with links"
html tableData: [
html anchorWithAction: [self modify: aRecord] text: 'modify'.
html space.
html anchorWithAction: [self delete: aRecord] text: 'delete'.
]
This will display a table with a row for each record that contains a
modify and a delete link. Clicking those links will call #modify: or
#delete: on the RecordList, passing in the correct record.
To implement #modify:, you probably need a RecordEditor component, that
can be given a record, and displays a form to edit it. A good example of
such a component is WSMCardEditor from Seaside/Examples-SM. You would
want #modify: to create one of these components, pass it the record, and
then #call: it, causing that page to be shown instead of the list:
RecordList>>modify: aRecord
self call: (RecordEditor new record: aRecord)
To implement #delete:, you might want to ask the user if they really want
to delete the record first. Then, simply delete it from your list of
records.
RecordList>>delete: aRecord
(self confirm: 'Are you sure you want to delete ', aRecord printString, '=
?')
ifTrue: [AllRecords remove: aRecord]
Now, if you want to use checkboxes, things get a little trickier. You
need tp create some data structure to store which rows are checked and
which aren't. I'll show you how you'd do it using a Dictionary that has
a true or false entry for each record being shown. You'll need to add a
'selected' instance variable to the component:
WAComponent subclass: #RecordList
instanceVariableNames: 'selected'
classVariableNames: ''
poolDictionaries: ''
category: 'German-Example'
and override the component's #initialize method to create a Dictionary:
RecordList>>initialize
selected :=3D Dictionary new.
now, when you render a row, you want it to also have a checkbox. This
checkbox will always be displayed unchecked, but when the form is
submitted, it will store true or false in the 'selected' dictionary:
RecordList>>renderRowForRecord: aRecord on: html
html tableRow: [
"one column with a checkbox"
html tableData: [
html
checkboxWithValue: false
callback: [:b | selected at: aRecord put: b]
]
"one column describing the record"
html tableData: [html text: aRecord printString].
"one column with links"
html tableData: [
html anchorWithAction: [self modify: aRecord] text: 'modify'.
html space.
html anchorWithAction: [self delete: aRecord] text: 'delete'.
]
You need to make sure that the table is wrapped inside a form, and add a
Delete button that will delete all of the selected records:
RecordList>>renderContentOn: html
html form: [
html table: [
self records do:
[:record |
self renderRowForRecord: record on: html]
]
html submitButtonWithAction: [self deleteSelected] text: 'Delete'.
]
We can implement a method #selectedRecords that will find only records
that have been checked off:
RecordList>>selectedRecords
^ self records select: [:ea | selected at: ea]
Finally, implement #deleteSelected; we can put in a check to make sure the
selection is not empty
RecordList>>deleteSelected
|recordsToDelete|
recordsToDelete :=3D self selectedRecords.
recordsToDelete isEmpty
ifTrue: [^ self inform: 'You must select at least one record!'].
(self confirm: 'Delete ', recordsToDelete size asString, ' records?')
ifTrue: [AllRecords removeAll: recordsToDelete]
And I think that's it. Does that help?
Avi
More information about the Seaside
mailing list