[PATCH 6 of 9 seda V2] [views] Add master/slave dependency between keyword type and possible vocabularies

Sylvain Thenault sylvain.thenault at logilab.fr
Thu Mar 16 11:37:13 CET 2017


# HG changeset patch
# User Sylvain Thénault <sylvain.thenault at logilab.fr>
# Date 1489659880 -3600
#      Thu Mar 16 11:24:40 2017 +0100
# Node ID 7864b0ba1858788cee6580f398d233098bb84b82
# Parent  2398ca285237721f7b4cb6d8c18f83b933d82d59
[views] Add master/slave dependency between keyword type and possible vocabularies

as specified in extranet #12351787.

Some UI tweaks will be done later to make it more robust (removing the
possibility to add/remove the type inlined form).

diff --git a/cubicweb_seda/data/cubes.skoscomplete.js b/cubicweb_seda/data/cubes.skoscomplete.js
--- a/cubicweb_seda/data/cubes.skoscomplete.js
+++ b/cubicweb_seda/data/cubes.skoscomplete.js
@@ -83,5 +83,52 @@ concept_autocomplete = {
     resetConceptFormField: function(slaveSelectId) {
         cw.jqNode(slaveSelectId+'Label').val('');
         cw.jqNode(slaveSelectId).val('');
     }
 };
+
+typed_vocabularies = {
+    initKeywordTypeMasterWidget: function(masterSelectId, slaveSelectBaseName, allVocabularies) {
+        typed_vocabularies.allVocabularies = allVocabularies;
+        var $masterSelect = cw.jqNode(masterSelectId);
+        var $slaveSelect = $('select[name*="' + slaveSelectBaseName + '"]');
+        if ($slaveSelect.length === 0) {
+            // simple keyword, don't do anything
+            return
+        }
+        // bind keyword type select to update possible vocabularies on value change
+        $masterSelect.change(function() {
+            typed_vocabularies.updatePossibleVocabularies($masterSelect, $slaveSelect);
+        });
+        // initialize possible vocabularies by looking the value of the master field
+        typed_vocabularies.updatePossibleVocabularies($masterSelect, $slaveSelect);
+    },
+
+    updatePossibleVocabularies: function($masterSelect, $slaveSelect) {
+        if (typeof $masterSelect != 'undefined') {
+            var selected_type = $masterSelect.val();
+        } else {
+            var selected_type = '__cubicweb_internal_field__';
+        }
+        var selected_vocab = $slaveSelect.val();
+        // empty possible vocabularies, then refill it with vocabularies that match selected type
+        // (or every vocabulary if there is no selected type)
+        $slaveSelect.empty();
+        $slaveSelect.append('<option value="__cubicweb_internal_field__"></option>');
+        for (i=0; i < typed_vocabularies.allVocabularies.length; i++) {
+            var vocabulary = typed_vocabularies.allVocabularies[i];
+            if (selected_type == '__cubicweb_internal_field__'
+                    || selected_type == vocabulary.keyword_type) {
+                var selected = '';
+                if (selected_vocab == vocabulary.eid) {
+                    selected = ' selected="1"'
+                }
+                $slaveSelect.append(
+                    '<option value="' + vocabulary.eid+ '"' + selected + '>'
+                        + vocabulary.title + '</option>');
+            }
+        }
+        // we've to trigger the change event by ourselves to kick in concept_autocomplete,
+        // probably because we did not changed the value but rather rebuilt the select values
+        $slaveSelect.trigger('change');
+    },
+};
diff --git a/cubicweb_seda/views/archiveunit.py b/cubicweb_seda/views/archiveunit.py
--- a/cubicweb_seda/views/archiveunit.py
+++ b/cubicweb_seda/views/archiveunit.py
@@ -610,10 +610,14 @@ kw_simple_afs.tag_object_of(
     ('*', 'seda_keyword_reference_from', 'SEDAKeyword'),
     'main', 'hidden')
 # but one ordering is enough to rule them all
 affk.set_fields_order('SEDAKeyword', ['keyword_content', ('seda_keyword_reference_from', 'object')])
 
+affk.set_field_kwargs('SEDAKeywordType', 'seda_keyword_type_to',
+                      widget=widgets.KeywordTypeMasterWidget(
+                          slave_base_name='seda_keyword_reference_to_scheme'))
+
 
 class ComplexKeywordAutomaticEntityForm(autoform.AutomaticEntityForm):
     __select__ = (is_instance('SEDAKeyword') & ~is_simple_keyword())
 
     def should_display_inline_creation_form(self, rschema, existing, card):
diff --git a/cubicweb_seda/views/widgets.py b/cubicweb_seda/views/widgets.py
--- a/cubicweb_seda/views/widgets.py
+++ b/cubicweb_seda/views/widgets.py
@@ -104,10 +104,41 @@ class ConceptOrTextField(ff.Field):
             # won't find the proper value (this is very nasty)
             form.formvalues[(subfield, form)] = equivalent_eids
             yield (subfield, equivalent_eids)
 
 
+class KeywordTypeMasterWidget(fw.Select):
+    """
+    Usage::
+
+      affk = uicfg.autoform_field_kwargs
+      affk.set_field_kwargs('KeywordType', 'keyword_type_to',
+                            widget=widgets.KeywordTypeMasterWidget(
+                            slave_base_name='seda_keyword_reference_to_scheme'))
+    """
+
+    def __init__(self, slave_base_name, **kwargs):
+        super(KeywordTypeMasterWidget, self).__init__(**kwargs)
+        self.slave_base_name = slave_base_name
+
+    def _render(self, form, field, render):
+        req = form._cw
+
+        vocabularies_data = []
+        for eid, title, uri, keyword_type in req.execute(
+                'Any CS,CST,CSU,CSKT WHERE CS title CST, CS cwuri CSU, CS code_keyword_type CSKT?'):
+            vocabularies_data.append({'eid': eid, 'title': title or uri,
+                                      'keyword_type': keyword_type})
+        vocabularies_data.sort(key=lambda x: x['title'])
+
+        req.add_js(('cubicweb.js', 'cubicweb.ajax.js', 'cubes.skoscomplete.js'))
+        req.add_onload(js.typed_vocabularies.initKeywordTypeMasterWidget(
+            field.dom_id(form, self.suffix), self.slave_base_name, vocabularies_data))
+
+        return super(KeywordTypeMasterWidget, self)._render(form, field, render)
+
+
 class ConceptAutoCompleteWidget(fw.TextInput):
     """Derive from simple text input to create an autocompletion widget if a scheme is specified,
     otherwise free text is fine if `optional` argument is true. In such case:
 
     * `slave_name` is expected to be the name of the concept attribute, or the text attribute if


More information about the saem-devel mailing list