diff --git a/browser/configure.zcml b/browser/configure.zcml index 61e9645..b687024 100644 --- a/browser/configure.zcml +++ b/browser/configure.zcml @@ -603,16 +603,14 @@ for="loops.browser.node.NodeView zope.publisher.interfaces.browser.IBrowserRequest" factory="loops.browser.form.CreateConcept" - permission="zope.ManageContent" - /> + permission="zope.ManageContent" /> + permission="zope.ManageContent" /> diff --git a/browser/form.py b/browser/form.py index 0e10db8..d79e3e8 100644 --- a/browser/form.py +++ b/browser/form.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2008 Helmut Merz helmutm@cy55.de +# Copyright (c) 2009 Helmut Merz helmutm@cy55.de # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -115,6 +115,7 @@ class ObjectForm(NodeView): renderers['input_html'] = self.template.macros['input_html'] renderers['input_grid'] = grid_macros.macros['input_grid'] renderers['input_relationset'] = relation_macros.macros['input_relationset'] + renderers['input_relation'] = relation_macros.macros['input_relation'] return renderers @Lazy @@ -397,8 +398,7 @@ class CreateConceptPage(CreateConceptForm): @Lazy def nextUrl(self): - #return self.nodeView.getUrlForTarget(self.context) - return self.getUrlForTarget(self.context) + return self.getUrlForTarget(self.virtualTargetObject) class InnerForm(CreateObjectForm): diff --git a/browser/form_macros.pt b/browser/form_macros.pt index 8e31013..d160e44 100644 --- a/browser/form_macros.pt +++ b/browser/form_macros.pt @@ -189,8 +189,6 @@ - - diff --git a/browser/loops.js b/browser/loops.js index 8b0b7f2..adc8e47 100644 --- a/browser/loops.js +++ b/browser/loops.js @@ -147,11 +147,26 @@ function addRelation(fieldName) { valuesNode = dojo.byId(fieldName + '_values'); widget = dijit.byId(fieldName + '_search'); token = widget.getValue(); - title = widget.getDisplayedValue(); - ih = ' ' + title + ''; - newNode = document.createElement('div'); - newNode.innerHTML = ih; - valuesNode.appendChild(newNode); + if (token) { + title = widget.getDisplayedValue(); + ih = '
' + title + '
'; + newNode = document.createElement('div'); + newNode.innerHTML = ih; + valuesNode.appendChild(newNode); + } +} + +function setRelation(fieldName) { + valuesNode = dojo.byId(fieldName + '_values'); + widget = dijit.byId(fieldName + '_search'); + token = widget.getValue(); + if (token) { + title = widget.getDisplayedValue(); + ih = '
' + title + '
'; + newNode = document.createElement('div'); + newNode.innerHTML = ih; + valuesNode.replaceChild(newNode, valuesNode.firstChild); + } } function validate() { diff --git a/common.py b/common.py index 5724308..8ce0bfa 100644 --- a/common.py +++ b/common.py @@ -387,6 +387,16 @@ class RelationSetProperty(object): return self return self.factory(inst, self.predicateName) + def __set__(self, inst, value): + rs = self.factory(inst, self.predicateName) + current = list(rs) + for c in current: + if c not in value: + rs.remove(c) + for v in value: + if v not in current: + rs.add(v) + class ParentRelationSetProperty(RelationSetProperty): diff --git a/configure.zcml b/configure.zcml index 1511a81..3f9f9b2 100644 --- a/configure.zcml +++ b/configure.zcml @@ -345,6 +345,8 @@ name="grid" /> + diff --git a/schema/base.py b/schema/base.py index d4711f7..4de7b6b 100644 --- a/schema/base.py +++ b/schema/base.py @@ -24,13 +24,13 @@ $Id$ from zope.component import adapts from zope.interface import Attribute, implements -from zope.schema import Choice, List -from zope.schema.interfaces import IChoice, IList +from zope.schema import Field, List +from zope.schema.interfaces import IField, IList from cybertools.composer.schema.interfaces import FieldType -class IRelation(IChoice): +class IRelation(IField): """ An object addressed via a single relation. """ @@ -50,11 +50,14 @@ class IRelationSet(IList): 'targets for the relations.') -class Relation(Choice): +class Relation(Field): implements(IRelation) - __typeInfo__ = ('relation',) + __typeInfo__ = ('relation', + FieldType('relation', 'relation', + u'A field representing a related object.', + instanceName='relation')) def __init__(self, *args, **kw): self.target_types = kw.pop('target_types') diff --git a/schema/field.py b/schema/field.py index f799bc9..03f46ef 100644 --- a/schema/field.py +++ b/schema/field.py @@ -28,9 +28,10 @@ from zope.interface import implements from zope.app.pagetemplate import ViewPageTemplateFile from zope.cachedescriptors.property import Lazy import zope.schema +from zope.traversing.api import getName from cybertools.composer.schema.factory import createField -from cybertools.composer.schema.field import ListFieldInstance +from cybertools.composer.schema.field import FieldInstance, ListFieldInstance from cybertools.composer.schema.interfaces import IField, IFieldInstance from cybertools.composer.schema.interfaces import fieldTypes, undefined from cybertools.util.format import toStr, toUnicode @@ -41,17 +42,7 @@ from loops import util relation_macros = ViewPageTemplateFile('relation_macros.pt') -class RelationSetFieldInstance(ListFieldInstance): - - def marshall(self, value): - return [dict(title=v.title, uid=util.getUidForObject(v.context)) - for v in value] - - def display(self, value): - return value - - def unmarshall(self, value): - return value +class BaseRelationFieldInstance(object): @Lazy def typesParams(self): @@ -62,3 +53,40 @@ class RelationSetFieldInstance(ListFieldInstance): if result: return '?' + '&'.join(result) return '' + + def getPresetTargets(self, view): + if view.adapted.__is_dummy__: + # only for object in creation + target = view.virtualTargetObject + if getName(target.conceptType) in self.context.target_types: + return [dict(title=target.title, uid=util.getUidForObject(target))] + return [] + + +class RelationSetFieldInstance(ListFieldInstance, BaseRelationFieldInstance): + + def marshall(self, value): + return [dict(title=v.title, uid=util.getUidForObject(v.context)) + for v in value] + + def display(self, value): + return ' | '.join([v.title for v in value]) + + def unmarshall(self, value): + return [util.getObjectForUid(v) for v in value] + + +class RelationFieldInstance(FieldInstance, BaseRelationFieldInstance): + + def marshall(self, value): + if value: + return dict(title=value.title, uid=util.getUidForObject(value)) + + def display(self, value): + if value: + return value.title + return u'' + + def unmarshall(self, value): + return util.getObjectForUid(value) + diff --git a/schema/relation_macros.pt b/schema/relation_macros.pt index f0d1dda..a73a23c 100755 --- a/schema/relation_macros.pt +++ b/schema/relation_macros.pt @@ -17,6 +17,13 @@ value obj/uid" /> +
+ + +
+ +
+
+
+ + + + +
+
+ +
+ +