[Checkins] SVN: z3c.ajax/ initial ajax package import
Oliver Petznick
oliver at mopa.at
Thu Nov 2 06:09:29 EST 2006
Log message for revision 71026:
initial ajax package import
Changed:
A z3c.ajax/
A z3c.ajax/branches/
A z3c.ajax/tags/
A z3c.ajax/trunk/
A z3c.ajax/trunk/src/
A z3c.ajax/trunk/src/z3c/
A z3c.ajax/trunk/src/z3c/__init__.py
A z3c.ajax/trunk/src/z3c/ajax/
A z3c.ajax/trunk/src/z3c/ajax/README.txt
A z3c.ajax/trunk/src/z3c/ajax/TODO.txt
A z3c.ajax/trunk/src/z3c/ajax/__init__.py
A z3c.ajax/trunk/src/z3c/ajax/configure.zcml
A z3c.ajax/trunk/src/z3c/ajax/form.py
A z3c.ajax/trunk/src/z3c/ajax/interfaces.py
A z3c.ajax/trunk/src/z3c/ajax/namespace.py
A z3c.ajax/trunk/src/z3c/ajax/resources/
A z3c.ajax/trunk/src/z3c/ajax/resources/test.html
A z3c.ajax/trunk/src/z3c/ajax/resources/z3c_ajax.js
A z3c.ajax/trunk/src/z3c/ajax/tests.py
A z3c.ajax/trunk/src/z3c/ajax/widget.py
-=-
Added: z3c.ajax/trunk/src/z3c/__init__.py
===================================================================
Property changes on: z3c.ajax/trunk/src/z3c/__init__.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.ajax/trunk/src/z3c/ajax/README.txt
===================================================================
--- z3c.ajax/trunk/src/z3c/ajax/README.txt 2006-11-02 08:29:23 UTC (rev 71025)
+++ z3c.ajax/trunk/src/z3c/ajax/README.txt 2006-11-02 11:09:26 UTC (rev 71026)
@@ -0,0 +1,5 @@
+======
+ ajax
+======
+
+ >>> from z3c.ajax.namespace import AjaxHandler
Property changes on: z3c.ajax/trunk/src/z3c/ajax/README.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.ajax/trunk/src/z3c/ajax/TODO.txt
===================================================================
--- z3c.ajax/trunk/src/z3c/ajax/TODO.txt 2006-11-02 08:29:23 UTC (rev 71025)
+++ z3c.ajax/trunk/src/z3c/ajax/TODO.txt 2006-11-02 11:09:26 UTC (rev 71026)
@@ -0,0 +1,10 @@
+
+remove obsolete stuff from @@ajax implementations
+
+up-to-date? make subform of listwidget a factory attribute, so we do not need a
+registered form for the subobjects
+
+when TextWidget is empty one can't click it
+
+
+
Property changes on: z3c.ajax/trunk/src/z3c/ajax/TODO.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.ajax/trunk/src/z3c/ajax/__init__.py
===================================================================
--- z3c.ajax/trunk/src/z3c/ajax/__init__.py 2006-11-02 08:29:23 UTC (rev 71025)
+++ z3c.ajax/trunk/src/z3c/ajax/__init__.py 2006-11-02 11:09:26 UTC (rev 71026)
@@ -0,0 +1 @@
+#
Property changes on: z3c.ajax/trunk/src/z3c/ajax/__init__.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.ajax/trunk/src/z3c/ajax/configure.zcml
===================================================================
--- z3c.ajax/trunk/src/z3c/ajax/configure.zcml 2006-11-02 08:29:23 UTC (rev 71025)
+++ z3c.ajax/trunk/src/z3c/ajax/configure.zcml 2006-11-02 11:09:26 UTC (rev 71026)
@@ -0,0 +1,108 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser">
+
+
+ <class class=".namespace.AjaxFormTraverser">
+ <allow interface="zope.publisher.interfaces.browser.IBrowserPage"/>
+ </class>
+ <class class=".namespace.AjaxWidgetTraverser">
+ <allow interface="zope.publisher.interfaces.browser.IBrowserPage"/>
+ </class>
+
+ <adapter
+ name="ajax"
+ provides="zope.traversing.interfaces.ITraversable" for="*"
+ factory=".namespace.AjaxHandler"
+ />
+
+ <view
+ name="ajax"
+ type="zope.interface.Interface"
+ provides="zope.traversing.interfaces.ITraversable" for="*"
+ factory=".namespace.AjaxHandler"
+ />
+
+ <adapter
+ provides="zope.traversing.interfaces.ITraversable"
+ for=".interfaces.IAjaxFormTraverser"
+ factory=".namespace.AjaxFormTraversable"/>
+
+ <adapter
+ provides="zope.traversing.interfaces.ITraversable"
+ for=".interfaces.IAjaxWidgetTraverser"
+ factory=".namespace.AjaxWidgetTraversable"/>
+
+
+
+ <!--
+ <adapter
+ name="input"
+ provides=".interfaces.IAjaxForm"
+ factory=".form.ajaxInputForm"
+ for="zope.formlib.interfaces.IForm"
+ trusted="true"/>
+ -->
+
+
+ <!--
+ <browser:page
+ for="zope.formlib.interfaces.IForm"
+ name="ajax"
+ class=".namespace.Ajax"
+ permission="zope.Public"
+ />
+ -->
+
+ <view
+ type="zope.publisher.interfaces.browser.IBrowserRequest"
+ for="zope.schema.interfaces.ITextLine"
+ provides=".interfaces.IAjaxWidget"
+ factory=".widget.TextWidget"
+ permission="zope.Public"
+ />
+
+ <view
+ type="zope.publisher.interfaces.browser.IBrowserRequest"
+ for="zope.schema.interfaces.IList"
+ provides=".interfaces.IAjaxWidget"
+ factory=".widget.ListWidget"
+ permission="zope.Public"
+ />
+
+<!--
+ <browser:pages
+ for=".interfaces.IAjaxWidget"
+ class=".widget.Page"
+ permission="zope.Public"
+ >
+
+ <browser:page name="index.html"
+ attribute="__call__"/>
+ <browser:page name="display"
+ attribute="display"/>
+ <browser:page name="input"
+ attribute="input"/>
+ </browser:pages>
+ -->
+ <!--
+ <browser:pages
+ for=".interfaces.IAjaxForm"
+ class=".form.Page"
+ permission="zope.Public"
+ >
+ <browser:page name="index.html"
+ attribute="__call__"/>
+ <browser:page name="display"
+ attribute="display"/>
+ <browser:page name="input"
+ attribute="input"/>
+ </browser:pages>
+ -->
+
+
+ <resourceLibrary name="z3c_ajax" require="z3c.javascript.scriptaculous">
+ <directory source="resources" include="z3c_ajax.js"/>
+ </resourceLibrary>
+
+
+</configure>
\ No newline at end of file
Property changes on: z3c.ajax/trunk/src/z3c/ajax/configure.zcml
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.ajax/trunk/src/z3c/ajax/form.py
===================================================================
--- z3c.ajax/trunk/src/z3c/ajax/form.py 2006-11-02 08:29:23 UTC (rev 71025)
+++ z3c.ajax/trunk/src/z3c/ajax/form.py 2006-11-02 11:09:26 UTC (rev 71026)
@@ -0,0 +1,31 @@
+from zope.formlib import form
+from interfaces import IAjaxForm
+from zope import interface
+
+class AjaxForm(form.FormBase):
+
+ """base ajax form class which makes its widgets locatable"""
+
+ interface.implements(IAjaxForm)
+ actions = form.Actions()
+
+ def setUpWidgets(self,*args,**kw):
+ super(AjaxForm,self).setUpWidgets(*args,**kw)
+ for widget in self.widgets:
+ widget.__form__ = self
+
+ def renderDisplay(self):
+
+ return "display"
+
+ def renderInput(self):
+
+ return "input"
+
+ def publishTraverse(self, request, name):
+ raise NotFound(self, name, request)
+
+
+
+
+
Property changes on: z3c.ajax/trunk/src/z3c/ajax/form.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.ajax/trunk/src/z3c/ajax/interfaces.py
===================================================================
--- z3c.ajax/trunk/src/z3c/ajax/interfaces.py 2006-11-02 08:29:23 UTC (rev 71025)
+++ z3c.ajax/trunk/src/z3c/ajax/interfaces.py 2006-11-02 11:09:26 UTC (rev 71026)
@@ -0,0 +1,36 @@
+from zope import interface
+from zope.app.form.interfaces import IInputWidget, IDisplayWidget
+
+
+class IAjaxTraverser(interface.Interface):
+
+ """an ajax traverser"""
+
+class IAjaxWidget(interface.Interface):
+
+ """an ajax widget, which is actualy a browser page"""
+
+class IAjaxFormTraverser(interface.Interface):
+
+ """a traverser that traverses to widgets of a form"""
+
+class IAjaxWidgetTraverser(interface.Interface):
+
+ """a traverser that traverses to displays of a widget"""
+
+class IAjaxForm(IInputWidget):
+
+ def __call__(self):
+ """default view"""
+
+ def renderDisplay():
+
+ """render display view"""
+
+ def renderInput():
+
+ """render input view"""
+
+ def browserDefault():
+
+ """ """
Property changes on: z3c.ajax/trunk/src/z3c/ajax/interfaces.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.ajax/trunk/src/z3c/ajax/namespace.py
===================================================================
--- z3c.ajax/trunk/src/z3c/ajax/namespace.py 2006-11-02 08:29:23 UTC (rev 71025)
+++ z3c.ajax/trunk/src/z3c/ajax/namespace.py 2006-11-02 11:09:26 UTC (rev 71026)
@@ -0,0 +1,158 @@
+from zope.traversing.namespace import SimpleHandler
+from zope import component,interface
+from zope.publisher.browser import BrowserPage,BrowserView
+from zope.app.form.interfaces import IInputWidget, IDisplayWidget
+from interfaces import IAjaxWidget
+from zope.traversing.browser.absoluteurl import absoluteURL
+from zc import resourcelibrary
+from zope.app.form.browser.textwidgets import renderElement
+from zope.security.proxy import removeSecurityProxy
+from interfaces import IAjaxFormTraverser,IAjaxWidgetTraverser
+
+class Ajax(BrowserPage):
+ #implements(IAbsoluteURL)
+
+ def __call__(self):
+ return u"no call"
+
+ def publishTraverse(self, request, name):
+
+ name = name.split('.')[-1]
+ fields = removeSecurityProxy(self.context.form_fields)
+ form_field = fields[name]
+ field = form_field.field
+ interface = field.interface
+ adapter = interface(removeSecurityProxy(self.context).context)
+ field = field.bind(adapter)
+ if form_field.custom_widget is not None:
+ widget = form_field.custom_widget(field, request)
+ else:
+ widget = component.getMultiAdapter((field, request),
+ IAjaxWidget)
+ prefix = removeSecurityProxy(self.context).prefix
+ if form_field.prefix:
+ prefix += '.' + form_field.prefix
+ widget.setPrefix(prefix)
+ widget.__form__=self.context
+ return widget
+
+
+class AjaxWidgetTraverser(BrowserPage):
+
+ interface.implements(IAjaxWidgetTraverser)
+
+ def __call__(self):
+ # renders a widget loader
+ #form = component.getMultiAdapter((self.context, self.request),
+ # name=self.__parent__.__name__)
+ url = absoluteURL(self.context,self.request)
+ url = '%s/++ajax++%s/%s' % (url,self.__parent__.__name__,
+ self.__name__)
+ # we switch to display as standard mode
+ html = renderElement('span',
+ cssClass='ajax:container',
+ extra='ajax:src="%s/display"' % url,
+ contents='Loading ...')
+ return html
+
+ def publishTraverse(self, request, name):
+
+ if name=='input':
+ forInput = True
+ elif name=='display':
+ forInput = False
+ else:
+ return super(AjaxWidgetTraverser,self).publishTraverse(
+ request,name)
+ form = component.getMultiAdapter((self.context, self.request),
+ name=self.__parent__.__name__)
+
+ # hm, how can we prevent this line?
+ fieldName = self.__name__.split('.')[-1]
+ fields = form.form_fields
+ #import pdb;pdb.set_trace()
+ form_field = fields[fieldName]
+ field = form_field.field
+ interface = field.interface
+ adapter = interface(form.context)
+ field = field.bind(adapter)
+ if form_field.custom_widget is not None:
+ widget = form_field.custom_widget(field, request)
+ else:
+ widget = component.getMultiAdapter((field, request),
+ IAjaxWidget)
+ prefix = form.prefix
+ if form_field.prefix:
+ prefix += '.' + form_field.prefix
+ widget.setPrefix(prefix)
+ widget.__form__=form
+ widget.__parent__=self
+ if forInput:
+ return widget.renderInput
+ else:
+ return widget.renderDisplay
+
+
+from zope.traversing.adapters import DefaultTraversable
+class AjaxWidgetTraversable(DefaultTraversable):
+
+ def traverse(self, name, furtherPath):
+ if not name in ('input','display'):
+ return super(AjaxWidgetTraversable,self).traverse(
+ name,furtherPath)
+
+ return self._subject.publishTraverse(self._subject.request,
+ name)
+
+
+class AjaxFormTraversable(DefaultTraversable):
+
+ def traverse(self, name, furtherPath):
+ wt = AjaxWidgetTraverser(self._subject.context,
+ self._subject.request)
+ wt.__parent__=self._subject
+ wt.__name__=name
+ return wt
+
+
+class AjaxFormTraverser(BrowserPage):
+
+ interface.implements(IAjaxFormTraverser)
+
+ def __init__(self,context,request,name):
+ super(AjaxFormTraverser,self).__init__(context,request)
+ self.__name__=name
+
+ def __call__(self):
+ # renders a form loader
+ view = component.getMultiAdapter((self.context, self.request),
+ name=self.__name__)
+ url = absoluteURL(view,self.request)
+ resourcelibrary.need('z3c_ajax')
+ # remember: forms only have one display mode, so we load them
+ # from their location
+ html = renderElement('div',
+ cssClass='ajax:container',
+ extra='ajax:src="%s"' % url,
+ contents='Loading ...')
+ return html
+
+ def publishTraverse(self, request, name):
+
+ wt = AjaxWidgetTraverser(self.context,request)
+ wt.__parent__=self
+ wt.__name__=name
+ return wt
+
+class AjaxHandler(SimpleHandler):
+
+ """returns the ajax view widget for a given field in a view"""
+
+ def __init__(self,context,request=None):
+ super(AjaxHandler,self).__init__(context,request)
+ self.request=request
+
+ def traverse(self,name,ignored):
+ # context is a content object
+ return AjaxFormTraverser(self.context,self.request,name)
+
Property changes on: z3c.ajax/trunk/src/z3c/ajax/namespace.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.ajax/trunk/src/z3c/ajax/resources/test.html
===================================================================
--- z3c.ajax/trunk/src/z3c/ajax/resources/test.html 2006-11-02 08:29:23 UTC (rev 71025)
+++ z3c.ajax/trunk/src/z3c/ajax/resources/test.html 2006-11-02 11:09:26 UTC (rev 71026)
@@ -0,0 +1,14 @@
+<html xmlns:ajax="ajax" xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <tal:block replace="resource_library:z3c_ajax"/>
+
+ </head>
+ <body>
+
+ <div class="ajax:container"
+ ajax:src="http://localhost:8080/++skin++Debug/book/++attribute++groups/0/@@edit.html/@@ajax/title">
+ Loading ...
+ </div>
+ </body>
+
+</html>
\ No newline at end of file
Property changes on: z3c.ajax/trunk/src/z3c/ajax/resources/test.html
___________________________________________________________________
Name: svn:eol-style
+ native
Added: z3c.ajax/trunk/src/z3c/ajax/resources/z3c_ajax.js
===================================================================
--- z3c.ajax/trunk/src/z3c/ajax/resources/z3c_ajax.js 2006-11-02 08:29:23 UTC (rev 71025)
+++ z3c.ajax/trunk/src/z3c/ajax/resources/z3c_ajax.js 2006-11-02 11:09:26 UTC (rev 71026)
@@ -0,0 +1,222 @@
+Array.prototype.indexOf = function(v) {
+ for(var i = 0; i < this.length; i++) if(this[i] == v) return i; return -1;
+}
+
+Array.prototype.remove = function(v) {
+ for(var i = 0; i < this.length; i++) if(this[i] == v) { this.splice(i, 1); return; }
+}
+
+// Adds event to window.onload without overwriting currently
+// assigned onload functions.
+function addLoadEvent(func)
+{
+ var oldonload = window.onload;
+ if (typeof window.onload != 'function')
+ {
+ window.onload = func;
+ }
+ else
+ {
+ window.onload = function()
+ {
+ oldonload();
+ func();
+ }
+ }
+}
+
+var z3cContainerOnLoadListeners = Array();
+function z3cContainerLoaded(container){
+ //alert(z3cContainerOnLoadListeners.length);
+ z3cContainerOnLoadListeners.each(function(f){
+ f(container);
+ });
+}
+
+
+function z3cAddContainerLoadListener(func){
+ z3cContainerOnLoadListeners.push(func);
+}
+
+function z3cRemoveContainerLoadListener(func){
+ z3cContainerOnLoadListeners.remove(func);
+}
+
+function fnSuccess(t){
+ //alert(t.responseText);
+}
+
+function fnFailure(resp){
+ alert('failure: ' + t.responseText);
+}
+
+var z3cAjaxContainerCount=0;
+
+// returns the next parent of obj which has the given class
+function z3cNextParentByClass(obj,klass){
+ obj = $(obj);
+
+ while(!Element.hasClassName(obj,klass)){
+ if (obj.parentNode==document){
+ return null;
+ }
+ obj=obj.parentNode;
+ }
+ if (obj){
+ return obj;
+ }
+ return null;
+}
+
+function z3cIsContainer(obj){
+ obj = $(obj);
+ return (obj.getAttribute('class')=='ajax:container');
+}
+
+function z3cNextContainer(obj){
+
+ obj = $(obj);
+ while(obj && (!z3cIsContainer(obj))){
+ obj=obj.parentNode;
+
+ }
+ if (z3cIsContainer(obj)){
+ return obj;
+ }
+ return null;
+}
+
+function z3cContainerURL(obj,view){
+ var container = z3cNextContainer(obj);
+ var current = container.getAttribute('ajax:src');
+ return current.substr(0,current.lastIndexOf('/')+1) + view;
+}
+
+// calls an url on the container
+function z3cCallContainer(obj,view,callback){
+ var container = z3cNextContainer(obj);
+ var url = z3cContainerURL(obj,view);
+ new Ajax.Request(url,
+ {asynchronous:true,
+ method: 'get',
+ onSuccess: fnSuccess,
+ onFailure: fnFailure,
+ onComplete: callback,
+ evalScripts:true}
+ );
+ //alert('loaded');
+}
+
+
+function z3cChangeView(obj,view,condition){
+ if ((condition != null)&&(!condition)){
+ return;
+ }
+ var container = z3cNextContainer(obj);
+ var url = z3cContainerURL(container,view);
+ z3cLoadContainer(container,url);
+}
+
+function z3cLoadContainer(container,url,paras){
+ // XXX: this should be a class because of the onComplete func
+ var container=$(container);
+
+ if (!url){
+ url = container.getAttribute('ajax:src');
+ }
+ new Ajax.Updater(container.id,
+ url,
+ {asynchronous:true,
+ method: 'get',
+ onSuccess: fnSuccess,
+ onFailure: fnFailure,
+ parameters: paras,
+ onComplete: function (t){
+ return z3cContainerLoaded(container);
+ },
+ evalScripts:true}
+ );
+}
+
+// recursive load containers
+z3cAddContainerLoadListener(z3cLoadContainers);
+
+function z3cLoadContent(event){
+ z3cLoadContainers(document.body);
+}
+
+function z3cSaveForm(f){
+ var f = $(f);
+ var container = z3cNextContainer(f);
+ var paras = (Form.serialize(f));
+ z3cLoadContainer(container,null,paras);
+ return;
+ new Ajax.Request(f.action,
+ {asynchronous:false,
+ method: 'get',
+ onSuccess: fnSuccess,
+ onFailure: fnFailure,
+ parameters: paras,
+ evalScripts:true}
+ );
+}
+
+function z3cLoadContainers(obj){
+ // loads containers in obj
+ var obj = $(obj);
+ var containers = document.getElementsByClassName('ajax:container',obj);
+ for (i=0;i<containers.length;i++) {
+ var container = containers[i];
+ // make sure we have an id
+ if (!container.id){
+ z3cAjaxContainerCount++;
+ var id='ajax:container:' +z3cAjaxContainerCount;
+ container.id=id;
+ }
+ z3cLoadContainer(container);
+ }
+}
+
+addLoadEvent(z3cLoadContent);
+
+
+
+
+function makeEdit(id){
+
+ var containerId = id + ".container";
+ var name = $(containerId).getAttribute('name');
+ //var url = document.location + '/@@ajax/' + id;
+ var url=$(containerId).getAttribute('url');
+ //alert(url);
+ var paras = '__input__=1';
+ new Ajax.Updater(containerId,
+ url,
+ {asynchronous:true,
+ method: 'get',
+ onSuccess: fnSuccess,
+ onFailure: fnFailure,
+ parameters: paras,
+ evalScripts:true}
+ );
+}
+
+function z3cApplyChanges(obj){
+ var value = $F(obj);
+ z3cChangeView(obj,'display?apply=1&' + obj.name +'='+$F(obj));
+}
+
+
+function applyAndDisplay(id){
+ var containerId = id + ".container";
+ var url = document.location + '/@@ajax/' + id;
+ paras = id +'='+ $F(id) + '&' + id +'.apply=1';
+ new Ajax.Updater(containerId,
+ url,
+ {asynchronous:true,
+ method: 'get',
+ parameters: paras,
+ }
+ );
+
+}
\ No newline at end of file
Added: z3c.ajax/trunk/src/z3c/ajax/tests.py
===================================================================
--- z3c.ajax/trunk/src/z3c/ajax/tests.py 2006-11-02 08:29:23 UTC (rev 71025)
+++ z3c.ajax/trunk/src/z3c/ajax/tests.py 2006-11-02 11:09:26 UTC (rev 71026)
@@ -0,0 +1,27 @@
+import doctest
+import unittest
+from zope.testing.doctestunit import DocFileSuite, DocTestSuite
+from zope.app.testing import setup
+from zope import component
+
+def setUp(test):
+ setup.placefulSetUp()
+
+
+def tearDown(test):
+ setup.placefulTearDown()
+
+
+def test_suite():
+
+ return unittest.TestSuite(
+ (
+ DocFileSuite('README.txt',
+ setUp=setUp,tearDown=tearDown,
+ optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
+ ),
+ ))
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
+
Property changes on: z3c.ajax/trunk/src/z3c/ajax/tests.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
Added: z3c.ajax/trunk/src/z3c/ajax/widget.py
===================================================================
--- z3c.ajax/trunk/src/z3c/ajax/widget.py 2006-11-02 08:29:23 UTC (rev 71025)
+++ z3c.ajax/trunk/src/z3c/ajax/widget.py 2006-11-02 11:09:26 UTC (rev 71026)
@@ -0,0 +1,182 @@
+from zope.app.form.browser.textwidgets import TextWidget as BaseTextWidget
+from interfaces import IAjaxWidget
+from zope import interface, component
+from zope.publisher.browser import BrowserPage
+from xml.sax.saxutils import quoteattr, escape
+from zope.app.form.browser.textwidgets import renderElement
+from zc import resourcelibrary
+from zope.traversing.browser.absoluteurl import absoluteURL
+from zope.app.form.interfaces import WidgetInputError
+
+class BaseAjaxWidget(BaseTextWidget):
+ interface.implements(IAjaxWidget)
+ containerTag='span'
+
+ def __init__(self,*args,**kw):
+ resourcelibrary.need('z3c_ajax')
+ super(BaseTextWidget,self).__init__(*args,**kw)
+ if self.request:
+ self.request.response.setHeader('Content-Type','text/html')
+
+ def getValue(self):
+ return self.context.get(self.context.context)
+
+ def getURL(self):
+
+ """returns the name of the form"""
+ #TODO make an absolute_url view for this
+ #import pdb;pdb.set_trace()
+
+ url =absoluteURL(self.__form__,self.request)
+
+ formName = url.split('/')[-1]
+ contextURL = absoluteURL(self.__form__.context,self.request)
+ return '%s/++ajax++%s/%s' % (contextURL,self.__form__.__name__,
+ self.name)
+
+ def __call__(self):
+ resourcelibrary.need('z3c_ajax')
+ html = renderElement(self.containerTag,
+ cssClass='ajax:container',
+ extra='ajax:src="%s/display"' % self.getURL(),
+ contents='Loading ...')
+ return html
+
+ def renderInput(self):
+ self.applyMethods()
+
+ def renderDisplay(self):
+ self.applyMethods()
+
+ def applyMethods(self):
+ pass
+
+
+class TextWidget(BaseAjaxWidget):
+
+ inputOnBlur = "z3cChangeView(this,'display?apply=1&' + this.name +'='+$F(this))"
+ displayOnClick = "z3cChangeView(this,'input')"
+
+ def applyMethods(self):
+ if 'apply' in self.request.form:
+ try:
+ self.applyChanges(self.context.context)
+ except WidgetInputError,e:
+ # XXX to some valueable default here
+ pass
+
+
+ def renderInput(self):
+ self.applyMethods()
+ resourcelibrary.need('z3c_ajax')
+ value = self.getValue()
+ self.setRenderedValue(value)
+ value = self._getFormValue()
+ if value is None or value == self.context.missing_value:
+ value = ''
+
+ kwargs = {'type': self.type,
+ 'name': self.name,
+ 'id': self.name,
+ 'value': value,
+ 'cssClass': self.cssClass,
+ 'style': self.style,
+ 'onblur':self.inputOnBlur,
+ 'size': self.displayWidth,
+ 'extra': self.extra}
+ if self.displayMaxWidth:
+ kwargs['maxlength'] = self.displayMaxWidth
+
+ contents = renderElement(self.tag, **kwargs)
+ return contents
+
+ def renderDisplay(self):
+ self.applyMethods()
+ resourcelibrary.need('z3c_ajax')
+ value = self.getValue()
+ contents = renderElement(self.containerTag,
+ name=self.name,
+ id=self.name,
+ contents=value,
+ onclick=self.displayOnClick)
+ return contents
+
+
+from zope.formlib import form
+
+from zope.app.container.contained import ContainedProxy
+from zope.security.proxy import removeSecurityProxy
+
+class ListWidget(BaseAjaxWidget):
+
+ # factory has to take a unicode as constructor
+ contentFactory = None
+ subFormName = u'edit.html'
+ containerTag='div'
+ added = None
+ deleted = None
+
+ def items(self):
+
+ """returns (idx,value) of original value in order to keep the
+ appopriate indexes intact"""
+
+ value = self.getValue()
+ return zip(range(len(value)),value)
+
+
+ def applyMethods(self):
+ if not hasattr(self,'value'):
+ raise RuntimeError,u"self.value is not set"
+ if 'add' in self.request.form and self.added is None:
+ self.createAndAdd(self.request.form.get('add'))
+ if 'delete' in self.request.form and self.deleted is None:
+ value = self.getValue()
+ idx = int(self.request.form.get('delete'))
+ del value[idx]
+ self.deleted = idx
+
+
+ def renderDisplay(self):
+ self.applyMethods()
+ resourcelibrary.need('z3c_ajax')
+ value = self.getValue()
+ html = u''
+ index=0
+ #import pdb;pdb.set_trace()
+ for item in value:
+ item = ContainedProxy(removeSecurityProxy(item))
+ item.__parent__=value
+ item.__name__=unicode(index)
+ sf =component.getMultiAdapter((item, self.request),
+ name=self.subFormName)
+ #sf = self._subForm(item,self.request)
+ sf.setPrefix('%s.%s' % (self.name,index))
+ sf.update()
+ for widget in sf.widgets:
+ widget.__form__=sf
+ print "url------",
+ html += u'<div>%s</div>' % sf.widgets['title']()
+ index+=1
+ onClick = """z3cChangeView(this,'display?add=1')"""
+ html += '<div onclick="%s">+</div>' % onClick
+ return html
+
+ def createAndAdd(self,*args):
+ value = self.getValue()
+ o = self.contentFactory(*args)
+ self.added=o
+ value.append(o)
+
+
+from zope.security.proxy import removeSecurityProxy
+class Page(object):
+
+ def __call__(self):
+ return removeSecurityProxy(self.context)()
+
+ def display(self):
+ return removeSecurityProxy(self.context).renderDisplay()
+
+ def input(self):
+ return removeSecurityProxy(self.context).renderInput()
Property changes on: z3c.ajax/trunk/src/z3c/ajax/widget.py
___________________________________________________________________
Name: svn:keywords
+ Id
Name: svn:eol-style
+ native
More information about the Checkins
mailing list