The answer... Thanks to Damien for pointing me in the right direction.
>From your controller you can pass to the form either a SQLAlchemy ORM
object,
or a dictionary. However, if one of the form fields is a
MultipleSelectField,
then to pre-select values in that field, you need to pass a
dictionary, where
the value for the MultipleSelectField is a list strings. The
MultipleSelectField
does not understand how to traverse the ORM object into a relation
and get the right values.
However, if the relation is put not into a MultipleSelectField but
rather
a tw.dynforms.GrowingTableFieldSet, then the ORM object works. The
GrowingTableFieldSet understands that it needs to get the data from
the
ORM object's relation.
Here's the code to convert the ORM object to a dictionary, and handle
both the MultipleSelectField (which in this example is the
insertionSite
field in the location relation in Sample), and the
GrowingTableFieldSet
(which is the neuron relation in Sample, which in turn has several
fields).
Controller:
tmpl_context.sample_form = sample_form.update_sample_form
# Retrieve the sample with "sampleNumber" from the database.
sample =
DBSession.query(Sample).filter_by(sampleNumber=sampleNumber).one()
# Convert the retrieved ORM object to a dictionary.
formData = sample.__dict__
# Convert location to a list of strings.
formData['location'] = [ll.insertionSite for ll in
sample.location]
# Convert neuron to a list of dictionaries.
formData['neuron'] = [nn.__dict__ for nn in sample.neuron]
# Pass the dictionary to the form in the template.
return dict(sample=formData)
Template:
<div py:replace="tmpl_context.sample_form(sample)">Input Form</
div>
-- Matthew
On Aug 10, 4:07 pm, Matthew Cahn <[email protected]> wrote:
> Well, I now have a couple of values pre-selected, like this:
>
> Controller:
>
> IdPrefilledData = {'location' : ('option 1', 'option 2')}
>
> return dict(IdPrefilledData=
> IdPrefilledData)
>
> Template:
>
> <div py:replace="tmpl_context.sample_form(IdPrefilledData)">Input
> Form</div>
>
> That gives me only the location MultipleSelectField pre-selected, and the
> rest of the form is not filled out,
> because I"m no longer passing in the Sample ORM object. How do I pass both
> the pre-selections for location
> and the ORM object?
>
> On Wed, Aug 10, 2011 at 10:48 AM, Damien Accorsi
> <[email protected]>wrote:
>
>
>
>
>
>
>
> > **
> > Ok. So... did you succeed in pre-selecting several values ?
>
> > Le 10/08/2011 16:29, Matthew Cahn a écrit :
>
> > Well, it's a thought, but despite the fact that I called the options of the
> > select "option 1", "option 2", and "option 3" in my posting, it's a real
> > project, and the item in the MultipleSelectField needs to allow multiple
> > responses.
>
> > Matthew
>
> > On Tue, Aug 9, 2011 at 3:15 PM, Damien Accorsi
> > <[email protected]>wrote:
>
> >> By the way, if you are new to Tosca Widgets, I would recommend to start
> >> by using "simple" widgets like TextField, SingleSelectField, etc. The
> >> mechanisms are not always easy to understand, so the firsts steps should be
> >> to use simple widgets with static data, then go into complex widgets with
> >> dynamic data.
>
> >> Le 09/08/2011 21:11, Damien Accorsi a écrit :
>
> >> Matthew,
>
> >> In your templates you should have something like this:
> >> ${tmpl_context.sample_form(ldPrefilledData, child_args=ldChildArgs)}
>
> >> Where :
> >> * ldPrefilledData is a dictionnary containing the preselected values
> >> * ldChildArgs is a dictionnary containing the available values
>
> >> In your case, you should have something like:
> >> * ldChildArgs = { 'location': {'option 1', 'option 2', 'option 3'}}
> >> * ldPrefilledData = { 'location': {'option 1', 'option 2'}}
>
> >> This should work.
>
> >> Damien
>
> >> Le 09/08/2011 20:40, MHCPU a écrit :
>
> >> I hope someone will tell me how to pass which options are selected
> >> into a MultipleSelectField. I can see that the values being passed
> >> into update_params is a list of SQLAlchemy ORM objects. It seems like
> >> it needs to be a list of strings instead, but I'm not sure how to make
> >> that happen.
>
> >> Matthew
>
> >> On Aug 9, 11:19 am, MHCPU <[email protected]>
> >> <[email protected]> wrote:
>
> >> Could someone tell me how to get the selections in a
> >> MultipleSelectField to reflect the values coming from the database?
> >> The selections get saved to the database fine, but they don't get set
> >> in the form when I give the form an existing set of data.
>
> >> For example, I have a Sample table, with a one-to-many relation to the
> >> Location table. If the Location table has two records, with the
> >> "some_attribute" field having the values "option 1" and "option 2", I
> >> want those two options to be selected in the MultipleSelectField for
> >> "some_attribute" when I display the form.
>
> >> I'm not sure how the MultipleFieldSelect would even know that the data
> >> is supposed to come from the "some_attribute" field of the Location
> >> table, which is probably why it doesn't work. When I create the
> >> Sample object for insertion to the database, I have to make a list of
> >> Location objects and assign them to the new Sample. Do I have to do
> >> the reverse when I get a Sample from the database, in order to pass a
> >> list to the form? How would I pass it?
>
> >> Any help appreciated.
>
> >> - Matthew
>
> >> Tables:
>
> >> class Sample(DeclarativeBase):
> >> __tablename__ = 'sample'
> >> id = Column(Integer, primary_key=True)
> >> sampleNumber = Column(Unicode, index=True, unique=True,
> >> nullable=False)
> >> location = relation('Location', backref='sample',
> >> order_by='Location.id')
>
> >> class Location(DeclarativeBase):
> >> __tablename__ = 'location'
> >> id = Column(Integer, primary_key=True)
> >> sample_id = Column(Unicode, ForeignKey('sample.id'))
> >> some_attribute = Column(Unicode)
>
> >> Form:
>
> >> class SampleForm(TableForm, twd.CustomisedForm):
> >> ...
> >> location = MultipleSelectField('some_attribute',
> >> options=['option 1', 'option 2', 'option 3'])
>
> >> Controller:
>
> >> class RootController(BaseController):
>
> >> @validate(sample_form.create_sample_form, error_handler=create)
> >> @expose()
> >> def create_sample(self, **kw):
> >> """Create a new sample record"""
>
> >> locationList = []
> >> for ll in kw['location']:
> >> newLocation = Location(some_attribute=ll)
> >> locationList.append(newLocation)
>
> >> new = Sample(
> >> sampleNumber = kw['sampleNumber'],
> >> location = locationList,
> >> )
>
> >> DBSession.add(new)
>
> >> flash( '''Added sample: %s'''%( kw['sampleNumber'], ))
> >> redirect( './index' )
>
> >> @expose('myproject.templates.update')
> >> def update(self, sampleNumber, **kw):
> >> """Display the form for updating a sample, with values from
> >> the database."""
>
> >> tmpl_context.sample_form = sample_form.update_sample_form
>
> >> sample =
> >> DBSession.query(Sample).filter_by(sampleNumber=sampleNumber).one()
>
> >> return dict(sample=sample)
>
> >> --
> >> You received this message because you are subscribed to the Google Groups
> >> "TurboGears" group.
> >> To post to this group, send email to [email protected].
> >> To unsubscribe from this group, send email to
> >> [email protected].
> >> For more options, visit this group at
> >>http://groups.google.com/group/turbogears?hl=en.
--
You received this message because you are subscribed to the Google Groups
"TurboGears" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/turbogears?hl=en.