[Checkins] SVN: megrok.z3cform.ajax/trunk/ Initial Import

Christian Klinger cklinger at novareto.de
Thu Mar 18 11:49:21 EDT 2010


Log message for revision 110057:
  Initial Import

Changed:
  A   megrok.z3cform.ajax/trunk/
  A   megrok.z3cform.ajax/trunk/LICENSE.txt
  A   megrok.z3cform.ajax/trunk/README.txt
  A   megrok.z3cform.ajax/trunk/bootstrap.py
  A   megrok.z3cform.ajax/trunk/buildout.cfg
  A   megrok.z3cform.ajax/trunk/docs/
  A   megrok.z3cform.ajax/trunk/docs/HISTORY.txt
  A   megrok.z3cform.ajax/trunk/setup.py
  A   megrok.z3cform.ajax/trunk/src/
  A   megrok.z3cform.ajax/trunk/src/megrok/
  A   megrok.z3cform.ajax/trunk/src/megrok/__init__.py
  A   megrok.z3cform.ajax/trunk/src/megrok/z3cform/
  A   megrok.z3cform.ajax/trunk/src/megrok/z3cform/__init__.py
  A   megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/
  A   megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/__init__.py
  A   megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/configure.zcml
  A   megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/ftesting.zcml
  A   megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/libs/
  A   megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/libs/validation.js
  A   megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/libs/z3cwizard.js
  A   megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/resource.py
  A   megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/tests/
  A   megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/tests/__init__.py
  A   megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/tests/test_inlinevalidation.py
  A   megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/tests/test_resource.py
  A   megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/validation.py

-=-
Added: megrok.z3cform.ajax/trunk/LICENSE.txt
===================================================================
--- megrok.z3cform.ajax/trunk/LICENSE.txt	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/LICENSE.txt	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1,54 @@
+Zope Public License (ZPL) Version 2.1
+-------------------------------------
+
+A copyright notice accompanies this license document that
+identifies the copyright holders.
+
+This license has been certified as open source. It has also
+been designated as GPL compatible by the Free Software
+Foundation (FSF).
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the
+following conditions are met:
+
+1. Redistributions in source code must retain the
+   accompanying copyright notice, this list of conditions,
+   and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the accompanying
+   copyright notice, this list of conditions, and the
+   following disclaimer in the documentation and/or other
+   materials provided with the distribution.
+
+3. Names of the copyright holders must not be used to
+   endorse or promote products derived from this software
+   without prior written permission from the copyright
+   holders.
+
+4. The right to distribute this software or to use it for
+   any purpose does not give you the right to use
+   Servicemarks (sm) or Trademarks (tm) of the copyright
+   holders. Use of them is covered by separate agreement
+   with the copyright holders.
+
+5. If any files are modified, you must cause the modified
+   files to carry prominent notices stating that you changed
+   the files and the date of any change.
+
+Disclaimer
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS''
+  AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+  NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+  AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+  NO EVENT SHALL THE COPYRIGHT HOLDERS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+  DAMAGE.

Added: megrok.z3cform.ajax/trunk/README.txt
===================================================================
--- megrok.z3cform.ajax/trunk/README.txt	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/README.txt	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1,4 @@
+Introduction
+============
+
+

