Hi Tom & all, First of all, thanks for the help. Its much appreciated :) I understand what you're suggesting, but I needed a way to do it without traversal. For what I'm trying to do, the interface and implementation of the zope objects need to be as simple as possible - anything fancy needs to be (if possible) outside the interface/implementation (like in a widget) I attached what I ended up doing for the widget and the form. Its nothing radical, and very crude, but it works. (The supdoc attribute in the form is defined as supDoc = List(title=_(u"Supporting Docs List"), value_type=Object(IImage, __name__='ImgItem', title=_(u"Image")))anyway, hope this helps anyone who gets stuck on this sort of thing. Again, thanks. Adam Tom Dossis wrote: Adam Summers wrote:Hi Tom & Widget Afficionados.Thanks for the help so far. My problem is now this: From this code (which Tom supplied), how do I code the logic (in bold) def _toFieldValue(self, input): data = "" self)._toFieldValue(input) if data is not None: img = Image(data) notify(ObjectCreatedEvent(img)) return img *else: #data is None, ie. the File input field was left blank and we don't want to #replace the current value of the Image Widget with an empty value. currentImg = the Image object which the field is being rendered for return currentImg * I can't rely on field = self.context image = field.get(field.context) logic to find the data, because my schema can contain: class Iclaim(IContained): """Claim""" supDoc = List(title=_(u"Supporting Docs List"), value_type=Object(IImage, __name__='ImgItem', title=_(u"Image"))) img = Object(IImage, title=_(u"Single img"), required=False) And hence, the self.context.context points to the claim object, not the list inside when rendering supDocHi Adam, You can rely on: field = self.context image = field.get(field.context) because the widget is for an attribute object of type IImage. Your supDoc attribute object is a List Type - not an IImage. In this case you'd need another widget - for a list of IImage. I wouldn't been too keen to tackle the html work effort and would probably look at an alternative along the lines of... class IImageList(IContainer): contains(zope.app.image.interfaces.IImage) class IClaim(IContained): supDoc=Object(schema=IImageList) Make supDoc traversable, then you wouldn't need the custom widget here because you can store Images directly in supDoc view with the browser:containerView's. |
from zope.app.form import CustomWidgetFactory from zope.app.form.browser.widget import DisplayWidget, SimpleInputWidget, renderElement from zope.app.form.browser.sequencewidget import ListSequenceWidget, SequenceDisplayWidget from zope.app.file.image import Image from zope.app.form.interfaces import ConversionError from base64 import b64encode, b64decode class MyImageDisplayWidget(DisplayWidget): def __call__(self): mycontent = u"(No Image)" if self._renderedValueSet() and self._data is not None: mycontent = buildHTMLImg(self._data.data) return mycontent MyImageListDisplayWidget = CustomWidgetFactory(SequenceDisplayWidget, subwidget = MyImageDisplayWidget) class MyImageInputWidget(SimpleInputWidget): """File Widget""" type = 'file' def _toFieldValue(self, input): if (input is None or input == ''): try: imgData = b64decode(self.request.form[self.name + '.data']) return Image(imgData) except AttributeError, e: return self.context.missing_value else: try: seek = input.seek read = input.read except AttributeError, e: raise ConversionError(_('Form input is not a file object'), e) else: seek(0) data = read() if data or getattr(input, 'filename', ''): return Image(data) else: return self.context.missing_value def __call__(self): elem = renderElement(self.tag, type=self.type, name=self.name, id=self.name, extra=self.extra) input_widget = elem try: img_widget = buildHTMLImg(self._data.data) elem = renderElement(self.tag, type='hidden', name=self.name+'.data', id=self.name, extra='value="' + b64encode(self._data.data) + '"') input_widget = img_widget + input_widget +elem return input_widget except AttributeError: return input_widget MyImageInputListWidget = CustomWidgetFactory(ListSequenceWidget, subwidget = MyImageInputWidget) def buildHTMLImg(data): return "<img src=\"data:image/gif;base64, " + b64encode(data) + " \" />"
from zope.formlib import form from as.claim.interfaces import Iclaim from as.claim.claim import claim from as.widget.browser.widgets import MyImageListDisplayWidget, MyImageInputListWidget def _(arg): #yes this is a hack. to be modified return arg class claimAddForm(form.AddForm): form_fields = form.Fields(Iclaim).omit('__name__', '__parent__') form_fields['supDoc'].custom_widget = MyImageInputListWidget def create(self, data): return claim(**data) class claimEditForm(form.EditForm): form_fields = form.Fields(Iclaim).omit('__name__', '__parent__') form_fields['supDoc'].custom_widget = MyImageInputListWidget [EMAIL PROTECTED](_("Apply"), condition=form.haveInputWidgets) #def handle_edit_action(self, action, data): # if self.context.modify(data): # self.status = _(u"Object Updated") # else: # self.status = _(u"No Changes") class claimDisplayForm(form.DisplayForm): form_fields = form.Fields(Iclaim).omit('__name__', '__parent__') #form_fields['img'].custom_widget = MyImageDisplayWidget form_fields['supDoc'].custom_widget = MyImageListDisplayWidget
_______________________________________________ Zope3-users mailing list Zope3-users@zope.org http://mail.zope.org/mailman/listinfo/zope3-users