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.

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

    def _toFieldValue(self, input):
        data = "" self)._toFieldValue(input)
        if data is not None:
            img = Image(data)
            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):


	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 supDoc

Hi 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):

class IClaim(IContained):

Make supDoc traversable, then you wouldn't need the custom widget here
because you can store Images directly in supDoc view with the

from zope.app.form import CustomWidgetFactory
from zope.app.form.browser.widget import DisplayWidget, SimpleInputWidget, 
from zope.app.form.browser.sequencewidget import ListSequenceWidget, 
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 == ''):
                        imgData =  b64decode(self.request.form[self.name + 
                        return Image(imgData)
                except AttributeError, e:
                        return self.context.missing_value
                    seek = input.seek
                    read = input.read
                except AttributeError, e:
                    raise ConversionError(_('Form input is not a file object'), 
                    data = read()
                    if data or getattr(input, 'filename', ''):
                        return Image(data)
                        return self.context.missing_value

    def __call__(self):
        elem = renderElement(self.tag,
        input_widget = elem

                img_widget = buildHTMLImg(self._data.data)
                elem = renderElement(self.tag,
                         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 = 

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, 

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

Reply via email to