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
|
||||
>>> topicUid = util.getUidForObject(topic)
|
||||
>>> predicateUid = util.getUidForObject(concepts.getDefaultPredicate())
|
||||
>>> request = TestRequest(form={'form.title': u'Test Note',
|
||||
... 'form.type': u'.loops/concepts/note',
|
||||
... 'form.concept.search.text_selected': str(topicUid)})
|
||||
... 'form.assignments.selected':
|
||||
... [':'.join((topicUid, predicateUid))]})
|
||||
>>> view = NodeView(m112, request)
|
||||
>>> cont = CreateObject(view, request)
|
||||
>>> cont.update()
|
||||
|
|
|
@ -268,6 +268,11 @@ class ConceptRelationView(BaseView):
|
|||
return ':'.join((self.loopsRoot.getLoopsUri(self.context),
|
||||
self.loopsRoot.getLoopsUri(self.predicate)))
|
||||
|
||||
@Lazy
|
||||
def uidToken(self):
|
||||
return ':'.join((util.getUidForObject(self.context),
|
||||
util.getUidForObject(self.predicate)))
|
||||
|
||||
@Lazy
|
||||
def isProtected(self):
|
||||
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 _
|
||||
|
||||
|
||||
# forms
|
||||
|
||||
class ObjectForm(NodeView):
|
||||
|
||||
template = ViewPageTemplateFile('form_macros.pt')
|
||||
|
@ -61,32 +63,10 @@ class ObjectForm(NodeView):
|
|||
def __call__(self):
|
||||
return innerHtml(self)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
class InnerForm(CreateObjectForm):
|
||||
|
||||
@property
|
||||
def macro(self): return self.template.macros['fields']
|
||||
@Lazy
|
||||
def defaultPredicate(self):
|
||||
return util.getUidForObject(
|
||||
self.loopsRoot.getConceptManager().getDefaultPredicate())
|
||||
|
||||
|
||||
class EditObjectForm(ObjectForm, EditForm):
|
||||
|
@ -109,22 +89,103 @@ class EditObjectForm(ObjectForm, EditForm):
|
|||
@property
|
||||
def assignments(self):
|
||||
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):
|
||||
super(EditObjectForm, self).__init__(context, request)
|
||||
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
|
||||
def loopsRoot(self):
|
||||
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):
|
||||
prefix = 'form.'
|
||||
conceptPrefix = 'concept.'
|
||||
form = self.request.form
|
||||
obj = Resource()
|
||||
container = self.loopsRoot.getResourceManager()
|
||||
|
@ -135,26 +196,10 @@ class CreateObject(FormController):
|
|||
container[name] = obj
|
||||
tc = form.get('form.type') or '.loops/concepts/note'
|
||||
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(ObjectModifiedEvent(obj))
|
||||
self.updateFields(obj)
|
||||
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):
|
||||
|
||||
|
@ -165,35 +210,3 @@ class ResourceNameChooser(NameChooser):
|
|||
name = super(ResourceNameChooser, self).chooseName(name, obj)
|
||||
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>
|
||||
<td colspan="5" class="headline">Assign Concept(s)</td>
|
||||
</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/buttons" />
|
||||
</tbody>
|
||||
|
@ -106,9 +107,10 @@
|
|||
<tbody id="form.assignments">
|
||||
<tr tal:repeat="relation view/assignments">
|
||||
<td colspan="5">
|
||||
<input type="hidden" name="form.assignments.tokens:list"
|
||||
tal:attributes="value relation/token" />
|
||||
<input type="checkbox" checked />
|
||||
<input type="hidden" name="form.assignments.old:list"
|
||||
tal:attributes="value relation/uidToken" 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/typeTitle">Topic</span>)
|
||||
</td>
|
||||
|
@ -118,12 +120,12 @@
|
|||
|
||||
|
||||
<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>
|
||||
<select name="form.concept.search.type" id="form.concept.search.type"
|
||||
<select id="concept.search.type"
|
||||
tal:attributes="onChange
|
||||
string:setConceptTypeForComboBox(
|
||||
'form.concept.search.type', 'form.concept.search.text')">
|
||||
'concept.search.type', 'concept.search.text')">
|
||||
<tal:types repeat="type view/conceptTypesForSearch">
|
||||
<option value="loops:*"
|
||||
i18n:translate=""
|
||||
|
@ -132,10 +134,13 @@
|
|||
</tal:types>
|
||||
</select>
|
||||
</td>
|
||||
<td><label for="form.concept.search.text">Search text:</label></td>
|
||||
<td><label for="concept.search.text">Search text:</label></td>
|
||||
<td>
|
||||
<input type="hidden"
|
||||
id="concept.search.predicate"
|
||||
tal:attributes="value view/defaultPredicate" />
|
||||
<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
|
||||
string:${context/@@absolute_url}/listConceptsForComboBox.js?searchString=%{searchString}&searchType=" />
|
||||
</td>
|
||||
|
|
|
@ -79,12 +79,17 @@ function objectDialog(dlgName, url) {
|
|||
|
||||
function addConceptAssignment() {
|
||||
node = dojo.byId('form.assignments');
|
||||
token = document.getElementsByName('form.concept.search.text_selected')[0].value;
|
||||
if (token.length == 0) {return false;}
|
||||
title = document.getElementsByName('form.concept.search.text')[0].value;
|
||||
cToken = document.getElementsByName('concept.search.text_selected')[0].value;
|
||||
if (cToken.length == 0) {
|
||||
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');
|
||||
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');
|
||||
tr.appendChild(td);
|
||||
node.appendChild(tr);
|
||||
|
|
2
util.py
2
util.py
|
@ -66,4 +66,4 @@ def getUidForObject(obj):
|
|||
if obj == '*': # wild card
|
||||
return '*'
|
||||
intIds = component.getUtility(IIntIds)
|
||||
return intIds.queryId(obj)
|
||||
return str(intIds.queryId(obj))
|
||||
|
|
Loading…
Add table
Reference in a new issue