summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrédéric Péters <fpeters@0d.be>2011-12-04 19:26:58 (GMT)
committerFrédéric Péters <fpeters@0d.be>2011-12-04 19:27:42 (GMT)
commit2648a76447c519a8aa6bddd01c8c35b7327c0925 (patch)
tree5993573bb161b308d75b84748652ec03b3382b61
parente28a3076ae9e9863021d839b6a996fdb6b188e59 (diff)
downloadtabellio.searchform-2648a76447c519a8aa6bddd01c8c35b7327c0925.zip
tabellio.searchform-2648a76447c519a8aa6bddd01c8c35b7327c0925.tar.gz
tabellio.searchform-2648a76447c519a8aa6bddd01c8c35b7327c0925.tar.bz2
droppable check boxes for everyone
-rw-r--r--tabellio/searchform/docsearch.pt1
-rw-r--r--tabellio/searchform/droppable-checkbox-widget-input.pt75
-rw-r--r--tabellio/searchform/form.py84
-rw-r--r--tabellio/searchform/js_macros.pt38
4 files changed, 177 insertions, 21 deletions
diff --git a/tabellio/searchform/docsearch.pt b/tabellio/searchform/docsearch.pt
index 22b20cf..ead9ea1 100644
--- a/tabellio/searchform/docsearch.pt
+++ b/tabellio/searchform/docsearch.pt
@@ -186,6 +186,7 @@
<script type="text/javascript" tal:content="string: var PORTAL_URL='${view/portal_url}';"></script>
<script metal:use-macro="view/js_macros/macros/labelboxes"></script>
<script metal:use-macro="view/js_macros/macros/sorton"></script>
+<script metal:use-macro="view/js_macros/macros/droppablecheckboxes"></script>
</tal:block>
</tal:main-macro>
diff --git a/tabellio/searchform/droppable-checkbox-widget-input.pt b/tabellio/searchform/droppable-checkbox-widget-input.pt
new file mode 100644
index 0000000..29d4032
--- /dev/null
+++ b/tabellio/searchform/droppable-checkbox-widget-input.pt
@@ -0,0 +1,75 @@
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:tal="http://xml.zope.org/namespaces/tal"
+ tal:omit-tag="">
+<div class="droppedcheckboxes">
+<span class="option"
+ tal:repeat="item view/items">
+ <input type="checkbox" id="" name="" class="" alt="" title=""
+ tabindex="" disabled="" readonly="" accesskey="" value=""
+ checked="checked"
+ tal:condition="item/checked"
+ tal:attributes="id item/id;
+ name item/name;
+ class view/klass;
+ value item/value;
+ style view/style;
+ title view/title;
+ lang view/lang;
+ onclick view/onclick;
+ ondblclick view/ondblclick;
+ onmousedown view/onmousedown;
+ onmouseup view/onmouseup;
+ onmouseover view/onmouseover;
+ onmousemove view/onmousemove;
+ onmouseout view/onmouseout;
+ onkeypress view/onkeypress;
+ onkeydown view/onkeydown;
+ onkeyup view/onkeyup;
+ disabled view/disabled;
+ tabindex view/tabindex;
+ onfocus view/onfocus;
+ onblur view/onblur;
+ onchange view/onchange;
+ readonly view/readonly;
+ alt view/alt;
+ accesskey view/accesskey;
+ onselect view/onselect"
+ /><input id="" name="" class="" alt="" title="" tabindex=""
+ disabled="" readonly="" accesskey="" value=""
+ type="checkbox"
+ tal:condition="not:item/checked"
+ tal:attributes="id item/id;
+ name item/name;
+ class view/klass;
+ value item/value;
+ style view/style;
+ title view/title;
+ lang view/lang;
+ onclick view/onclick;
+ ondblclick view/ondblclick;
+ onmousedown view/onmousedown;
+ onmouseup view/onmouseup;
+ onmouseover view/onmouseover;
+ onmousemove view/onmousemove;
+ onmouseout view/onmouseout;
+ onkeypress view/onkeypress;
+ onkeydown view/onkeydown;
+ onkeyup view/onkeyup;
+ disabled view/disabled;
+ tabindex view/tabindex;
+ onfocus view/onfocus;
+ onblur view/onblur;
+ onchange view/onchange;
+ readonly view/readonly;
+ alt view/alt;
+ accesskey view/accesskey;
+ onselect view/onselect" />
+ <label for=""
+ tal:attributes="for item/id">
+ <span class="label" tal:content="item/label">Label</span>
+ </label>
+</span>
+</div>
+<input name="field-empty-marker" type="hidden" value="1"
+ tal:attributes="name string:${view/name}-empty-marker" />
+</html>
diff --git a/tabellio/searchform/form.py b/tabellio/searchform/form.py
index 4896df4..9099cbb 100644
--- a/tabellio/searchform/form.py
+++ b/tabellio/searchform/form.py
@@ -16,7 +16,7 @@ from z3c.form.ptcompat import ViewPageTemplateFile
import z3c.form.interfaces
from z3c.form.browser import text
from z3c.form import widget
-from z3c.form.interfaces import ITextWidget
+from z3c.form.interfaces import ITextWidget, ICheckBoxWidget
from z3c.form.browser.checkbox import CheckBoxWidget
from z3c.form.browser.radio import RadioWidget
@@ -183,15 +183,27 @@ def FieldPolgroupsWidget(field, request):
class ITopicsWidget(ITextWidget):
pass
+class IDroppableCheckBoxWidget(ICheckBoxWidget):
+ pass
+
class TopicsWidget(text.TextWidget):
implements(ITopicsWidget)
klass = u'topics'
+class DroppableCheckBoxWidget(CheckBoxWidget):
+ implements(IDroppableCheckBoxWidget)
+ input_template = ViewPageTemplateFile('droppable-checkbox-widget-input.pt')
+
+ def render(self):
+ if self.mode == z3c.form.interfaces.INPUT_MODE:
+ return self.input_template(self)
+ return CheckBoxWidget.render(self)
+
def FieldTopicsWidget(field, request):
return widget.FieldWidget(field, TopicsWidget(request))
def FieldDroppedCheckboxWidget(field, request):
- return widget.FieldWidget(field, CheckBoxWidget(request))
+ return widget.FieldWidget(field, DroppableCheckBoxWidget(request))
def FieldRadioboxesWidget(field, request):
return widget.FieldWidget(field, RadioWidget(request))
@@ -228,7 +240,8 @@ def get_docdos_type_id(context, type_id):
catalog = getToolByName(context, 'portal_catalog')
possible_doctypes = catalog.uniqueValuesFor('doctype')
possible_dostypes = catalog.uniqueValuesFor('dostype')
- for iter_type_id in (possible_dostypes + possible_doctypes):
+ possible_questypes = catalog.uniqueValuesFor('questype')
+ for iter_type_id in (possible_dostypes + possible_doctypes + possible_questypes):
if iter_type_id is None:
continue
rep_id = iter_type_id.encode('ascii', 'replace')
@@ -275,8 +288,6 @@ def possible_sessions(context):
@grok.provider(IContextSourceBinder)
def possible_polgroups(context):
- terms = []
-
current = getToolByName(context, 'portal_url').getPortalObject()
settings = component.getUtility(IRegistry).forInterface(ITabellioSettings, False)
for part in settings.polgroupsPath.split('/'):
@@ -284,13 +295,20 @@ def possible_polgroups(context):
continue
current = getattr(current, part)
+ active_groups = []
+ inactive_groups = []
for object in current.objectValues():
if object.portal_type != 'themis.datatypes.polgroup':
continue
polgroup_id = object.id
polgroup_str = object.Title()
- terms.append(SimpleVocabulary.createTerm(polgroup_id, polgroup_id, polgroup_str))
- return SimpleVocabulary(terms)
+ if object.active:
+ active_groups.append(SimpleVocabulary.createTerm(polgroup_id, polgroup_id, polgroup_str))
+ else:
+ inactive_groups.append(SimpleVocabulary.createTerm(polgroup_id, polgroup_id, polgroup_str))
+ # keep active groups ordered by their position
+ inactive_groups.sort(cmp_term)
+ return SimpleVocabulary(active_groups + inactive_groups)
@grok.provider(IContextSourceBinder)
def possible_active_polgroups(context):
@@ -330,12 +348,15 @@ class IDocumentSearch(interface.Interface):
search_type_is_document = schema.TextLine(title=u'Search Type', default=u'1', required=False)
nodoc = schema.TextLine(title=_(u'Document Number'), required=False)
nosuite = schema.TextLine(title=_(u'Suite Number'), required=False)
- doctype = schema.Choice(title=_(u'Document Type'), required=False,
- source=possible_document_types)
+ l_doctypes = schema.List(title=_(u'Document Type'), required=False,
+ value_type=schema.Choice(title=_(u'Type'), required=False,
+ source=possible_document_types))
ttitle = schema.TextLine(title=_(u'Title'), required=False)
text = schema.TextLine(title=_(u'Text'), required=False)
authors = schema.TextLine(title=_(u'Authors'), required=False)
- polgroups = schema.TextLine(title=_(u'Political Groups'), required=False)
+ l_polgroups = schema.List(title=_(u'Political Groups'), required=False,
+ value_type=schema.Choice(title=_(u'Political Group'),
+ required=False, source=possible_polgroups))
topics = schema.TextLine(title=_(u'Topics'), required=False)
session = schema.Choice(title=_(u'Legislature / Session'), required=False,
source=possible_sessions)
@@ -352,8 +373,9 @@ class DocumentSearchForm(form.Form):
prefix = 'document'
fields = field.Fields(IDocumentSearch)
fields['authors'].widgetFactory = FieldAuthorsWidget
- fields['polgroups'].widgetFactory = FieldPolgroupsWidget
fields['topics'].widgetFactory = FieldTopicsWidget
+ fields['l_doctypes'].widgetFactory = FieldDroppedCheckboxWidget
+ fields['l_polgroups'].widgetFactory = FieldDroppedCheckboxWidget
ignoreContext = True
template = ViewPageTemplateFile('form_templates/view_form.pt')
@@ -370,11 +392,14 @@ class IDossierSearch(interface.Interface):
search_type_is_dossier = schema.TextLine(title=u'Search Type', default=u'1', required=False)
nodos = schema.TextLine(title=_(u'Dossier Number'), required=False)
- dostype = schema.Choice(title=_(u'Dossier Type'), required=False,
- source=possible_dossier_types)
+ l_dostypes = schema.List(title=_(u'Dossier Type'), required=False,
+ value_type=schema.Choice(title=_(u'Type'), required=False,
+ source=possible_dossier_types))
ttitle = schema.TextLine(title=_(u'Title'), required=False)
authors = schema.TextLine(title=_(u'Authors'), required=False)
- polgroups = schema.TextLine(title=_(u'Political Groups'), required=False)
+ l_polgroups = schema.List(title=_(u'Political Groups'), required=False,
+ value_type=schema.Choice(title=_(u'Political Group'),
+ required=False, source=possible_polgroups))
participants = schema.TextLine(title=_(u'Participants'), required=False)
topics = schema.TextLine(title=_(u'Topics'), required=False)
session = schema.Choice(title=_(u'Legislature / Session'), required=False,
@@ -395,7 +420,8 @@ class DossierSearchForm(form.Form):
fields = field.Fields(IDossierSearch)
fields['authors'].widgetFactory = FieldAuthorsWidget
fields['participants'].widgetFactory = FieldAuthorsWidget
- fields['polgroups'].widgetFactory = FieldPolgroupsWidget
+ fields['l_dostypes'].widgetFactory = FieldDroppedCheckboxWidget
+ fields['l_polgroups'].widgetFactory = FieldDroppedCheckboxWidget
fields['topics'].widgetFactory = FieldTopicsWidget
ignoreContext = True
template = ViewPageTemplateFile('form_templates/view_form.pt')
@@ -412,11 +438,14 @@ class DossierSearchForm(form.Form):
class IQuestionSearch(interface.Interface):
search_type_is_question = schema.TextLine(title=u'Search Type', default=u'1', required=False)
- questype = schema.Choice(title=_(u'Question Type'), required=False,
- source=possible_question_types)
+ l_questypes = schema.List(title=_(u'Question Type'), required=False,
+ value_type=schema.Choice(title=_(u'Type'), required=False,
+ source=possible_question_types))
ttitle = schema.TextLine(title=_(u'Title'), required=False)
authors = schema.TextLine(title=_(u'Authors'), required=False)
- polgroups = schema.TextLine(title=_(u'Political Groups'), required=False)
+ l_polgroups = schema.List(title=_(u'Political Groups'), required=False,
+ value_type=schema.Choice(title=_(u'Political Group'),
+ required=False, source=possible_polgroups))
topics = schema.TextLine(title=_(u'Topics'), required=False)
session = schema.Choice(title=_(u'Legislature / Session'), required=False,
source=possible_sessions)
@@ -432,7 +461,8 @@ class QuestionSearchForm(form.Form):
prefix = 'question'
fields = field.Fields(IQuestionSearch)
fields['authors'].widgetFactory = FieldAuthorsWidget
- fields['polgroups'].widgetFactory = FieldPolgroupsWidget
+ fields['l_polgroups'].widgetFactory = FieldDroppedCheckboxWidget
+ fields['l_questypes'].widgetFactory = FieldDroppedCheckboxWidget
fields['topics'].widgetFactory = FieldTopicsWidget
ignoreContext = True
template = ViewPageTemplateFile('form_templates/view_form.pt')
@@ -448,6 +478,8 @@ class QuestionSearchForm(form.Form):
class QuestionPfbSearchForm(QuestionSearchForm):
fields = field.Fields(IQuestionSearch)
fields['authors'].title = _(u'Author(s)')
+ del fields['l_polgroups']
+ fields['l_questypes'].widgetFactory = FieldDroppedCheckboxWidget
@button.buttonAndHandler(_(u'Submit'))
def handleApply(self, action):
@@ -627,6 +659,12 @@ class IGlobalSearchForm(interface.Interface):
l_doctypes = schema.List(title=_(u'Types'), required=False,
value_type=schema.Choice(title=_(u'Type'), required=False,
source=possible_document_types))
+ l_dostypes = schema.List(title=_(u'Types'), required=False,
+ value_type=schema.Choice(title=_(u'Type'), required=False,
+ source=possible_dossier_types))
+ l_questypes = schema.List(title=_(u'Types'), required=False,
+ value_type=schema.Choice(title=_(u'Type'), required=False,
+ source=possible_question_types))
l_polgroups = schema.List(title=_(u'Political Groups'), required=False,
value_type=schema.Choice(title=_(u'Political Group'),
required=False, source=possible_polgroups))
@@ -724,8 +762,14 @@ class SearchView(BrowserView):
kw['doctype'] = get_docdos_type_id(self.context, data.get('doctype'))
if data.get('dostype'):
kw['dostype'] = get_docdos_type_id(self.context, data.get('dostype'))
+ if data.get('questype'):
+ kw['questype'] = get_docdos_type_id(self.context, data.get('questype'))
if data.get('l_doctypes'):
- kw['doctype'] = [get_docdos_type_id(self.context, x) for x in data.get('l_doctypes')]
+ kw['doctype'] = [get_docdos_type_id(self.context, x) for x in data.get('l_doctypes')]
+ if data.get('l_dostypes'):
+ kw['dostype'] = [get_docdos_type_id(self.context, x) for x in data.get('l_dostypes')]
+ if data.get('l_questypes'):
+ kw['questype'] = [get_docdos_type_id(self.context, x) for x in data.get('l_questypes')]
if data.get('start') and data.get('end'):
kw['dateDoc'] = {'query': [data.get('start'), data.get('end')], 'range': 'minmax'}
diff --git a/tabellio/searchform/js_macros.pt b/tabellio/searchform/js_macros.pt
index dcfaa76..c8d82cd 100644
--- a/tabellio/searchform/js_macros.pt
+++ b/tabellio/searchform/js_macros.pt
@@ -97,7 +97,7 @@ function load_results(elem)
})(jQuery);
</script>
-<script tppe="text/javascript" metal:define-macro="sorton">
+<script type="text/javascript" metal:define-macro="sorton">
(function($) {
$().ready(function() {
$('#formfield-document-widgets-sort_on').hide();
@@ -124,6 +124,42 @@ function load_results(elem)
</script>
+<script type="text/javascript" metal:define-macro="droppablecheckboxes">
+function sync_from_checkboxes(elem, dummyinput)
+{
+ t = '';
+ $(elem).find('span.option').each(function(idx, el) {
+ if ($(el).find('input').attr('checked')) {
+ if (t.length > 0) {
+ t = t + ', ';
+ }
+ t = t + $(el).find('label span').text();
+ }
+ });
+ $(dummyinput).attr('value', t);
+}
+
+function setup_droppedcheckboxes(index, elem)
+{
+ var dummyinput = $('<input class="dummyinput" type="text" readonly="readonly"/>');
+ sync_from_checkboxes(elem, dummyinput);
+ dummyinput.click(function() {
+ $(elem).toggle().parent().toggleClass('openboxes');
+ });
+ $(elem).parent().find('.fieldErrorBox').after(dummyinput);
+ $(elem).find('span.option').click(function() {
+ sync_from_checkboxes(elem, dummyinput);
+ });
+ $(elem).hide();
+}
+
+(function($) {
+ $().ready(function() {
+ $('div.droppedcheckboxes').each(setup_droppedcheckboxes);
+ });
+})(jQuery);
+</script>
+
</body>
</html>