Curious: I have a content type that is supposed to 'auto fill certain fields' when something is selected. For example, if 'meeting type' is "Zoom", it would auto fill 'field A' with value A1 and field B with value B1. If 'meeting type' is 'Something else', it would fill field A with value A2 and field B with value B2.
Could this be done another way (for example: From menu, choose 'Add Meeting', then show dialog 'meeting type', then add Meeting with prefilled fields.
I assume 'just making a form' would work, but before I 'try': Has anyone else done this?
you can register your own second formview for the immediate_view
In the schema definition is the option available and per default set to the display view.
You could register your custom ++add++ view for your content type like this:
<!-- Standard add view and form - invoked from ++add++ traverser -->
<adapter
factory=".add.CustomAddView"
provides="zope.publisher.interfaces.browser.IBrowserPage"
for="Products.CMFCore.interfaces.IFolderish
zope.publisher.interfaces.browser.IDefaultBrowserLayer
my.package.interfaces.MyType"
/>
<class class=".add.DefaultAddView">
<require
permission="cmf.YourAddView"
interface="zope.publisher.interfaces.browser.IBrowserPage"
/>
</class>
and in your CustomAddView call check for a query parameter (lets say subtype)
if subtype is not given you return a template with a selector which will call ++add++MyType?subtype=xyz in the next step ... then you can inject predefined values into the request which will be filled in your addform ... just a quick idea...
If I understand you right: I could (should) 'use the same AddView' (browser view) after 'save' (for example: hide all 'groups' / fieldset / description etc, showing just one field?
This approach seems to work great, to test it I made this (which adds text to description based on field value)
UPDATE: My first approach did NOT work. It seems like the meeting type value is 'stored in the widget' until next 'add', so when I add 'Meeting no 2', it will use 'Meeting no 1' data to populate the description field, so it is neccessarty to set the value of the widget, not the field.
So probably this should work:
class MeetingCustomAddForm(DefaultAddForm):
def __init__(self, context, request):
super(MeetingCustomAddForm, self).__init__(context, request)
def updateWidgets(self):
super(MeetingCustomAddForm, self).updateWidgets()
#To do: set correct empty value according to field type
if self.widgets['meeting_type'].value in [(), None, '']:
for widgetname in self.widgets:
if widgetname != 'meeting_type':
self.widgets[widgetname].mode = interfaces.HIDDEN_MODE
else:
if self.widgets['meeting_type'].value != None:
self.widgets['IBasic.title'].value = f"Meeting {self.widgets['meeting_type'].value[0]}" >
def updateFields(self):
super(MeetingCustomAddForm, self).updateFields()
def update(self):
super(MeetingCustomAddForm, self).update()
class MeetingCustomAddFormView(DefaultAddView):
form = MeetingCustomAddForm