Added: megrok.z3cform.ajax/trunk/bootstrap.py
===================================================================
--- megrok.z3cform.ajax/trunk/bootstrap.py	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/bootstrap.py	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1,84 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation 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.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id$
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+is_jython = sys.platform.startswith('java')
+
+try:
+    import pkg_resources
+except ImportError:
+    ez = {}
+    exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+                         ).read() in ez
+    ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+    import pkg_resources
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    def quote (c):
+        return c
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+ws  = pkg_resources.working_set
+
+if len(sys.argv) > 2 and sys.argv[1] == '--version':
+    VERSION = '==%s' % sys.argv[2]
+    args = sys.argv[3:] + ['bootstrap']
+else:
+    VERSION = ''
+    args = sys.argv[1:] + ['bootstrap']
+
+if is_jython:
+    import subprocess
+
+    assert subprocess.Popen([sys.executable] + ['-c', quote(cmd), '-mqNxd',
+           quote(tmpeggs), 'zc.buildout' + VERSION],
+           env=dict(os.environ,
+               PYTHONPATH=
+               ws.find(pkg_resources.Requirement.parse('setuptools')).location
+               ),
+           ).wait() == 0
+
+else:
+    assert os.spawnle(
+        os.P_WAIT, sys.executable, quote (sys.executable),
+        '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout' + VERSION,
+        dict(os.environ,
+            PYTHONPATH=
+            ws.find(pkg_resources.Requirement.parse('setuptools')).location
+            ),
+        ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout' + VERSION)
+import zc.buildout.buildout
+zc.buildout.buildout.main(args)
+shutil.rmtree(tmpeggs)

Added: megrok.z3cform.ajax/trunk/buildout.cfg
===================================================================
--- megrok.z3cform.ajax/trunk/buildout.cfg	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/buildout.cfg	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1,12 @@
+[buildout]
+develop = .
+parts = test
+extends = http://grok.zope.org/releaseinfo/grok-1.1rc1.cfg 
+versions = versions
+newest = false
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = 
+    megrok.z3cform.ajax
+defaults = ['--tests-pattern', '^f?tests$', '-v', '-c']

Added: megrok.z3cform.ajax/trunk/docs/HISTORY.txt
===================================================================
--- megrok.z3cform.ajax/trunk/docs/HISTORY.txt	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/docs/HISTORY.txt	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1,7 @@
+Changelog
+=========
+
+0.1 (xxxx-xx-xx)
+----------------
+
+* Initial release

Added: megrok.z3cform.ajax/trunk/setup.py
===================================================================
--- megrok.z3cform.ajax/trunk/setup.py	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/setup.py	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1,41 @@
+from setuptools import setup, find_packages
+import os
+
+version = '0.1'
+
+setup(name='megrok.z3cform.ajax',
+      version=version,
+      description="grok ajax libs",
+      long_description=open("README.txt").read() + "\n" +
+                       open(os.path.join("docs", "HISTORY.txt")).read(),
+      # Get more strings from http://www.python.org/pypi?%3Aaction=list_classifiers
+      classifiers=[
+        "Programming Language :: Python",
+        "Topic :: Software Development :: Libraries :: Python Modules",
+        "License :: OSI Approved :: Zope Public License",
+        ],
+      keywords='grok z3c.form ajax jquery',
+      author='Christian Klinger',
+      author_email='cklinger at novareto.de',
+      url='',
+      license='ZPL',
+      package_dir={'':'src'},
+      packages=find_packages('src', exclude=['ez_setup']),
+      namespace_packages=['megrok', 'megrok.z3cform'],
+      include_package_data=True,
+      zip_safe=False,
+      install_requires=[
+          'setuptools',
+          'grok',
+          'zope.app.testing',
+          'zope.app.zcmlfiles',
+	  'megrok.z3cform.base',
+	  'megrok.z3cform.ui',
+          'hurry.jquery',
+          'megrok.resource',
+          'zope.testbrowser',
+      ],
+      entry_points="""
+      # -*- Entry points: -*-
+      """,
+      )

Added: megrok.z3cform.ajax/trunk/src/megrok/__init__.py
===================================================================
--- megrok.z3cform.ajax/trunk/src/megrok/__init__.py	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/src/megrok/__init__.py	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)

Added: megrok.z3cform.ajax/trunk/src/megrok/z3cform/__init__.py
===================================================================
--- megrok.z3cform.ajax/trunk/src/megrok/z3cform/__init__.py	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/src/megrok/z3cform/__init__.py	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1,6 @@
+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)

Added: megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/__init__.py
===================================================================
--- megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/__init__.py	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/__init__.py	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1 @@
+from resource import InlineValidation 

Added: megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/configure.zcml
===================================================================
--- megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/configure.zcml	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/configure.zcml	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1,20 @@
+<configure
+   xmlns="http://namespaces.zope.org/zope"
+   xmlns:grok="http://namespaces.zope.org/grok"
+   xmlns:z3c="http://namespaces.zope.org/z3c">
+
+  <include package="grokcore.component" file="meta.zcml" />
+  <include package="grokcore.view" file="meta.zcml" />
+
+  <include package="megrok.resource" />
+
+<!-- z3c.form stuff -->
+  <include package="megrok.z3cform.base" file="meta.zcml"/>
+  <include package="megrok.z3cform.base"/>
+  <include package="megrok.z3cform.base" file="default_form_layer.zcml"/>
+  <include package="megrok.z3cform.ui" />
+
+  <grok:grok package=".resource" />
+  <grok:grok package=".validation" />
+
+</configure>

