assign/deassign concepts via dialog OK
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1380 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
1437934070
commit
a44c5a1d2e
6 changed files with 123 additions and 93 deletions
|
@ -650,9 +650,11 @@ created object:
|
||||||
|
|
||||||
>>> from loops import util
|
>>> from loops import util
|
||||||
>>> topicUid = util.getUidForObject(topic)
|
>>> topicUid = util.getUidForObject(topic)
|
||||||
|
>>> predicateUid = util.getUidForObject(concepts.getDefaultPredicate())
|
||||||
>>> request = TestRequest(form={'form.title': u'Test Note',
|
>>> request = TestRequest(form={'form.title': u'Test Note',
|
||||||
... 'form.type': u'.loops/concepts/note',
|
... 'form.type': u'.loops/concepts/note',
|
||||||
... 'form.concept.search.text_selected': str(topicUid)})
|
... 'form.assignments.selected':
|
||||||
|
... [':'.join((topicUid, predicateUid))]})
|
||||||
>>> view = NodeView(m112, request)
|
>>> view = NodeView(m112, request)
|
||||||
>>> cont = CreateObject(view, request)
|
>>> cont = CreateObject(view, request)
|
||||||
>>> cont.update()
|
>>> cont.update()
|
||||||
|
|
|
@ -268,6 +268,11 @@ class ConceptRelationView(BaseView):
|
||||||
return ':'.join((self.loopsRoot.getLoopsUri(self.context),
|
return ':'.join((self.loopsRoot.getLoopsUri(self.context),
|
||||||
self.loopsRoot.getLoopsUri(self.predicate)))
|
self.loopsRoot.getLoopsUri(self.predicate)))
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def uidToken(self):
|
||||||
|
return ':'.join((util.getUidForObject(self.context),
|
||||||
|
util.getUidForObject(self.predicate)))
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def isProtected(self):
|
def isProtected(self):
|
||||||
return zapi.getName(self.predicate) == 'hasType'
|
return zapi.getName(self.predicate) == 'hasType'
|
||||||
|
|
171
browser/form.py
171
browser/form.py
|
@ -46,6 +46,8 @@ from loops import util
|
||||||
from loops.util import _
|
from loops.util import _
|
||||||
|
|
||||||
|
|
||||||
|
# forms
|
||||||
|
|
||||||
class ObjectForm(NodeView):
|
class ObjectForm(NodeView):
|
||||||
|
|
||||||
template = ViewPageTemplateFile('form_macros.pt')
|
template = ViewPageTemplateFile('form_macros.pt')
|
||||||
|
@ -61,32 +63,10 @@ class ObjectForm(NodeView):
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
return innerHtml(self)
|
return innerHtml(self)
|
||||||
|
|
||||||
|
@Lazy
|
||||||
class CreateObjectForm(ObjectForm, Form):
|
def defaultPredicate(self):
|
||||||
|
return util.getUidForObject(
|
||||||
@property
|
self.loopsRoot.getConceptManager().getDefaultPredicate())
|
||||||
def macro(self): return self.template.macros['create']
|
|
||||||
|
|
||||||
title = _(u'Create Resource, Type = ')
|
|
||||||
form_action = 'create_resource'
|
|
||||||
dialog_name = 'create'
|
|
||||||
|
|
||||||
@property
|
|
||||||
def form_fields(self):
|
|
||||||
typeToken = self.request.get('form.type')
|
|
||||||
if typeToken:
|
|
||||||
t = self.loopsRoot.loopsTraverse(typeToken)
|
|
||||||
ifc = ITypeConcept(t).typeInterface
|
|
||||||
else:
|
|
||||||
ifc = INote
|
|
||||||
self.typeInterface = ifc
|
|
||||||
return FormFields(ifc)
|
|
||||||
|
|
||||||
|
|
||||||
class InnerForm(CreateObjectForm):
|
|
||||||
|
|
||||||
@property
|
|
||||||
def macro(self): return self.template.macros['fields']
|
|
||||||
|
|
||||||
|
|
||||||
class EditObjectForm(ObjectForm, EditForm):
|
class EditObjectForm(ObjectForm, EditForm):
|
||||||
|
@ -109,22 +89,103 @@ class EditObjectForm(ObjectForm, EditForm):
|
||||||
@property
|
@property
|
||||||
def assignments(self):
|
def assignments(self):
|
||||||
for c in self.context.getConceptRelations():
|
for c in self.context.getConceptRelations():
|
||||||
yield ConceptRelationView(c, self.request)
|
r = ConceptRelationView(c, self.request)
|
||||||
|
if r.isProtected: continue
|
||||||
|
yield r
|
||||||
|
|
||||||
def __init__(self, context, request):
|
def __init__(self, context, request):
|
||||||
super(EditObjectForm, self).__init__(context, request)
|
super(EditObjectForm, self).__init__(context, request)
|
||||||
self.context = self.virtualTargetObject
|
self.context = self.virtualTargetObject
|
||||||
|
|
||||||
|
|
||||||
class CreateObject(FormController):
|
class CreateObjectForm(ObjectForm, Form):
|
||||||
|
|
||||||
|
@property
|
||||||
|
def macro(self): return self.template.macros['create']
|
||||||
|
|
||||||
|
title = _(u'Create Resource, Type = ')
|
||||||
|
form_action = 'create_resource'
|
||||||
|
dialog_name = 'create'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def form_fields(self):
|
||||||
|
typeToken = self.request.get('form.type')
|
||||||
|
if typeToken:
|
||||||
|
t = self.loopsRoot.loopsTraverse(typeToken)
|
||||||
|
ifc = ITypeConcept(t).typeInterface
|
||||||
|
else:
|
||||||
|
ifc = INote
|
||||||
|
self.typeInterface = ifc
|
||||||
|
return FormFields(ifc)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def assignments(self):
|
||||||
|
return ()
|
||||||
|
|
||||||
|
|
||||||
|
class InnerForm(CreateObjectForm):
|
||||||
|
|
||||||
|
@property
|
||||||
|
def macro(self): return self.template.macros['fields']
|
||||||
|
|
||||||
|
|
||||||
|
# processing form input
|
||||||
|
|
||||||
|
class EditObject(FormController):
|
||||||
|
|
||||||
|
prefix = 'form.'
|
||||||
|
conceptPrefix = 'assignments.'
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
self.updateFields(self.view.virtualTargetObject)
|
||||||
|
return True
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def loopsRoot(self):
|
def loopsRoot(self):
|
||||||
return self.view.loopsRoot
|
return self.view.loopsRoot
|
||||||
|
|
||||||
|
def updateFields(self, obj):
|
||||||
|
form = self.request.form
|
||||||
|
adapter = IType(obj).typeInterface(obj)
|
||||||
|
for k in form.keys():
|
||||||
|
if k.startswith(self.prefix):
|
||||||
|
fn = k[len(self.prefix):]
|
||||||
|
if fn in ('action', 'type',) or fn.endswith('-empty-marker'):
|
||||||
|
continue
|
||||||
|
value = form[k]
|
||||||
|
if fn.startswith(self.conceptPrefix) and value:
|
||||||
|
self.assignConcepts(obj, fn[len(self.conceptPrefix):], value)
|
||||||
|
else:
|
||||||
|
setattr(adapter, fn, value)
|
||||||
|
notify(ObjectModifiedEvent(obj))
|
||||||
|
|
||||||
|
def assignConcepts(self, obj, fieldName, value):
|
||||||
|
old = []
|
||||||
|
selected = []
|
||||||
|
for v in value:
|
||||||
|
if fieldName == 'old':
|
||||||
|
old.append(v)
|
||||||
|
elif fieldName == 'selected':
|
||||||
|
selected.append(v)
|
||||||
|
for v in old:
|
||||||
|
if v not in selected:
|
||||||
|
c, p = v.split(':')
|
||||||
|
concept = util.getObjectForUid(c)
|
||||||
|
predicate = util.getObjectForUid(p)
|
||||||
|
obj.deassignConcept(concept, [predicate])
|
||||||
|
for v in selected:
|
||||||
|
if v not in old:
|
||||||
|
c, p = v.split(':')
|
||||||
|
concept = util.getObjectForUid(c)
|
||||||
|
predicate = util.getObjectForUid(p)
|
||||||
|
exists = obj.getConceptRelations(predicates=[p], concept=concept)
|
||||||
|
if not exists:
|
||||||
|
obj.assignConcept(concept, predicate)
|
||||||
|
|
||||||
|
|
||||||
|
class CreateObject(EditObject):
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
prefix = 'form.'
|
|
||||||
conceptPrefix = 'concept.'
|
|
||||||
form = self.request.form
|
form = self.request.form
|
||||||
obj = Resource()
|
obj = Resource()
|
||||||
container = self.loopsRoot.getResourceManager()
|
container = self.loopsRoot.getResourceManager()
|
||||||
|
@ -135,26 +196,10 @@ class CreateObject(FormController):
|
||||||
container[name] = obj
|
container[name] = obj
|
||||||
tc = form.get('form.type') or '.loops/concepts/note'
|
tc = form.get('form.type') or '.loops/concepts/note'
|
||||||
obj.resourceType = self.loopsRoot.loopsTraverse(tc)
|
obj.resourceType = self.loopsRoot.loopsTraverse(tc)
|
||||||
adapter = IType(obj).typeInterface(obj)
|
|
||||||
for k in form.keys():
|
|
||||||
if k.startswith(prefix):
|
|
||||||
fn = k[len(prefix):]
|
|
||||||
if fn in ('action', 'type',) or fn.endswith('-empty-marker'):
|
|
||||||
continue
|
|
||||||
value = form[k]
|
|
||||||
if fn.startswith(conceptPrefix):
|
|
||||||
self.assignConcepts(obj, fn[len(conceptPrefix):], value)
|
|
||||||
else:
|
|
||||||
setattr(adapter, fn, value)
|
|
||||||
notify(ObjectCreatedEvent(obj))
|
notify(ObjectCreatedEvent(obj))
|
||||||
notify(ObjectModifiedEvent(obj))
|
self.updateFields(obj)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def assignConcepts(self, obj, fieldName, value):
|
|
||||||
if value and fieldName == 'search.text_selected':
|
|
||||||
concept = util.getObjectForUid(value)
|
|
||||||
obj.assignConcept(concept)
|
|
||||||
|
|
||||||
|
|
||||||
class ResourceNameChooser(NameChooser):
|
class ResourceNameChooser(NameChooser):
|
||||||
|
|
||||||
|
@ -165,35 +210,3 @@ class ResourceNameChooser(NameChooser):
|
||||||
name = super(ResourceNameChooser, self).chooseName(name, obj)
|
name = super(ResourceNameChooser, self).chooseName(name, obj)
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
|
||||||
class EditObject(FormController):
|
|
||||||
|
|
||||||
@Lazy
|
|
||||||
def loopsRoot(self):
|
|
||||||
return self.view.loopsRoot
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
prefix = 'form.'
|
|
||||||
conceptPrefix = 'concept.'
|
|
||||||
form = self.request.form
|
|
||||||
obj = self.view.virtualTargetObject
|
|
||||||
adapter = IType(obj).typeInterface(obj)
|
|
||||||
for k in form.keys():
|
|
||||||
if k.startswith(prefix):
|
|
||||||
fn = k[len(prefix):]
|
|
||||||
if fn in ('action', 'type',) or fn.endswith('-empty-marker'):
|
|
||||||
continue
|
|
||||||
value = form[k]
|
|
||||||
if fn.startswith(conceptPrefix):
|
|
||||||
self.assignConcepts(obj, fn[len(conceptPrefix):], value)
|
|
||||||
else:
|
|
||||||
setattr(adapter, fn, value)
|
|
||||||
notify(ObjectModifiedEvent(obj))
|
|
||||||
return True
|
|
||||||
|
|
||||||
def assignConcepts(self, obj, fieldName, value):
|
|
||||||
if value and fieldName == 'search.text_selected':
|
|
||||||
concept = util.getObjectForUid(value)
|
|
||||||
obj.assignConcept(concept)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="5" class="headline">Assign Concept(s)</td>
|
<td colspan="5" class="headline">Assign Concept(s)</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr metal:use-macro="view/template/macros/assignments" />
|
||||||
<tr metal:use-macro="view/template/macros/search_concepts" />
|
<tr metal:use-macro="view/template/macros/search_concepts" />
|
||||||
<tr metal:use-macro="view/template/macros/buttons" />
|
<tr metal:use-macro="view/template/macros/buttons" />
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -106,9 +107,10 @@
|
||||||
<tbody id="form.assignments">
|
<tbody id="form.assignments">
|
||||||
<tr tal:repeat="relation view/assignments">
|
<tr tal:repeat="relation view/assignments">
|
||||||
<td colspan="5">
|
<td colspan="5">
|
||||||
<input type="hidden" name="form.assignments.tokens:list"
|
<input type="hidden" name="form.assignments.old:list"
|
||||||
tal:attributes="value relation/token" />
|
tal:attributes="value relation/uidToken" checked />
|
||||||
<input type="checkbox" checked />
|
<input type="checkbox" name="form.assignments.selected:list"
|
||||||
|
tal:attributes="value relation/uidToken" checked />
|
||||||
<span tal:content="relation/title">Something</span>
|
<span tal:content="relation/title">Something</span>
|
||||||
(<span tal:content="relation/typeTitle">Topic</span>)
|
(<span tal:content="relation/typeTitle">Topic</span>)
|
||||||
</td>
|
</td>
|
||||||
|
@ -118,12 +120,12 @@
|
||||||
|
|
||||||
|
|
||||||
<tr metal:define-macro="search_concepts">
|
<tr metal:define-macro="search_concepts">
|
||||||
<td><label for="form.concept.search.type">Type:</label></td>
|
<td><label for="concept.search.type">Type:</label></td>
|
||||||
<td>
|
<td>
|
||||||
<select name="form.concept.search.type" id="form.concept.search.type"
|
<select id="concept.search.type"
|
||||||
tal:attributes="onChange
|
tal:attributes="onChange
|
||||||
string:setConceptTypeForComboBox(
|
string:setConceptTypeForComboBox(
|
||||||
'form.concept.search.type', 'form.concept.search.text')">
|
'concept.search.type', 'concept.search.text')">
|
||||||
<tal:types repeat="type view/conceptTypesForSearch">
|
<tal:types repeat="type view/conceptTypesForSearch">
|
||||||
<option value="loops:*"
|
<option value="loops:*"
|
||||||
i18n:translate=""
|
i18n:translate=""
|
||||||
|
@ -132,10 +134,13 @@
|
||||||
</tal:types>
|
</tal:types>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
<td><label for="form.concept.search.text">Search text:</label></td>
|
<td><label for="concept.search.text">Search text:</label></td>
|
||||||
<td>
|
<td>
|
||||||
|
<input type="hidden"
|
||||||
|
id="concept.search.predicate"
|
||||||
|
tal:attributes="value view/defaultPredicate" />
|
||||||
<input dojoType="comboBox" mode="remote" autoComplete="False"
|
<input dojoType="comboBox" mode="remote" autoComplete="False"
|
||||||
name="form.concept.search.text" id="form.concept.search.text"
|
name="concept.search.text" id="concept.search.text"
|
||||||
tal:attributes="dataUrl
|
tal:attributes="dataUrl
|
||||||
string:${context/@@absolute_url}/listConceptsForComboBox.js?searchString=%{searchString}&searchType=" />
|
string:${context/@@absolute_url}/listConceptsForComboBox.js?searchString=%{searchString}&searchType=" />
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -79,12 +79,17 @@ function objectDialog(dlgName, url) {
|
||||||
|
|
||||||
function addConceptAssignment() {
|
function addConceptAssignment() {
|
||||||
node = dojo.byId('form.assignments');
|
node = dojo.byId('form.assignments');
|
||||||
token = document.getElementsByName('form.concept.search.text_selected')[0].value;
|
cToken = document.getElementsByName('concept.search.text_selected')[0].value;
|
||||||
if (token.length == 0) {return false;}
|
if (cToken.length == 0) {
|
||||||
title = document.getElementsByName('form.concept.search.text')[0].value;
|
alert('Please select a concept!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pToken = dojo.byId('concept.search.predicate').value;
|
||||||
|
token = cToken + ':' + pToken;
|
||||||
|
title = document.getElementsByName('concept.search.text')[0].value;
|
||||||
var td = document.createElement('td');
|
var td = document.createElement('td');
|
||||||
td.setAttribute('colspan', '5');
|
td.setAttribute('colspan', '5');
|
||||||
td.innerHTML = '<input type="hidden" name="form.assignments.tokens:list" value="' + token + '" /><input type="checkbox" checked /><span>' + title + '</span>';
|
td.innerHTML = '<input type="checkbox" name="form.assignments.selected:list" value="' + token + '" checked><span>' + title + '</span>';
|
||||||
var tr = document.createElement('tr');
|
var tr = document.createElement('tr');
|
||||||
tr.appendChild(td);
|
tr.appendChild(td);
|
||||||
node.appendChild(tr);
|
node.appendChild(tr);
|
||||||
|
|
2
util.py
2
util.py
|
@ -66,4 +66,4 @@ def getUidForObject(obj):
|
||||||
if obj == '*': # wild card
|
if obj == '*': # wild card
|
||||||
return '*'
|
return '*'
|
||||||
intIds = component.getUtility(IIntIds)
|
intIds = component.getUtility(IIntIds)
|
||||||
return intIds.queryId(obj)
|
return str(intIds.queryId(obj))
|
||||||
|
|
Loading…
Add table
Reference in a new issue