[Seaside] Re: Magritte Description for a collection

Stephan Eggermont stephan at stack.nl
Tue Feb 3 13:26:27 UTC 2015


Hilaire wrote:
>Let's say I have a model with a single attribute as a collection of strings. 
>
>I want a Magritte description and a Seaside component to fill this 
>collection and edit it when not empty: 
>- the user should be able to add new string in the collection with '+' 
>link and an appropriate text field 
>- if the collection contains 3 items, the component should come with 3 
>text fields 
>
>Any tips how to achieve that? 

1 First the setup to work in:

In an image with QCMagritte loaded (e.g. one from https://ci.inria.fr/pharo-contribution/job/QCMagritte/)

Create an application and a model.

QCBootstrapApplication subclass: #QCNestedDemoApplication
	instanceVariableNames: ''
	classVariableNames: ''
	category: 'NestedDemo'

QCBootstrapApplicationModel subclass: #QCNestedDemoModel
	instanceVariableNames: 'parties'
	classVariableNames: ''
	category: 'NestedDemo'

The application needs to know where to find the model

QCNestedDemoApplication >>model
	^QCNestedDemoModel default

It needs a title to display in the browser bar

QCNestedDemoApplication >>title
	^QCMultilanguageString on: 'Nested Demo'

It needs an entry point 

QCNestedDemoApplication class >>applicationName
	^'NestedDemo'

And as this is a development app where we don't
care about deployment but want the developer tools
and debugger

QCNestedDemoApplication class >>initialize
	" QCNestedDemoApplication initialize "
	self registerForDevelopment

2 The actual answer

In the model class, add lazy accessors for the parties

QCNestedDemoModel >>parties: anObject
	parties := anObject

QCNestedDemoModel >>parties
	^ parties ifNil: [ parties := OrderedCollection new ]

Create a domain class as a subclass of QCParentObject.
(This provides a hierarchical ownership model and some
default behavior)

QCParentObject subclass: #QCDemoParty
	instanceVariableNames: 'firstName lastName adresses'
	classVariableNames: ''
	category: 'NestedDemo'

Make this the entry point for the application by
adding a description to the model

QCNestedDemoModel >>descriptionParties
	<magritteDescription>
	^MAToManyRelationDescription new
		label: 'Parties ';
		accessor: #parties;
		priority: 100;
		sorted: true;
		classes: { QCDemoParty };
		yourself

DoIt QCNestedDemoApplication initialize

Open a web browser on 
http://localhost:8080/NestedDemo
and see an application showing a report where new parties can be added.



Click on Add to do so. Notice there are no descriptions for the fields yet.


It is safe to add one. The resulting table looks like


No fields, but icons representing actions for 'edit details', 'edit inline' and 'remove'
They work but do nothing useful yet. Add some descriptions and accessors.
The addresses are again lazily instantiated. 

QCDemoParty >>adresses
	^ adresses ifNil: [ adresses := OrderedCollection new ]

QCDemoParty >>adresses: anObject
	adresses := anObject

QCDemoParty >>firstName
	^ firstName

QCDemoParty >>firstName: anObject
	firstName := anObject

QCDemoParty >>lastName
	^ lastName

QCDemoParty >>lastName: anObject
	lastName := anObject

QCDemoParty >>descriptionFirstName
	<magritteDescription>
	^MADateDescription new
		priority: 100;
		label: 'First name';
		accessor: #firstName;
		visibleInReport: true;
		yourself

QCDemoParty >>descriptionLastName
	<magritteDescription>
	^MADateDescription new
		priority: 200;
		label: 'Last name';
		accessor: #lastName ;
		visibleInReport: true;
		yourself

Before adding a description for the addresses,
add a new class

QCParentObject subclass: #QCDemoAddress
	instanceVariableNames: 'address'
	classVariableNames: ''
	category: 'NestedDemo'

Setting ordered to true makes sure that
an OrderedCollection is used in the setter.
(sorted: true uses a SortedCollection)

QCDemoParty >>descriptionAdresses
	<magritteDescription>
	^MAToManyRelationDescription new
		label: 'Adresses ';
		accessor: #adresses;
		priority: 300;
		ordered: true;
		classes: { QCDemoAddress };
		yourself

Start a new session in the web browser.

Notice that only the descriptions that are visibleInReport are shown.
You can edit inline (the save and cancel buttons are not yet in 
Bootstrap style)


and you can also edit the details



To show something more useful than 'a QCDemoParty' in the top menu, override 

QCDemoParty >>displayName
	^ (String streamContents: [:s |
		firstName ifNotNil: [s nextPutAll: firstName,' '].
		lastName ifNotNil: [s nextPutAll: lastName]]) ifEmpty: [^'Party']

The addresses also need to show something more useful. Add accessors and a description

QCDemoParty >>address
	^ address

QCDemoParty >>address: anObject
	address := anObject

QCDemoParty >>descriptionAddress
	<magritteDescription>
	^MAStringDescription new
		priority: 100;
		label: 'Address';
		accessor: #address;
		visibleInReport: true;
		yourself

Now the address lines can be edited

Resulting in


-------------- next part --------------
Skipped content of type multipart/related


More information about the seaside mailing list