[Checkins] SVN: z3c.formjs/trunk/src/z3c/formjs/ Implemented
initial version of widget switch.
Stephan Richter
srichter at cosmos.phy.tufts.edu
Thu Jul 19 12:39:54 EDT 2007
Log message for revision 78176:
Implemented initial version of widget switch.
Changed:
U z3c.formjs/trunk/src/z3c/formjs/interfaces.py
U z3c.formjs/trunk/src/z3c/formjs/jqueryrenderer.py
U z3c.formjs/trunk/src/z3c/formjs/jqueryrenderer.zcml
A z3c.formjs/trunk/src/z3c/formjs/jsswitch.py
-=-
Modified: z3c.formjs/trunk/src/z3c/formjs/interfaces.py
===================================================================
--- z3c.formjs/trunk/src/z3c/formjs/interfaces.py 2007-07-19 16:10:22 UTC (rev 78175)
+++ z3c.formjs/trunk/src/z3c/formjs/interfaces.py 2007-07-19 16:39:54 UTC (rev 78176)
@@ -226,7 +226,12 @@
value.
"""
+class IWidgetSwitcher(zope.interface.Interface):
+ pass
+class IWidgetSaver(zope.interface.Interface):
+ pass
+
# -----[ AJAX ]--------------------------------------------------------
Modified: z3c.formjs/trunk/src/z3c/formjs/jqueryrenderer.py
===================================================================
--- z3c.formjs/trunk/src/z3c/formjs/jqueryrenderer.py 2007-07-19 16:10:22 UTC (rev 78175)
+++ z3c.formjs/trunk/src/z3c/formjs/jqueryrenderer.py 2007-07-19 16:39:54 UTC (rev 78176)
@@ -18,6 +18,7 @@
__docformat__ = "reStructuredText"
import zope.component
import zope.interface
+from zope.traversing.browser import absoluteURL
from jquery.layer import IJQueryJavaScriptBrowserLayer
@@ -85,16 +86,20 @@
'\n '.join([r.render() for r in self.renderers]) )
-class JQueryBaseValidationScriptRenderer(object):
+class JQueryMessageValidationScriptRenderer(object):
+ zope.component.adapts(
+ interfaces.IMessageValidationScript, IJQueryJavaScriptBrowserLayer)
zope.interface.implements(interfaces.IRenderer)
+ function = 'applyErrorMessage'
+
def __init__(self, script, request):
- self.script = script
+ self.context = script
self.request = request
def _ajaxURL(self):
- widget = self.script.widget
- form = self.script.form
+ widget = self.context.widget
+ form = self.context.form
# build js expression for extracting widget value
valueString = '$("#%s").val()' % widget.id
# build a js expression that joins valueString expression
@@ -110,17 +115,82 @@
def update(self):
pass
+ def render(self):
+ ajaxURL = self._ajaxURL()
+ # build a js expression that shows the user the error message
+ widget = self.context.widget
+ messageSetter = '%s("%s", msg)' % (self.function, widget.id)
+ ajax = '$.get(%s,\nfunction(msg){%s}\n)' % (ajaxURL, messageSetter)
+ return ajax
-class JQueryMessageValidationScriptRenderer(JQueryBaseValidationScriptRenderer):
+
+class JQueryWidgetSwitcherRenderer(object):
zope.component.adapts(
- interfaces.IMessageValidationScript, IJQueryJavaScriptBrowserLayer)
+ interfaces.IWidgetSwitcher, IJQueryJavaScriptBrowserLayer)
+ zope.interface.implements(interfaces.IRenderer)
- function = 'applyErrorMessage'
+ function = 'switchWidget'
+ def __init__(self, switcher, request):
+ self.context = switcher
+ self.request = request
+
+ def _ajaxURL(self):
+ widget = self.context.widget
+ form = self.context.form
+ # build a js expression that joins valueString expression
+ queryString = '?widget-name=%s' % widget.__name__
+ mode = self.context.mode.title()
+ # build a js expression that joins form url, validate path, and query
+ # string
+ ajaxURL = '"'+ absoluteURL(form, form.request) + '/@@ajax/get' \
+ + mode + 'Widget' + queryString + '"'
+
+ return ajaxURL
+
+ def update(self):
+ pass
+
def render(self):
ajaxURL = self._ajaxURL()
- # build a js expression that shows the user the error message
- widget = self.script.widget
- messageSetter = '%s("%s", msg)' % (self.function, widget.id)
- ajax = '$.get(%s,\nfunction(msg){%s}\n)' % (ajaxURL, messageSetter)
+ widget = self.context.widget
+ switcherCall = '%s("%s", html)' % (self.function, widget.id)
+ ajax = '$.get(%s,\nfunction(html){%s}\n)' % (ajaxURL, switcherCall)
return ajax
+
+
+class JQueryWidgetSaverRenderer(object):
+ zope.component.adapts(
+ interfaces.IWidgetSaver, IJQueryJavaScriptBrowserLayer)
+ zope.interface.implements(interfaces.IRenderer)
+
+ function = 'saveWidget'
+
+ def __init__(self, switcher, request):
+ self.context = switcher
+ self.request = request
+
+ def _ajaxURL(self):
+ widget = self.context.widget
+ form = self.context.form
+ # build js expression for extracting widget value
+ valueString = '$("#%s").val()' % widget.id
+ # build a js expression that joins valueString expression
+ queryString = '?widget-name=%s&%s=" + %s' % (
+ widget.__name__, widget.name, valueString)
+ # build a js expression that joins form url, validate path, and query
+ # string
+ ajaxURL = '"'+ absoluteURL(form, form.request) + \
+ '/@@ajax/saveWidgetValue' + queryString
+
+ return ajaxURL
+
+ def update(self):
+ pass
+
+ def render(self):
+ ajaxURL = self._ajaxURL()
+ widget = self.context.widget
+ switcherCall = '%s("%s", html)' % (self.function, widget.id)
+ ajax = '$.get(%s,\nfunction(html){%s}\n)' % (ajaxURL, switcherCall)
+ return ajax
Modified: z3c.formjs/trunk/src/z3c/formjs/jqueryrenderer.zcml
===================================================================
--- z3c.formjs/trunk/src/z3c/formjs/jqueryrenderer.zcml 2007-07-19 16:10:22 UTC (rev 78175)
+++ z3c.formjs/trunk/src/z3c/formjs/jqueryrenderer.zcml 2007-07-19 16:39:54 UTC (rev 78176)
@@ -14,5 +14,11 @@
<adapter
factory=".jqueryrenderer.JQueryMessageValidationScriptRenderer"
/>
+ <adapter
+ factory=".jqueryrenderer.JQueryWidgetSwitcherRenderer"
+ />
+ <adapter
+ factory=".jqueryrenderer.JQueryWidgetSaverRenderer"
+ />
</configure>
Added: z3c.formjs/trunk/src/z3c/formjs/jsswitch.py
===================================================================
--- z3c.formjs/trunk/src/z3c/formjs/jsswitch.py (rev 0)
+++ z3c.formjs/trunk/src/z3c/formjs/jsswitch.py 2007-07-19 16:39:54 UTC (rev 78176)
@@ -0,0 +1,113 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Switching between display and edit mode.
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import zope.component
+import zope.interface
+import zope.schema.interfaces
+from z3c.form.interfaces import IWidgets
+from zope.publisher.interfaces import NotFound
+
+from z3c.formjs import ajax, interfaces, jsevent, jsaction
+
+
+class WidgetSwitcher(object):
+ zope.interface.implements(interfaces.IWidgetSwitcher)
+
+ def __init__(self, form, widget, mode):
+ self.form = form
+ self.widget = widget
+ self.mode = mode
+
+ def render(self):
+ renderer = zope.component.getMultiAdapter(
+ (self, self.form.request), interfaces.IRenderer)
+ return renderer.render()
+
+
+class WidgetSaver(object):
+ zope.interface.implements(interfaces.IWidgetSaver)
+
+ def __init__(self, form, widget):
+ self.form = form
+ self.widget = widget
+
+ def render(self):
+ renderer = zope.component.getMultiAdapter(
+ (self, self.form.request), interfaces.IRenderer)
+ return renderer.render()
+
+
+class WidgetModeSwitcher(ajax.AJAXRequestHandler):
+ """A mix-in to forms to allow switching between widget modes."""
+ zope.interface.implements(interfaces.IWidgetModeSwitcher)
+
+ @jsaction.handler(zope.schema.interfaces.IField, jsevent.CLICK)
+ def switchToDisplayWidget(self, event, selector):
+ return WidgetSwitcher(self, selector.widget, 'input').render()
+
+ @jsaction.handler(zope.schema.interfaces.IField, jsevent.BLUR)
+ def switchToDisplayWidget(self, event, selector):
+ res = u';\n'.join((
+ WidgetSaver(self, selector.widget).render(),
+ WidgetSwitcher(self, selector.widget, 'display').render()
+ ))
+ return res
+
+ def _getWidget(self, mode):
+ # Step 1: Determine the name of the widget.
+ shortName = self.request.form['widget-name']
+ # Step 2: Limit the form fields only to this one widget.
+ self.fields = self.fields.select(shortName)
+ # Step 3: Instantiate the widget manager, set the correct mode and
+ # update it.
+ self.widgets = zope.component.getMultiAdapter(
+ (self, self.request, self.getContent()), IWidgets)
+ self.widgets.mode = mode
+ self.widgets.update()
+ # Step 4: Return the widget
+ return self.widgets[shortName]
+
+ @ajax.handler
+ def getDisplayWidget(self):
+ '''See interfaces.IWidgetModeSwitcher'''
+ widget = self._getWidget('display')
+ handlers = dict(widget.form.jshandlers.getHandlers(widget.field))
+ code = handlers[jsevent.CLICK](
+ jsevent.CLICK, jsaction.WidgetSelector(widget), self.request)
+ widget.onclick = unicode(code.replace('\n', ''))
+ return widget.render()
+
+ @ajax.handler
+ def getInputWidget(self):
+ '''See interfaces.IWidgetModeSwitcher'''
+ widget = self._getWidget('input')
+ handlers = dict(widget.form.jshandlers.getHandlers(widget.field))
+ code = handlers[jsevent.BLUR](
+ jsevent.BLUR, jsaction.WidgetSelector(widget), self.request)
+ widget.onblur = unicode(code.replace('\n', ''))
+ return widget.render()
+
+ @ajax.handler
+ def saveWidgetValue(self):
+ '''See interfaces.IWidgetModeSwitcher'''
+ widget = self._getWidget('input')
+ data, errors = self.extractData()
+ if errors:
+ return errors[0].message
+ self.applyChanges(data)
+ return ''
Property changes on: z3c.formjs/trunk/src/z3c/formjs/jsswitch.py
___________________________________________________________________
Name: svn:keywords
+ Id
More information about the Checkins
mailing list