Added: megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/ftesting.zcml
===================================================================
--- megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/ftesting.zcml	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/ftesting.zcml	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1,41 @@
+<configure
+   xmlns="http://namespaces.zope.org/zope"
+   xmlns:grok="http://namespaces.zope.org/grok">
+<!--
+  <include package="zope.app.zcmlfiles" file="meta.zcml" />
+  <include package="zope.securitypolicy" file="meta.zcml" />
+  <include package="zope.app.zcmlfiles" />
+-->
+  <include package="grok" />
+
+
+
+  <include package="megrok.z3cform.ajax" />
+
+  <grok:grok package="megrok.z3cform.ajax.tests" />
+
+  <securityPolicy
+      component="zope.securitypolicy.zopepolicy.ZopeSecurityPolicy"
+      />
+
+  <unauthenticatedPrincipal
+      id="zope.anybody"
+      title="Unauthenticated User"
+      />
+  <grant
+      permission="zope.View"
+      principal="zope.anybody"
+      />
+
+  <principal
+      id="zope.mgr"
+      title="Manager"
+      login="mgr"
+      password="mgrpw"
+      />
+
+  <role id="zope.Manager" title="Site Manager" />
+  <grantAll role="zope.Manager" />
+  <grant role="zope.Manager" principal="zope.mgr" />
+</configure>
+

Added: megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/libs/validation.js
===================================================================
--- megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/libs/validation.js	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/libs/validation.js	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1 @@
+/* */

Added: megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/libs/z3cwizard.js
===================================================================
--- megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/libs/z3cwizard.js	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/libs/z3cwizard.js	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1,38 @@
+// (c) Souheil Chelfouh for Novareto
+
+$(document).ready(function() {
+
+   jQuery.fn.flash = function(opacity, cycle, duration) {
+      for(current=0; current < cycle; current++) {
+        this.animate( { opacity: opacity }, duration / 2 );
+        this.animate( { opacity: '1' }, duration / 2 );
+      }
+    }
+
+  $('form input[type=submit]').live("click", function(e) {
+      clicked = "&" + $(this).attr('name') + "=" + $(this).attr('value');
+
+      dataString = $('form').serialize() + clicked;
+      success = false;
+      errors = null;
+      $.ajax({
+          type: $('form').attr('method'),
+          url: $('form').attr('action'),
+          data: dataString,
+          async: false,
+          complete: function(data, text) {
+              var html = $(data.responseText).find('#inner-page').html();
+
+              $("#inner-page").fadeOut("slow", function(){
+                  $("#inner-page").html(html);
+              });
+
+              $("#inner-page").fadeIn("slow", function(){
+                  $("form input[type=submit]").flash(0.4, 2, 500);
+              });
+          }
+      });
+      return false;
+  });
+
+});

Added: megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/resource.py
===================================================================
--- megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/resource.py	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/resource.py	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+
+from megrok import resource
+from hurry.jquery import jquery
+
+
+class AjaxLib(resource.Library):
+    resource.name('ajaxlib')
+    resource.path('libs')
+
+InlineValidation = resource.ResourceInclusion(
+    AjaxLib, 'validation.js', depends=[jquery])
+

Added: megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/tests/__init__.py
===================================================================
--- megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/tests/__init__.py	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/tests/__init__.py	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1,9 @@
+import os.path
+import megrok.z3cform.ajax
+from zope.app.testing.functional import ZCMLLayer
+
+ftesting_zcml = os.path.join(os.path.dirname(megrok.z3cform.ajax.__file__),
+                             'ftesting.zcml')
+FunctionalLayer = ZCMLLayer(ftesting_zcml, __name__, 'FunctionalLayer',
+                            allow_teardown=True)
+

Added: megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/tests/test_inlinevalidation.py
===================================================================
--- megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/tests/test_inlinevalidation.py	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/tests/test_inlinevalidation.py	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1,45 @@
+"""
+Let's import and init the necessary work environment::
+
+  >>> import grokcore.component as grok
+  >>> from zope.testbrowser.testing import Browser
+
+  >>> browser = Browser()
+  >>> browser.handleErrors = False
+
+  >>> browser.open('http://localhost/@@myform')
+  >>> browser.headers['STATUS'].upper()
+  '200 OK'
+
+  >>> browser.open('http://localhost/@@myform++validation++/field?fieldname=name')
+  >>> browser.contents
+"""
+
+import grokcore.view as grok
+
+from megrok.z3cform.ajax import InlineValidation 
+from zope.interface import Interface
+from zope.schema import TextLine
+from megrok.z3cform.base import Form, Fields
+
+
+class IMammoth(Interface):
+    name = TextLine(title=u"Name")
+
+class MyForm(Form):
+    grok.context(Interface)
+    fields = Fields(IMammoth)
+    ignoreContext = True
+
+    def update(self):
+        InlineValidation.need()
+
+
+
+def test_suite():
+    from zope.testing import doctest
+    from megrok.z3cform.ajax.tests import FunctionalLayer
+    suite = doctest.DocTestSuite(
+          optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS)
+    suite.layer = FunctionalLayer
+    return suite

