work in progress: preparing dojo dialog forms for implementing validation
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1965 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
4ccf4d033c
commit
4d645cc695
4 changed files with 68 additions and 16 deletions
|
@ -43,7 +43,7 @@ from cybertools.browser.form import FormController
|
|||
from cybertools.typology.interfaces import IType, ITypeManager
|
||||
from loops.concept import ResourceRelation
|
||||
from loops.interfaces import IConcept, IResourceManager, IDocument
|
||||
from loops.interfaces import IFile, IExternalFile, INote
|
||||
from loops.interfaces import IFile, IExternalFile, INote, ITextDocument
|
||||
from loops.browser.node import NodeView
|
||||
from loops.browser.concept import ConceptRelationView
|
||||
from loops.query import ConceptQuery
|
||||
|
@ -80,10 +80,14 @@ class ObjectForm(NodeView):
|
|||
|
||||
template = ViewPageTemplateFile('form_macros.pt')
|
||||
|
||||
_isSetUp = False
|
||||
|
||||
def __init__(self, context, request):
|
||||
super(ObjectForm, self).__init__(context, request)
|
||||
|
||||
def setUp(self):
|
||||
if self._isSetUp:
|
||||
return
|
||||
self.setUpWidgets()
|
||||
desc = self.widgets.get('description')
|
||||
if desc:
|
||||
|
@ -91,6 +95,7 @@ class ObjectForm(NodeView):
|
|||
if self.typeInterface in widgetControllers:
|
||||
wc = widgetControllers[self.typeInterface](self.context, self.request)
|
||||
wc.modifyWidgetSetup(self.widgets)
|
||||
self._isSetUp = True
|
||||
|
||||
def __call__(self):
|
||||
response = self.request.response
|
||||
|
@ -175,6 +180,7 @@ class EditObjectForm(ObjectForm, EditForm):
|
|||
|
||||
def __init__(self, context, request):
|
||||
super(EditObjectForm, self).__init__(context, request)
|
||||
self.url = self.url # keep virtual target URL
|
||||
self.context = self.virtualTargetObject
|
||||
|
||||
@Lazy
|
||||
|
@ -213,7 +219,8 @@ class CreateObjectForm(ObjectForm, Form):
|
|||
t = self.loopsRoot.loopsTraverse(typeToken)
|
||||
ifc = removeSecurityProxy(ITypeConcept(t).typeInterface)
|
||||
else:
|
||||
ifc = INote
|
||||
#ifc = INote
|
||||
ifc = ITextDocument
|
||||
self.typeInterface = ifc
|
||||
ff = FormFields(ifc)
|
||||
#ff['data'].custom_widget = UploadWidget
|
||||
|
@ -256,16 +263,21 @@ class EditObject(FormController):
|
|||
# make sure new version is used by the view
|
||||
self.view.virtualTargetObject = obj
|
||||
self.request.annotations['loops.view']['target'] = obj
|
||||
self.updateFields(obj)
|
||||
errors = self.updateFields(obj)
|
||||
if errors:
|
||||
self.view.setUp()
|
||||
for fieldName, message in errors.items():
|
||||
self.view.widgets[fieldName].error = message
|
||||
return True
|
||||
self.request.response.redirect(self.view.virtualTargetUrl + '?version=this')
|
||||
return False
|
||||
#return True
|
||||
|
||||
@Lazy
|
||||
def loopsRoot(self):
|
||||
return self.view.loopsRoot
|
||||
|
||||
def updateFields(self, obj):
|
||||
errors = {}
|
||||
form = self.request.form
|
||||
ti = IType(obj).typeInterface
|
||||
if ti is not None:
|
||||
|
@ -273,6 +285,7 @@ class EditObject(FormController):
|
|||
else:
|
||||
adapted = obj
|
||||
for k in form.keys():
|
||||
# TODO: use self.view.form_fields
|
||||
if k.startswith(self.prefix):
|
||||
fn = k[len(self.prefix):]
|
||||
if fn in ('action', 'type', 'data.used') or fn.endswith('-empty-marker'):
|
||||
|
@ -295,10 +308,16 @@ class EditObject(FormController):
|
|||
self.request.form['form.contentType'] = ct
|
||||
adapted.contentType = ct
|
||||
adapted.localFilename = filename
|
||||
setattr(adapted, fn, value)
|
||||
if fn == 'title' and not value:
|
||||
# TODO: provide general validation mechanism
|
||||
errors[fn] = 'Field %s must not be empty' % fn
|
||||
else:
|
||||
# TODO: provide unmarshalling depending on field type
|
||||
setattr(adapted, fn, value)
|
||||
if self.old or self.selected:
|
||||
self.assignConcepts(obj)
|
||||
notify(ObjectModifiedEvent(obj))
|
||||
return errors
|
||||
|
||||
def collectConcepts(self, fieldName, value):
|
||||
if self.old is None: self.old = []
|
||||
|
@ -361,5 +380,4 @@ class CreateObject(EditObject):
|
|||
self.updateFields(obj)
|
||||
self.request.response.redirect(self.view.virtualTargetUrl)
|
||||
return False
|
||||
#return True
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
$Id$ -->
|
||||
|
||||
<metal:block define-macro="edit" i18n:domain="loops">
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<form method="post" enctype="multipart/form-data" id="dialog_form">
|
||||
<input type="hidden" name="form.action" value="edit"
|
||||
tal:attributes="value view/form_action" />
|
||||
<input type="hidden" name="version"
|
||||
|
@ -55,7 +55,7 @@
|
|||
tal:attributes="value type/token;
|
||||
selected python:
|
||||
type.token == (request.get('form.type')
|
||||
or '.loops/concepts/note')">
|
||||
or '.loops/concepts/textdocument')">
|
||||
Note
|
||||
</option>
|
||||
</select>
|
||||
|
@ -81,8 +81,11 @@
|
|||
</metal:block>
|
||||
|
||||
|
||||
<metal:fields define-macro="fields">
|
||||
<tal:block tal:define="dummy view/setUp">
|
||||
<metal:fields define-macro="fields"
|
||||
tal:define="show view/update">
|
||||
<tal:show condition="show">
|
||||
<div id="form_fields"
|
||||
tal:define="dummy view/setUp">
|
||||
<table width="100%">
|
||||
<tr tal:repeat="widget view/widgets">
|
||||
<td class="label" width="10%"
|
||||
|
@ -104,7 +107,8 @@
|
|||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</tal:block>
|
||||
</div>
|
||||
</tal:show>
|
||||
</metal:fields>
|
||||
|
||||
|
||||
|
@ -205,8 +209,12 @@
|
|||
<tr metal:define-macro="buttons" i18n:domain="">
|
||||
<td colspan="5"
|
||||
tal:define="dlgName view/dialog_name">
|
||||
<input type="submit" value="Save" onClick="dlg.hide()" class="submit"
|
||||
<input value="Save" type="submit"
|
||||
i18n:attributes="value"
|
||||
xtal:attributes="onClick
|
||||
string:return submitReplacingOrReloading(
|
||||
'form_fields', 'dialog_form',
|
||||
'${view/virtualTargetUrl}/@@inner_form.html')"
|
||||
tal:attributes="onClick string:dialogs['$dlgName'].hide()">
|
||||
<input type="button" value="Cancel" onClick="dlg.hide();"
|
||||
i18n:attributes="value"
|
||||
|
|
|
@ -28,6 +28,28 @@ function submitReplacing(targetId, formId, actionUrl) {
|
|||
return false;
|
||||
}
|
||||
|
||||
function submitReplacingOrReloading(targetId, formId, actionUrl) {
|
||||
node = dojo.byId(targetId);
|
||||
var args = {
|
||||
url: actionUrl,
|
||||
formNode: dojo.byId(formId),
|
||||
method: 'post',
|
||||
mimetype: "text/html"
|
||||
};
|
||||
args.load = function (t, d, e) {
|
||||
if (d.length < 10) {
|
||||
document.location.reload(false);
|
||||
} else {
|
||||
while (node.firstChild) {
|
||||
dojo.dom.destroyNode(node.firstChild);
|
||||
}
|
||||
node.innerHTML = d;
|
||||
}
|
||||
};
|
||||
dojo.io.bind(args);
|
||||
return false;
|
||||
}
|
||||
|
||||
function inlineEdit(id, saveUrl) {
|
||||
var iconNode = dojo.byId('inlineedit_icon');
|
||||
iconNode.style.visibility = 'hidden';
|
||||
|
|
|
@ -220,18 +220,22 @@
|
|||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="#" i18n:translate=""
|
||||
<a href="create_object.html" i18n:translate=""
|
||||
onclick="objectDialog('create', 'create_object.html'); return false;"
|
||||
tal:attributes="onclick string:objectDialog('create', '$url/create_object.html');; return false;;">
|
||||
tal:attributes="onClick
|
||||
string:objectDialog('create', '$url/create_object.html');;
|
||||
return false;;">
|
||||
Create Resource...
|
||||
</a>
|
||||
</div>
|
||||
<div tal:condition="view/hasEditableTarget">
|
||||
<a href="#" i18n:translate=""
|
||||
<a href="edit_object.html" i18n:translate=""
|
||||
onclick="objectDialog('edit', 'edit_object.html'); return false;"
|
||||
tal:define="version request/version|nothing;
|
||||
versionPar python: version and '?version=' + version or ''"
|
||||
tal:attributes="onclick string:objectDialog('edit', '$url/edit_object.html$versionPar');; return false;;">
|
||||
tal:attributes="onClick
|
||||
string:objectDialog('edit', '$url/edit_object.html$versionPar');;
|
||||
return false;;">
|
||||
Edit Resource...
|
||||
</a>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue