droppable check boxes for everyone

This commit is contained in:
Frédéric Péters 2011-12-04 20:26:58 +01:00
parent e28a3076ae
commit 2648a76447
4 changed files with 177 additions and 21 deletions

View File

@ -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>

View File

@ -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>

View File

@ -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'}

View File

@ -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>