provide implementation for relation set and relation field types
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3184 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
87cb629f1c
commit
40b8182f06
9 changed files with 118 additions and 31 deletions
|
@ -603,16 +603,14 @@
|
||||||
for="loops.browser.node.NodeView
|
for="loops.browser.node.NodeView
|
||||||
zope.publisher.interfaces.browser.IBrowserRequest"
|
zope.publisher.interfaces.browser.IBrowserRequest"
|
||||||
factory="loops.browser.form.CreateConcept"
|
factory="loops.browser.form.CreateConcept"
|
||||||
permission="zope.ManageContent"
|
permission="zope.ManageContent" />
|
||||||
/>
|
|
||||||
|
|
||||||
<zope:adapter
|
<zope:adapter
|
||||||
name="edit_concept"
|
name="edit_concept"
|
||||||
for="loops.browser.node.NodeView
|
for="loops.browser.node.NodeView
|
||||||
zope.publisher.interfaces.browser.IBrowserRequest"
|
zope.publisher.interfaces.browser.IBrowserRequest"
|
||||||
factory="loops.browser.form.EditConcept"
|
factory="loops.browser.form.EditConcept"
|
||||||
permission="zope.ManageContent"
|
permission="zope.ManageContent" />
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- inner HTML views -->
|
<!-- inner HTML views -->
|
||||||
|
|
||||||
|
|
|
@ -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
|
# 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
|
# 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_html'] = self.template.macros['input_html']
|
||||||
renderers['input_grid'] = grid_macros.macros['input_grid']
|
renderers['input_grid'] = grid_macros.macros['input_grid']
|
||||||
renderers['input_relationset'] = relation_macros.macros['input_relationset']
|
renderers['input_relationset'] = relation_macros.macros['input_relationset']
|
||||||
|
renderers['input_relation'] = relation_macros.macros['input_relation']
|
||||||
return renderers
|
return renderers
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
|
@ -397,8 +398,7 @@ class CreateConceptPage(CreateConceptForm):
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def nextUrl(self):
|
def nextUrl(self):
|
||||||
#return self.nodeView.getUrlForTarget(self.context)
|
return self.getUrlForTarget(self.virtualTargetObject)
|
||||||
return self.getUrlForTarget(self.context)
|
|
||||||
|
|
||||||
|
|
||||||
class InnerForm(CreateObjectForm):
|
class InnerForm(CreateObjectForm):
|
||||||
|
|
|
@ -189,8 +189,6 @@
|
||||||
</metal:assignments>
|
</metal:assignments>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<metal:versioning define-macro="versioning"
|
<metal:versioning define-macro="versioning"
|
||||||
tal:define="versionInfo view/versionInfo"
|
tal:define="versionInfo view/versionInfo"
|
||||||
tal:condition="versionInfo">
|
tal:condition="versionInfo">
|
||||||
|
|
|
@ -147,12 +147,27 @@ function addRelation(fieldName) {
|
||||||
valuesNode = dojo.byId(fieldName + '_values');
|
valuesNode = dojo.byId(fieldName + '_values');
|
||||||
widget = dijit.byId(fieldName + '_search');
|
widget = dijit.byId(fieldName + '_search');
|
||||||
token = widget.getValue();
|
token = widget.getValue();
|
||||||
|
if (token) {
|
||||||
title = widget.getDisplayedValue();
|
title = widget.getDisplayedValue();
|
||||||
ih = '<input type="checkbox" name="' + name + ':list" value="' + token + '" checked> <span>' + title + '</span>';
|
ih = '<div><input type="checkbox" name="' + fieldName + ':list" value="' + token + '" checked> <span>' + title + '</span></div>';
|
||||||
newNode = document.createElement('div');
|
newNode = document.createElement('div');
|
||||||
newNode.innerHTML = ih;
|
newNode.innerHTML = ih;
|
||||||
valuesNode.appendChild(newNode);
|
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 = '<div><input type="checkbox" name="' + fieldName + '" value="' + token + '" checked> <span>' + title + '</span></div>';
|
||||||
|
newNode = document.createElement('div');
|
||||||
|
newNode.innerHTML = ih;
|
||||||
|
valuesNode.replaceChild(newNode, valuesNode.firstChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function validate() {
|
function validate() {
|
||||||
//var form = dijit.byId('dialog_form');
|
//var form = dijit.byId('dialog_form');
|
||||||
|
|
10
common.py
10
common.py
|
@ -387,6 +387,16 @@ class RelationSetProperty(object):
|
||||||
return self
|
return self
|
||||||
return self.factory(inst, self.predicateName)
|
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):
|
class ParentRelationSetProperty(RelationSetProperty):
|
||||||
|
|
||||||
|
|
|
@ -345,6 +345,8 @@
|
||||||
name="grid" />
|
name="grid" />
|
||||||
<adapter factory="loops.schema.field.RelationSetFieldInstance"
|
<adapter factory="loops.schema.field.RelationSetFieldInstance"
|
||||||
name="relationset" />
|
name="relationset" />
|
||||||
|
<adapter factory="loops.schema.field.RelationFieldInstance"
|
||||||
|
name="relation" />
|
||||||
|
|
||||||
<adapter factory="cybertools.composer.schema.factory.SchemaFactory" />
|
<adapter factory="cybertools.composer.schema.factory.SchemaFactory" />
|
||||||
<adapter factory="loops.schema.factory.ResourceSchemaFactory" />
|
<adapter factory="loops.schema.factory.ResourceSchemaFactory" />
|
||||||
|
|
|
@ -24,13 +24,13 @@ $Id$
|
||||||
|
|
||||||
from zope.component import adapts
|
from zope.component import adapts
|
||||||
from zope.interface import Attribute, implements
|
from zope.interface import Attribute, implements
|
||||||
from zope.schema import Choice, List
|
from zope.schema import Field, List
|
||||||
from zope.schema.interfaces import IChoice, IList
|
from zope.schema.interfaces import IField, IList
|
||||||
|
|
||||||
from cybertools.composer.schema.interfaces import FieldType
|
from cybertools.composer.schema.interfaces import FieldType
|
||||||
|
|
||||||
|
|
||||||
class IRelation(IChoice):
|
class IRelation(IField):
|
||||||
""" An object addressed via a single relation.
|
""" An object addressed via a single relation.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -50,11 +50,14 @@ class IRelationSet(IList):
|
||||||
'targets for the relations.')
|
'targets for the relations.')
|
||||||
|
|
||||||
|
|
||||||
class Relation(Choice):
|
class Relation(Field):
|
||||||
|
|
||||||
implements(IRelation)
|
implements(IRelation)
|
||||||
|
|
||||||
__typeInfo__ = ('relation',)
|
__typeInfo__ = ('relation',
|
||||||
|
FieldType('relation', 'relation',
|
||||||
|
u'A field representing a related object.',
|
||||||
|
instanceName='relation'))
|
||||||
|
|
||||||
def __init__(self, *args, **kw):
|
def __init__(self, *args, **kw):
|
||||||
self.target_types = kw.pop('target_types')
|
self.target_types = kw.pop('target_types')
|
||||||
|
|
|
@ -28,9 +28,10 @@ from zope.interface import implements
|
||||||
from zope.app.pagetemplate import ViewPageTemplateFile
|
from zope.app.pagetemplate import ViewPageTemplateFile
|
||||||
from zope.cachedescriptors.property import Lazy
|
from zope.cachedescriptors.property import Lazy
|
||||||
import zope.schema
|
import zope.schema
|
||||||
|
from zope.traversing.api import getName
|
||||||
|
|
||||||
from cybertools.composer.schema.factory import createField
|
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 IField, IFieldInstance
|
||||||
from cybertools.composer.schema.interfaces import fieldTypes, undefined
|
from cybertools.composer.schema.interfaces import fieldTypes, undefined
|
||||||
from cybertools.util.format import toStr, toUnicode
|
from cybertools.util.format import toStr, toUnicode
|
||||||
|
@ -41,17 +42,7 @@ from loops import util
|
||||||
relation_macros = ViewPageTemplateFile('relation_macros.pt')
|
relation_macros = ViewPageTemplateFile('relation_macros.pt')
|
||||||
|
|
||||||
|
|
||||||
class RelationSetFieldInstance(ListFieldInstance):
|
class BaseRelationFieldInstance(object):
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def typesParams(self):
|
def typesParams(self):
|
||||||
|
@ -62,3 +53,40 @@ class RelationSetFieldInstance(ListFieldInstance):
|
||||||
if result:
|
if result:
|
||||||
return '?' + '&'.join(result)
|
return '?' + '&'.join(result)
|
||||||
return ''
|
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)
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,13 @@
|
||||||
value obj/uid" />
|
value obj/uid" />
|
||||||
<span tal:content="obj/title" />
|
<span tal:content="obj/title" />
|
||||||
</div>
|
</div>
|
||||||
|
<div tal:repeat="obj python:
|
||||||
|
fieldInstance.getPresetTargets(view)">
|
||||||
|
<input type="checkbox" checked
|
||||||
|
tal:attributes="name string:$name:list;
|
||||||
|
value obj/uid" />
|
||||||
|
<span tal:content="obj/title" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input dojoType="dijit.form.FilteringSelect"
|
<input dojoType="dijit.form.FilteringSelect"
|
||||||
autoComplete="False" labelAttr="label"
|
autoComplete="False" labelAttr="label"
|
||||||
|
@ -27,5 +34,31 @@
|
||||||
</metal:textline>
|
</metal:textline>
|
||||||
|
|
||||||
|
|
||||||
|
<metal:textline define-macro="input_relation"
|
||||||
|
tal:define="fieldInstance field/getFieldInstance;
|
||||||
|
types fieldInstance/typesParams">
|
||||||
|
<div dojoType="dojox.data.QueryReadStore" jsId="conceptSearch"
|
||||||
|
tal:attributes="url string:listConceptsForComboBox.js$types;
|
||||||
|
jsId string:${name}_search_store" >
|
||||||
|
</div>
|
||||||
|
<div tal:define="obj data/?name"
|
||||||
|
tal:attributes="id string:${name}_values"><div>
|
||||||
|
<tal:block tal:condition="obj">
|
||||||
|
<input type="checkbox" checked
|
||||||
|
tal:attributes="name string:$name;
|
||||||
|
value obj/uid" />
|
||||||
|
<span tal:content="obj/title" />
|
||||||
|
</tal:block>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input dojoType="dijit.form.FilteringSelect"
|
||||||
|
autoComplete="False" labelAttr="label"
|
||||||
|
tal:attributes="store string:${name}_search_store;
|
||||||
|
name string:${name}_search;
|
||||||
|
id string:${name}_search;
|
||||||
|
onChange string:setRelation('$name')" />
|
||||||
|
</metal:textline>
|
||||||
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Add table
Reference in a new issue