Add basic support for "mobile edit" of records
specifically need to allow this for Customer records, for one app
This commit is contained in:
parent
37a8bfd6f5
commit
b0b551af82
|
@ -42,3 +42,7 @@ ${form.render()|n}
|
||||||
<br />
|
<br />
|
||||||
${grid.render_complete()|n}
|
${grid.render_complete()|n}
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
|
% if master.mobile_editable and instance_editable and request.has_perm('{}.edit'.format(permission_prefix)):
|
||||||
|
${h.link_to("Edit This", url('mobile.{}.edit'.format(route_prefix), uuid=instance.uuid), class_='ui-btn ui-corner-all')}
|
||||||
|
% endif
|
||||||
|
|
|
@ -223,7 +223,9 @@ class CustomersView(MasterView):
|
||||||
f.set_renderer('groups', self.render_groups)
|
f.set_renderer('groups', self.render_groups)
|
||||||
f.set_readonly('groups')
|
f.set_readonly('groups')
|
||||||
|
|
||||||
def objectify(self, form, data):
|
def objectify(self, form, data=None):
|
||||||
|
if data is None:
|
||||||
|
data = form.validated
|
||||||
customer = super(CustomersView, self).objectify(form, data)
|
customer = super(CustomersView, self).objectify(form, data)
|
||||||
customer = self.objectify_contact(customer, data)
|
customer = self.objectify_contact(customer, data)
|
||||||
return customer
|
return customer
|
||||||
|
|
|
@ -195,7 +195,9 @@ class EmployeesView(MasterView):
|
||||||
if not self.viewing:
|
if not self.viewing:
|
||||||
f.remove_fields('first_name', 'last_name')
|
f.remove_fields('first_name', 'last_name')
|
||||||
|
|
||||||
def objectify(self, form, data):
|
def objectify(self, form, data=None):
|
||||||
|
if data is None:
|
||||||
|
data = form.validated
|
||||||
employee = super(EmployeesView, self).objectify(form, data)
|
employee = super(EmployeesView, self).objectify(form, data)
|
||||||
self.update_stores(employee, data)
|
self.update_stores(employee, data)
|
||||||
self.update_departments(employee, data)
|
self.update_departments(employee, data)
|
||||||
|
|
|
@ -100,6 +100,7 @@ class MasterView(View):
|
||||||
|
|
||||||
supports_mobile = False
|
supports_mobile = False
|
||||||
mobile_creatable = False
|
mobile_creatable = False
|
||||||
|
mobile_editable = False
|
||||||
mobile_pageable = True
|
mobile_pageable = True
|
||||||
mobile_filterable = False
|
mobile_filterable = False
|
||||||
mobile_executable = False
|
mobile_executable = False
|
||||||
|
@ -1111,7 +1112,7 @@ class MasterView(View):
|
||||||
context = {
|
context = {
|
||||||
'instance': instance,
|
'instance': instance,
|
||||||
'instance_title': self.get_instance_title(instance),
|
'instance_title': self.get_instance_title(instance),
|
||||||
# 'instance_editable': self.editable_instance(instance),
|
'instance_editable': self.editable_instance(instance),
|
||||||
# 'instance_deletable': self.deletable_instance(instance),
|
# 'instance_deletable': self.deletable_instance(instance),
|
||||||
'form': form,
|
'form': form,
|
||||||
}
|
}
|
||||||
|
@ -1199,12 +1200,12 @@ class MasterView(View):
|
||||||
self.configure_common_form(form)
|
self.configure_common_form(form)
|
||||||
|
|
||||||
def validate_mobile_form(self, form):
|
def validate_mobile_form(self, form):
|
||||||
controls = self.request.POST.items()
|
if form.validate(newstyle=True):
|
||||||
try:
|
# TODO: deprecate / remove self.form_deserialized
|
||||||
self.form_deserialized = form.validate(controls)
|
self.form_deserialized = form.validated
|
||||||
except deform.ValidationFailure:
|
|
||||||
return False
|
|
||||||
return True
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
def make_mobile_row_form(self, instance=None, factory=None, fields=None, schema=None, **kwargs):
|
def make_mobile_row_form(self, instance=None, factory=None, fields=None, schema=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -1535,15 +1536,61 @@ class MasterView(View):
|
||||||
context['dform'] = form.make_deform_form()
|
context['dform'] = form.make_deform_form()
|
||||||
return self.render_to_response('edit', context)
|
return self.render_to_response('edit', context)
|
||||||
|
|
||||||
|
def mobile_edit(self):
|
||||||
|
"""
|
||||||
|
Mobile view for editing an existing model record.
|
||||||
|
"""
|
||||||
|
self.mobile = True
|
||||||
|
self.editing = True
|
||||||
|
obj = self.get_instance()
|
||||||
|
|
||||||
|
if not self.editable_instance(obj):
|
||||||
|
msg = "Edit is not permitted for {}: {}".format(
|
||||||
|
self.get_model_title(),
|
||||||
|
self.get_instance_title(obj))
|
||||||
|
self.request.session.flash(msg, 'error')
|
||||||
|
return self.redirect(self.get_action_url('view', obj))
|
||||||
|
|
||||||
|
form = self.make_mobile_form(obj)
|
||||||
|
|
||||||
|
if self.request.method == 'POST':
|
||||||
|
if self.validate_mobile_form(form):
|
||||||
|
|
||||||
|
# note that save_form() may return alternate object
|
||||||
|
obj = self.save_mobile_edit_form(form)
|
||||||
|
|
||||||
|
msg = "{} has been updated: {}".format(
|
||||||
|
self.get_model_title(),
|
||||||
|
self.get_instance_title(obj))
|
||||||
|
self.request.session.flash(msg)
|
||||||
|
return self.redirect_after_edit(obj, mobile=True)
|
||||||
|
|
||||||
|
context = {
|
||||||
|
'instance': obj,
|
||||||
|
'instance_title': self.get_instance_title(obj),
|
||||||
|
'instance_deletable': self.deletable_instance(obj),
|
||||||
|
'instance_url': self.get_action_url('view', obj, mobile=True),
|
||||||
|
'form': form,
|
||||||
|
}
|
||||||
|
if hasattr(form, 'make_deform_form'):
|
||||||
|
context['dform'] = form.make_deform_form()
|
||||||
|
return self.render_to_response('edit', context, mobile=True)
|
||||||
|
|
||||||
def save_edit_form(self, form):
|
def save_edit_form(self, form):
|
||||||
|
if not self.mobile:
|
||||||
uploads = self.normalize_uploads(form)
|
uploads = self.normalize_uploads(form)
|
||||||
obj = self.objectify(form, self.form_deserialized)
|
obj = self.objectify(form)
|
||||||
|
if not self.mobile:
|
||||||
self.process_uploads(obj, form, uploads)
|
self.process_uploads(obj, form, uploads)
|
||||||
self.after_edit(obj)
|
self.after_edit(obj)
|
||||||
self.Session.flush()
|
self.Session.flush()
|
||||||
|
return obj
|
||||||
|
|
||||||
def redirect_after_edit(self, instance):
|
def save_mobile_edit_form(self, form):
|
||||||
return self.redirect(self.get_action_url('view', instance))
|
return self.save_edit_form(form)
|
||||||
|
|
||||||
|
def redirect_after_edit(self, instance, mobile=False):
|
||||||
|
return self.redirect(self.get_action_url('view', instance, mobile=mobile))
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
"""
|
"""
|
||||||
|
@ -3286,12 +3333,17 @@ class MasterView(View):
|
||||||
"Download associated data for {}".format(model_title))
|
"Download associated data for {}".format(model_title))
|
||||||
|
|
||||||
# edit
|
# edit
|
||||||
|
if cls.editable or cls.mobile_editable:
|
||||||
|
config.add_tailbone_permission(permission_prefix, '{}.edit'.format(permission_prefix),
|
||||||
|
"Edit {}".format(model_title))
|
||||||
if cls.editable:
|
if cls.editable:
|
||||||
config.add_route('{0}.edit'.format(route_prefix), '{0}/{{{1}}}/edit'.format(url_prefix, model_key))
|
config.add_route('{}.edit'.format(route_prefix), '{}/{{{}}}/edit'.format(url_prefix, model_key))
|
||||||
config.add_view(cls, attr='edit', route_name='{0}.edit'.format(route_prefix),
|
config.add_view(cls, attr='edit', route_name='{}.edit'.format(route_prefix),
|
||||||
permission='{0}.edit'.format(permission_prefix))
|
permission='{}.edit'.format(permission_prefix))
|
||||||
config.add_tailbone_permission(permission_prefix, '{0}.edit'.format(permission_prefix),
|
if cls.mobile_editable:
|
||||||
"Edit {0}".format(model_title))
|
config.add_route('mobile.{}.edit'.format(route_prefix), '/mobile{}/{{{}}}/edit'.format(url_prefix, model_key))
|
||||||
|
config.add_view(cls, attr='mobile_edit', route_name='mobile.{}.edit'.format(route_prefix),
|
||||||
|
permission='{}.edit'.format(permission_prefix))
|
||||||
|
|
||||||
# execute
|
# execute
|
||||||
if cls.executable or cls.mobile_executable:
|
if cls.executable or cls.mobile_executable:
|
||||||
|
|
|
@ -238,7 +238,9 @@ class MessagesView(MasterView):
|
||||||
elif self.viewing:
|
elif self.viewing:
|
||||||
f.remove('body')
|
f.remove('body')
|
||||||
|
|
||||||
def objectify(self, form, data):
|
def objectify(self, form, data=None):
|
||||||
|
if data is None:
|
||||||
|
data = form.validated
|
||||||
message = super(MessagesView, self).objectify(form, data)
|
message = super(MessagesView, self).objectify(form, data)
|
||||||
|
|
||||||
if self.creating:
|
if self.creating:
|
||||||
|
|
|
@ -106,7 +106,9 @@ class RolesView(PrincipalMasterView):
|
||||||
return ""
|
return ""
|
||||||
return six.text_type(role.session_timeout)
|
return six.text_type(role.session_timeout)
|
||||||
|
|
||||||
def objectify(self, form, data):
|
def objectify(self, form, data=None):
|
||||||
|
if data is None:
|
||||||
|
data = form.validated
|
||||||
role = super(RolesView, self).objectify(form, data)
|
role = super(RolesView, self).objectify(form, data)
|
||||||
role.permissions = data['permissions']
|
role.permissions = data['permissions']
|
||||||
return role
|
return role
|
||||||
|
|
|
@ -229,7 +229,7 @@ class UsersView(PrincipalMasterView):
|
||||||
.filter(~model.Role.uuid.in_(excluded))\
|
.filter(~model.Role.uuid.in_(excluded))\
|
||||||
.order_by(model.Role.name)
|
.order_by(model.Role.name)
|
||||||
|
|
||||||
def objectify(self, form, data):
|
def objectify(self, form, data=None):
|
||||||
|
|
||||||
# create/update user as per normal
|
# create/update user as per normal
|
||||||
if data is None:
|
if data is None:
|
||||||
|
|
4
tailbone/views/vendors/core.py
vendored
4
tailbone/views/vendors/core.py
vendored
|
@ -114,7 +114,9 @@ class VendorsView(MasterView):
|
||||||
f.set_readonly('contact')
|
f.set_readonly('contact')
|
||||||
f.set_renderer('contact', self.render_contact)
|
f.set_renderer('contact', self.render_contact)
|
||||||
|
|
||||||
def objectify(self, form, data):
|
def objectify(self, form, data=None):
|
||||||
|
if data is None:
|
||||||
|
data = form.validated
|
||||||
vendor = super(VendorsView, self).objectify(form, data)
|
vendor = super(VendorsView, self).objectify(form, data)
|
||||||
vendor = self.objectify_contact(vendor, data)
|
vendor = self.objectify_contact(vendor, data)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue