2017-01-25 6 views
0

J'ai besoin de modifier le comportement du widget attribué à un champ sur un z3c.form (plus précisément le widget utilisé pour un champ schema.Bool comme celui déclaré ci-dessous) pour changer la façon dont le mode widget fonctionne dans des conditions différentes:Comment remplacer ou hériter un widget z3c.form?

from plone.autoform.interfaces import IFormFieldProvider 
from plone.supermodel import model 
from zope import schema 
from zope.interface import provider 

@provider(IFormFieldProvider) 
class IGoogleNews(model.Schema): 
    """Behavior interface to add some Google News features.""" 

    standout_journalism = schema.Bool(
     title=_(u'Standout Journalism'), 
     required=False, 
    ) 

    news_keywords = schema.Tuple(
     title=_(u'Keywords'), 
     value_type=schema.TextLine(), 
     required=False, 
    ) 
+0

Vous creusez en enfer ;-) Il est probablement plus facile d'écrire votre propre widget héritant du widget bool original. Surcharger un widget n'est pas si simple, sans fournir une nouvelle interface sur le formulaire, ou le champ lui-même. Afaik Vous pouvez seulement remplacer le widget bool en général. – Mathias

+0

en fait, c'était mon idée initiale :-) savez-vous comment puis-je faire cela? – hvelarde

Répondre

2

Ceci est un exemple de code dérivé du widget ftw.datepicker.

En widget.py:

# This widget has a plone integration, so we take this one as base 
from plone.z3cform.widget import SingleCheckBoxWidget 
from z3c.form.interfaces import DISPLAY_MODE 
from z3c.form.interfaces import ISingleCheckBoxWidget 
from zope.interface import implementsOnly 
from zope.component import adapter 
from z3c.form.interfaces import IFormLayer 
from z3c.form.interfaces import IFieldWidget 
from z3c.form.widget import FieldWidget 


class IMyBoolWidget(ISingleCheckBoxWidget): 
    """Marker interface""" 


class MyBoolWidget(SingleCheckBoxWidget) 
    implementsOnly(IMyBoolWidget) 

    display_template = ViewPageTemplateFile('templates/keyword_display.pt') 
    input_template = ViewPageTemplateFile('templates/keyword_input.pt') 
    hidden_template = ViewPageTemplateFile('templates/keyword_hidden.pt') 
    disabled_template = ViewPageTemplateFile('templates/disabled_hidden.pt') 

    def update(self): 
     super(MyBoolWidget, self).update() 

    if self.disable_widget(): 
     # Change widget to display mode 
     self.mode = 'my_own_disabled_mode' 

    def disable_widget(self): 
     # Figure out if the widget should enabled or not. 

    def render(self): 
     if self.mode == INPUT_MODE: 
      return self.input_template(self) 
     elif self.mode == DISPLAY_MODE: 
      return self.display_template(self) 
     elif self.mode == HIDDEN_MODE: 
      return self.hidden_template(self) 
     elif self.mode == 'my_own_disabled_mode' 
      return self.disabled_template(self) 
     raise NotImplementedError(
      'Mode: "{0}" not supported'.format(self.mode)) 

# Following the patterns of z3c widget and create a widget factory. 
# This is not necessary in this case, since there are no additional params. 

@adapter(IMyBoolWidget, IFormLayer) 
@implementer(IFieldWidget) 
def MyBoolWidgetFactory(field, request, config=None): 
    """IFieldWidget factory for...""" 
    return FieldWidget(field, MyBoolWidget(request)) 

MyBoolFieldWidget = MyBoolWidgetFactory 

Inscrivez-vous avec zcml (configure.zcml):

<adapter factory=".widget.MyBoolWidgetFactory" /> 

Utilisez le widget pour votre champ booléen.

from plone.autoform.interfaces import IFormFieldProvider 
from plone.supermodel import model 
from zope import schema 
from zope.interface import provider 
from plone.directives import form 
from wherever.the.widget.is import widget MyBoolFieldWidget 


@provider(IFormFieldProvider) 
class IGoogleNews(model.Schema): 
    """Behavior interface to add some Google News features.""" 

    form.widget('standout_journalism', MyBoolFieldWidget) 
    standout_journalism = schema.Bool(
     title=_(u'Standout Journalism'), 
     required=False, 
    ) 

    news_keywords = schema.Tuple(
     title=_(u'Keywords'), 
     value_type=schema.TextLine(), 
     required=False, 
    ) 

Suivant cette approche, j'ai créé plusieurs widgets, Par exemple aussi un KeywordWidget

Du côté plus:

  • Habituellement petites et minimalistes
  • facile à utiliser

malus:

  • Vous devez l'appliquer manuellement partout où vous le souhaitez.

L'exemple ne comprend pas tous les modèles, vous pouvez les obtenir from z3c.form ou plone.z3cform. *

Cette approche est assez simple et ne pas utiliser les tous les composants d'un widget fait habituellement. Comme enregistrer un modèle de widget pour chaque mode, etc

+0

merci! Je vais tester cela et vous donner votre avis dans les jours qui suivent. – hvelarde