/fa/jquery/renderers.py
Python | 506 lines | 500 code | 4 blank | 2 comment | 0 complexity | 66a8a2cc1c901bb4bba07fad1cfdf3e1 MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1
- # -*- coding: utf-8 -*-
- import os
- from simplejson import dumps
- from webhelpers.html import literal
- from webhelpers.html.tools import strip_tags
- from webhelpers import text
- from formalchemy import helpers as h
- from formalchemy import types
- from formalchemy import fields
- from formalchemy import config
- from postmarkup import render_bbcode
- from textile import textile as render_textile
- from markdown import markdown as render_markdown
- from utils import TemplateEngine
- from utils import templates
- from utils import load_datas
- from utils import url
- __doc__ = """
- This is the predefined renderers. You can have a look at the :doc:`../demo`.
- If you need your own, use the :class:`~fa.jquery.renderers.jQueryFieldRenderer`
- as base class.
- Some plugins use extra resources stored at the
- :class:`~fa.jquery.wsgi.StaticApp`. By default the prefix used is ``/jquery``.
- If you want to change this you can use this snippet:
- .. sourcecode:: python
- >>> from fa.jquery import renderers
- >>> renderers.url.root_url = '/jquery'
- """
- def alias(obj, **alias_kwargs):
- """decorator to make aliases with docs"""
- def wrapped(func):
- if hasattr(obj, 'func_name'):
- def wrapper(*args, **kwargs):
- """Alias for :func:`~fa.jquery.renderers.%s` with preset options %r""" % (obj.func_name, alias_kwargs)
- kwargs.update(alias_kwargs)
- return obj(*args, **kwargs)
- wrapper.func_name = func.func_name
- wrapper.func_doc = """Alias for :func:`~fa.jquery.renderers.%s` with preset options %r""" % (obj.func_name, alias_kwargs)
- return wrapper
- else:
- doc = """Alias for :class:`~fa.jquery.renderers.%s` with preset options %r""" % (obj.__name__, alias_kwargs)
- alias_kwargs['__doc__'] = doc
- return type(func.func_name, (obj,), alias_kwargs)
- return wrapped
- def jQueryFieldRenderer(plugin, show_input=False, tag='div', renderer=fields.TextFieldRenderer,
- resources_prefix=None, resources=[], **jq_options):
- """Extending jQuery.fa:
- .. sourcecode:: python
- >>> from testing import fs
- >>> renderer = jQueryFieldRenderer('myplugin', option1=True, option2=['a', 'b'])
- >>> field = fs.title.set(renderer=renderer)
- >>> print field.render() #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
- <div style="display:none;"><input autocomplete="off" id="Sample--title" name="Sample--title" type="text" /></div>
- <div id="Sample--title_myplugin"></div>
- <script type="text/javascript">
- jQuery.fa.myplugin('Sample--title', {"option2": ["a", "b"], "options": [], "option1": true});
- </script>...
- Then in your javascript code:
- .. sourcecode:: javascript
- jQuery.fa.extend({
- myplugin: function(field, plugin, options) {
- // do what you want
- }
- });
- Where field is the input, plugin the empty div and options the jq_options passed to the renderer.
- """
- template_name = jq_options.get('_template', 'jquery')
- template=templates.get_template('/renderers/%s.mako' % template_name)
- class Renderer(renderer):
- def render(self, **kwargs):
- if 'autocomplete' in kwargs:
- kwargs.pop('autocomplete')
- html = renderer.render(self, autocomplete='off', **kwargs)
- kwargs.update(self.jq_options)
- options = dict(
- tag=tag,
- html=html,
- plugin=plugin,
- name=self.name,
- show_input=show_input,
- resources=[url(r, prefix=self.resources_prefix) for r in resources],
- )
- try:
- options.update(options=dumps(kwargs))
- except TypeError:
- options.update(options={})
- try:
- return literal(self.template.render(**options))
- except:
- raise ValueError('Invalid options: %s' % options)
- return type('%sPluginRenderer' % plugin.title(), (Renderer,),
- dict(template=template,
- jq_options=jq_options,
- resources_prefix=resources_prefix))
- @alias(jQueryFieldRenderer)
- def plugin(): pass
- def AutoCompleteFieldRenderer(url_or_data, renderer=fields.TextFieldRenderer, **jq_options):
- """Use http://docs.jquery.com/UI/Autocomplete:
- .. sourcecode:: python
- >>> from testing import fs
- >>> field = fs.title.set(renderer=AutoCompleteFieldRenderer(['aa', 'bb']))
- With more advanced options:
- .. sourcecode:: python
- >>> field = fs.title.set(
- ... renderer=AutoCompleteFieldRenderer(
- ... '/my/uri',
- ... width=320,
- ... scroll=True,
- ... scrollHeight=300,
- ... ))
- """
- jq_options.update(source=url_or_data, show_input=False)
- return jQueryFieldRenderer('autocomplete', renderer=renderer, **jq_options)
- @alias(AutoCompleteFieldRenderer)
- def autocomplete(): pass
- def SortableTokenTextFieldRenderer(sep=';', show_input=False, **jq_options):
- """Sortable token using http://jqueryui.com/demos/sortable/:
- .. sourcecode:: python
- >>> from testing import fs
- >>> field = fs.sortable.set(renderer=SortableTokenTextFieldRenderer())
- >>> print field.render() #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
- <input type="hidden" value="fisrt;second" id="Sample--sortable" name="Sample--sortable" />
- <ul id="Sample--sortable_sortable" class="fa_sortable">
- <li class="ui-state-default" alt="fisrt"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>fisrt</li>
- <li class="ui-state-default" alt="second"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>second</li>
- </ul>
- <script type="text/javascript">
- jQuery.fa.sortable('Sample--sortable', {sep:';'});
- </script>...
- """
- class Renderer(fields.TextFieldRenderer):
- template=templates.get_template('/renderers/sortable.mako')
- def render_readonly(self):
- return ', '.join(self.raw_value.split(sep))
- def render(self, **kwargs):
- value=self.value.strip(sep)
- tokens = value and value.split(sep) or ''
- tokens = [(v, v) for v in tokens]
- kwargs.update(
- name=self.name,
- sep=sep,
- value=value,
- tokens=tokens,
- show_input=show_input,
- jq_options=dumps(jq_options),
- )
- return literal(self.template.render(**kwargs))
- return Renderer
- @alias(SortableTokenTextFieldRenderer)
- def sortable_token(): pass
- def ColorPickerFieldRenderer(colors=[], **jq_options):
- """Color Picker using http://www.syronex.com/software/jquery-color-picker:
- .. sourcecode:: python
- >>> from testing import fs
- >>> print fs.color.render() #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
- <div style="display:none;"><input autocomplete="off" id="Sample--color" name="Sample--color" type="text" /></div>
- <div id="Sample--color_colorpicker"></div>
- <script type="text/javascript">
- jQuery.fa.colorpicker('Sample--color', {"color": ["#FFFFFF", ...]});
- </script>
- <BLANKLINE>
-
- <div style="display:none;"><input autocomplete="off" id="Sample--color" name="Sample--color" type="text" /></div>
- <div id="Sample--color_colors"></div>
- <script type="text/javascript">
- jQuery.fa.colorpicker('Sample--color', {"color": ["#FFFFFF", ..., "#FF0096", "#B02B2C", "#000000"]});
- </script>...
- """
- jq_options['color'] = colors or [
- "#FFFFFF", "#EEEEEE", "#FFFF88", "#FF7400", "#CDEB8B", "#6BBA70",
- "#006E2E", "#C3D9FF", "#4096EE", "#356AA0", "#FF0096", "#B02B2C",
- "#000000"
- ]
- class Renderer(fields.TextFieldRenderer):
- def render_readonly(self, **kwargs):
- v = self.raw_value
- if not v:
- return ''
- return h.literal('<div style="background:%s;">%s</div>' % (v, v))
- return jQueryFieldRenderer('colorpicker', renderer=Renderer, **jq_options)
- @alias(ColorPickerFieldRenderer)
- def colorpicker(): pass
- class DateFieldRenderer(fields.DateFieldRenderer):
- """Use http://jqueryui.com/demos/datepicker/:
- .. sourcecode:: python
- >>> from testing import fs
- >>> print fs.date.render() #doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
- <input type="text" autocomplete="off" size="10" value="" id="Sample--date" name="Sample--date" />
- <script type="text/javascript">
- jQuery.fa.datepicker('Sample--date', {"dateFormat": "yy-mm-dd"});
- </script>...
- """
- template = templates.get_template('/renderers/date.mako')
- jq_options = dict(dateFormat='yy-mm-dd')
- def render(self, **kwargs):
- value = self.value or ''
- value = value and value.split()[0] or ''
- kwargs.update(
- name=self.name,
- value=value,
- jq_options=dumps(self.jq_options),
- )
- return literal(self.template.render(**kwargs))
- def _serialized_value(self):
- value = self.params.getone(self.name) or ''
- return value
- @alias(DateFieldRenderer)