Thanks Iwan.
That makes a lot of sense.
I think where I'm stuck is that I was trying to use a transition (attached to a button) to go from a view mode to an Edit mode. I think that necessitates separate views since the views themselves are tied into the define_transition logic. Here's how I'd attempted to do that:
class ClientsUserInterface(UserInterface):
def assemble(self):
client_list = self.define_view('/',title='Clients')
client_list.set_slot('main',ClientListPanel.factory(self))
client_view = self.define_view('/view', view_class=ClientView,
title='View', client_id=IntegerField(required=True))
client_edit = self.define_view('/edit', view_class=EditClientView,
title='Edit', client_id=IntegerField(required=True))
self.define_transition(Client.events.save,client_edit,client_view)
self.define_transition(Client.events.cancel,client_edit,client_view)
self.define_transition(Client.events.edit,client_view,client_edit)
self.client_edit = client_edit
self.client_view = client_view
def get_edit_bookmark(self, client, description=None):
return self.client_edit.as_bookmark(self,
client_id=client.id, description='%s, %s'%(client.lastname,client.firstname))
def get_view_bookmark(self, client, description=None):
return self.client_view.as_bookmark(self,
client_id=client.id, description='%s, %s'%(client.lastname,client.firstname)) My end goal here is to create a form that's capable of editing, but doesn't permit it until someone clicks the "Edit" button -- call it a safety feature. I'd then tie security into the fields and/or into the button itself to add access control later.
p.s. I'm posting the whole file here. This is invoked as a child user interface.
#-------------------------------------------------------------------------------
#
from __future__ import print_function, unicode_literals, absolute_import, division
from sqlalchemy import Column, Integer, UnicodeText
from reahl.sqlalchemysupport import Session, Base
from reahl.web.fw import UserInterface, Widget, Url, UrlBoundView
from reahl.web.ui import HTML5Page, Panel, P, H, A, HorizontalLayout, VerticalLayout
from reahl.web.ui import Form, InputGroup, LabelledBlockInput, TextInput, Button, Table
from reahl.web.ui import TabbedPanel, Tab
from reahl.web.ui import StaticColumn, DynamicColumn
from reahl.web.table import DataTable
from reahl.component.modelinterface import exposed, EmailField, Field, Event, Action, IntegerField
#-------------------------------------------------------------------------------
# UI Definition
class ClientsUserInterface(UserInterface):
def assemble(self):
client_list = self.define_view('/',title='Clients')
client_list.set_slot('main',ClientListPanel.factory(self))
client_view = self.define_view('/view', view_class=ClientView,
title='View', client_id=IntegerField(required=True))
client_edit = self.define_view('/edit', view_class=EditClientView,
title='Edit', client_id=IntegerField(required=True))
self.define_transition(Client.events.save,client_edit,client_view)
self.define_transition(Client.events.cancel,client_edit,client_view)
self.define_transition(Client.events.edit,client_view,client_edit)
self.client_edit = client_edit
self.client_view = client_view
def get_edit_bookmark(self, client, description=None):
return self.client_edit.as_bookmark(self,
client_id=client.id, description='%s, %s'%(client.lastname,client.firstname))
def get_view_bookmark(self, client, description=None):
return self.client_view.as_bookmark(self,
client_id=client.id, description='%s, %s'%(client.lastname,client.firstname))
#-------------------------------------------------------------------------------
# List View
class ClientRow(object):
def __init__(self,client):
self.client = client
self.selected_by_user = False
@exposed
def fields(self, fields):
fields.selected_by_user = BooleanField(label='')
def __getattr__(self, name):
return getattr(self.client, name)
class ClientListPanel(Panel):
def __init__(self,view,clients_ui):
super(ClientListPanel,self).__init__(view)
self.rows = self.initialize_rows()
self.add_child(H(view,1,text='Clients'))
def make_link_widget(view,row):
return A.from_bookmark(view,clients_ui.get_view_bookmark(row.client))
columns = [
DynamicColumn('Name', make_link_widget, sort_key=lambda x: x.lastname),
StaticColumn(EmailField(label='Email'),'email_address',sort_key=lambda x: x.client.email_address)
]
data_table = DataTable(view, columns, self.rows, caption_text='All Clients',
summary='Summary for screen reader',css_id='address_data')
self.add_child(data_table)
def initialize_rows(self):
return [ClientRow(client) for client in Session.query(Client).all()]
#-------------------------------------------------------------------------------
# Client View