ioreskovic
ioreskovic

Reputation: 5699

Using custom classes in Tapestry's BeanEditor

I have a class consisting of mostly Strings and a few Doubles which I have a BeanEditor for.

However, I wish to add another field to this class, and the type of that field is my custom class, let's call it Bar.

public class Foo {
    private String myString;
    private Double myDouble;
    private Bar bar;

    // getters and setters
    ...
}

The allowed values for that field are pulled from a database and should appear as a select control.

However, when I try to do this in my page, it's like the myBar doesn't exist in my Foo class.

<beaneditor>
    <p:bar>
        <div class="t-beaneditor-row">
            <label>Bar</label>
            <t:select t:id="barSelecter" t:model="barModel" t:value="foo.bar" t:encoder="barEncoder"/>
        </div>
    </p:bar>
</beaneditor>

How do I accomplish the desired effect?

Upvotes: 1

Views: 224

Answers (2)

MrSmith42
MrSmith42

Reputation: 10151

You can write your own 'BeanEditor'-block for your type Bar.

Like I did for my TourOperator: NamedDTOSelectTourOperatorBlocks.tml:

<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_4.xsd" xmlns:p="tapestry:parameter">
     <t:block id="editSelectBar">

            <t:label for="tourOperatorEdit" />
              <t:select 
              value="prop:NamedDTOSelectTourOperatorEditContext.id" 
              t:model="tourOperatorIdsModel" t:validate="required" 
              t:id="tourOperatorEdit" t:blankOption="ALWAYS" 
              t:blankLabel="message:select.blank.label" 
              validate="required" />
        </t:block>
</t:container>

The NamedDTOSelectTourOperatorBlocks.java:

public class NamedDTOSelectTourOperatorBlocks {

    @Property
    @Environmental
    private PropertyOutputContext outputContext;

    @Property
    @Environmental
    private PropertyEditContext editContext;

    @Inject
    private ComponentResources resources;

    @Inject
    private TourOperatorManager tourOperatorManager;

    @Inject
    private SelectIdModelFactoryNamedDTO selectIdModelFactoryNamedDTO;

    private SelectModel tourOperatorIdsModel;

    void onPrepareForRender() {
        tourOperatorIdsModel = selectIdModelFactoryNamedDTO.create(tourOperatorManager.getAllNamedDTO());// Read the values from my DB
    }

    public SelectModel getTourOperatorIdsModel() {
        if (null == tourOperatorIdsModel) {
            // REMARK: I have no idea why but loading it in setupRender or onPrepareForRender seams to be too late.
            tourOperatorIdsModel = selectIdModelFactoryNamedDTO.create(tourOperatorManager.getAllNamedDTO());
        }
        return tourOperatorIdsModel;
    }

    public NamedDTOSelectTourOperator getNamedDTOSelectTourOperatorEditContext() {
        return (NamedDTOSelectTourOperator) editContext.getPropertyValue();
    }

    public NamedDTOSelectTourOperator getNamedDTOSelectTourOperatorOutputContext() {
        return (NamedDTOSelectTourOperator) outputContext.getPropertyValue();
    }
}

And don't forget to register the new defined Block in AdminModule.java:

public static void contributeDefaultDataTypeAnalyzer(final MappedConfiguration<Class<?>, String> configuration) {
  ...
      configuration.add(NamedDTOSelectTourOperator.class, "NamedDTOSelectTourOperator");
...}


    public static void contributeDefaultDataTypeAnalyzer(final MappedConfiguration<Class<?>, String> configuration) {
...
     configuration.add(NamedDTOSelectTourOperator.class, "NamedDTOSelectTourOperator");
...}

Upvotes: 0

lance-java
lance-java

Reputation: 27994

You'll have to add the bar property to the model.

Eg <beaneditor add="bar"... >

Upvotes: 2

Related Questions