Added: megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/tests/test_resource.py
===================================================================
--- megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/tests/test_resource.py	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/tests/test_resource.py	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1,41 @@
+"""
+Let's import and init the necessary work environment::
+
+  >>> import grokcore.component as grok
+  >>> from zope.testbrowser.testing import Browser
+
+  >>> browser = Browser()
+  >>> browser.handleErrors = False
+
+  >>> browser.open('http://localhost/@@base')
+  >>> print browser.contents
+  <html><head>
+    <script ... src="http://localhost/@@/jquery/jquery-1.4.2.js"></script>
+    <script ... src="http://localhost/@@/++noop++.../ajaxlib/validation.js"></script>
+  </head></html>
+
+"""
+
+import grokcore.view as grok
+
+from megrok.z3cform.ajax import InlineValidation 
+from zope.interface import Interface
+
+
+class Base(grok.View):
+    grok.context(Interface)
+
+    def update(self):
+        InlineValidation.need()
+
+    def render(self):
+        return "<html><head> </head></html>"
+
+
+def test_suite():
+    from zope.testing import doctest
+    from megrok.z3cform.ajax.tests import FunctionalLayer
+    suite = doctest.DocTestSuite(
+          optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS)
+    suite.layer = FunctionalLayer
+    return suite

Added: megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/validation.py
===================================================================
--- megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/validation.py	                        (rev 0)
+++ megrok.z3cform.ajax/trunk/src/megrok/z3cform/ajax/validation.py	2010-03-18 15:49:21 UTC (rev 110057)
@@ -0,0 +1,80 @@
+import grok
+from z3c.form import field
+from megrok.z3cform.base import IGrokForm
+from zope.i18n import translate
+from zope.i18nmessageid import Message
+from zope.security.proxy import removeSecurityProxy
+from zope.component import getMultiAdapter
+from zope.traversing.interfaces import ITraversable
+from zope.publisher.interfaces.http import IHTTPRequest
+
+
+class Errors(dict):
+    
+    def add(self, key, value, request):
+        if isinstance(value, Message):
+            value = translate(value, context=request)
+        self[key] = value
+
+
+class InlineValidation(grok.MultiAdapter):
+    grok.provides(ITraversable)
+    grok.name('validate')
+    grok.adapts(IGrokForm, IHTTPRequest)
+
+    def __init__(self, context, request):
+        self.form = removeSecurityProxy(context)
+        self.request = request
+
+    def check(self):
+        return True
+
+    def update(self):
+        self.form.update()
+        self.form.updateWidgets()
+        self.data, self.errors = self.form.extractData()
+
+    def validate(self, fieldnames, fieldset=None):
+        errors = Errors()
+        if fieldset is not None:
+            form = self.form.groups[fieldset]
+        else:
+            form = self.form
+            
+        for fieldname in fieldnames:
+            for error in self.errors:
+                if error.widget == form.widgets[fieldname]:
+                    widgetid = form.widgets[fieldname].id
+                    errors.add(widgetid, error.message, self.request)
+                    break
+        return errors
+
+    def traverse(self, name, extra):
+        if not self.check() or not name:
+            return ValueError
+        self.update()
+        if (self.request._traversal_stack):
+            self.extra = self.request._traversal_stack.pop()
+        return getMultiAdapter((self, self.request), name=name)
+
+
+class Validators(grok.JSON):
+    grok.context(InlineValidation)
+
+    def fieldset(self):
+        """Valides a given fieldset
+        """
+        idx = int(self.context.extra)
+        fieldnames = list(self.context.form.groups[idx].fields.keys())
+        errors = self.context.validate(fieldnames, fieldset=idx)
+        return {'success': not errors, 'errors': errors}
+        
+
+    def field(self, fieldname, fieldset=None):
+        wprefix = self.context.form.widgets.prefix
+        fprefix = self.context.form.prefix
+
+        remove = len(fprefix) + len(wprefix)
+        prefixless = fieldname[remove:]
+        errors = self.context.validate([prefixless, ])
+        return errors



More information about the checkins mailing list