Right.  I'm simply pointing out a way to do that with mixins.
For instance, we can add:

@BindParamater;
private SelectModel model;

private BlankOption originalOption;

and make beginRender* look something like this

void beginRender() {
  originalOption = blankOption;
  if (blankOption == AUTO) {
         //we're changing this /just/ before the select gets rendered, 
overriding the user-defined value (or the default value) so that Tapestry's 
"AUTO" branch of the switch never gets invoked; we've now made the component
         //do the right thing.
         if (required && model.getOptions.size() == 1) {
            blankOption=NEVER;
         }  else {
            blankOption=ALWAYS;
         }
  }
}

void afterRender() {
  blankOption = originalOption; //this isn't strictly necessary, but it's a 
nicety.
}

* Note: I misnamed the method beforeRender in my earlier e-mail; should be 
beginRender.  It's always bugged me that's it's "beginRender" and "afterRender" 
instead of "beginRender" and "endRender" or "beforeRender" and "afterRender". :)


Voila.  Apply your mixin.  "auto" behavior as desired, in a reusable format.

Robert

On May 13, 2010, at 5/131:44 PM , Benny Law wrote:

> As I explained before, I want to change the "auto" behavior to make it
> smarter. Currently, there is really no intelligence in the logic: a blank
> option is added if the field is not required, and no blank option is added
> if the field is required. When the option list is static, I can set the
> blank option myself, no problem. But when the list is dynamic, I don't know
> ahead of time how many options there will be, so I want the Select component
> to decide for me. If the field is required, I still want a blank option
> unless there is exactly one option because I don't want the first option to
> be selected as a default. I want the user to consciously choose a value.
> 
> On Thu, May 13, 2010 at 2:30 PM, Robert Zeigler <robe...@scazdl.org> wrote:
> 
>> Why are you wanting to change the "auto" behavior in the first place?
>> In the few cases where there is no "sensible" default value, is using the
>> "blankLabel" and "blankOption" parameters so excruciatingly onerous? If so,
>> why not not simply wrap the select component in a custom select component
>> that provides the values you want? You would have to provide parameters in
>> your wrapper that passed through to the underlying select, but this is
>> certainly doable.
>> 
>> In fact, this particular case could be handled (I think?) in 5.2 in a very
>> clean way.  5.2 introduces the possibility for mixins to bind and manipulate
>> the containing component's parameters.  So you could, in theory, write a
>> mixin that sets the appropriate values for you.  Basically, you would have
>> something like this:
>> 
>> public class Blank {
>> 
>> @BindParameter
>> private boolean required;
>> 
>> @BindParameter
>> private BlankOption blankOption;
>> 
>> @BindParameter
>> private blankLabel blankLabel;
>> 
>> void beginRender() {//this will happen before the select's before
>> render...
>> if (//whatever condition you want....) {
>>   blankOption=ALWAYS;//we've now overridden the default check in
>> showBlankOption() b/c by the time that renders, showBlankOption will see
>> "blankOption" as being ALWAYS instead of AUTO.
>>   blankLabel="Select one...";
>> } else {
>>   blankOption=NEVER;
>> }
>> }
>> 
>> }
>> 
>> Which you could then use like:
>> 
>> <t:select ... t:mixins="blank"/>
>> 
>> which seems very non-onerous to me. :)
>> 
>> Robert
>> 
>> On May 13, 2010, at 5/1312:56 PM , Benny Law wrote:
>> 
>>> I did look at the demo Geoff posted. How is that going to provide what I
>>> need? I'm sorry, but I fail to see this "easy fix" you mentioned. Maybe
>> you
>>> can be a bit more specific?
>>> 
>>> 
>>> On Thu, May 13, 2010 at 1:15 PM, Christian Riedel
>>> <cr.ml...@googlemail.com>wrote:
>>> 
>>>> Well I agree that some more extensibility could be made here and there.
>>>> That particular problem looks like it's worth a JIRA with a patch from
>> you
>>>> that makes the component extensible to fix that problem :)
>>>> 
>>>> On the other hand there is an easy fix. Just look at the demo Geoff
>> posted.
>>>> Why do you insist on the BlankOption thing? Just add your blank option
>>>> directly to the list select-options. Then there is no blank option at
>> all...
>>>> 
>>>> 
>>>> Am 13.05.2010 um 16:43 schrieb Benny Law:
>>>> 
>>>>> Thanks Geoff, but no, it doesn't. Your example shows how the Select
>>>>> component works as is. What I need is a smarter interpretation of
>>>>> BlankOption.AUTO. Basically, if you look at the showBlankOption()
>> method
>>>> in
>>>>> the Select class, you see this:
>>>>> 
>>>>>      switch (blankOption)
>>>>>      {
>>>>>          case ALWAYS:
>>>>>              return true;
>>>>> 
>>>>>          case NEVER:
>>>>>              return false;
>>>>> 
>>>>>          default:
>>>>>              return !isRequired();
>>>>>      }
>>>>> 
>>>>> What I want is this:
>>>>> 
>>>>>      switch (blankOption) {
>>>>> 
>>>>>      case ALWAYS:
>>>>>          return true;
>>>>> 
>>>>>      case NEVER:
>>>>>          return false;
>>>>> 
>>>>>      // AUTO: Decide based on model size, current value, and required
>>>> or
>>>>> not.
>>>>>      default:
>>>>>          List<OptionModel> options = model.getOptions();
>>>>> 
>>>>>          if (options.size() == 1) {
>>>>>              return !isRequired();
>>>>>          }
>>>>>          if (options.size() == 0 || value == null) {
>>>>>              return true;
>>>>>          }
>>>>>          if (value != null) {
>>>>>              for (OptionModel option: options) {
>>>>>                  if (option.getValue().equals( value )) {
>>>>>                      return !isRequired();
>>>>>                  }
>>>>>              }
>>>>>          }
>>>>>          return true;
>>>>>      }
>>>>> 
>>>>> I hope it's clear what I want to achieve with the enhanced logic for
>>>> AUTO.
>>>>> 
>>>>> Regards,
>>>>> 
>>>>> Benny
>>>>> 
>>>>> On Thu, May 13, 2010 at 10:29 AM, Geoff Callender <
>>>>> geoff.callender.jumpst...@gmail.com> wrote:
>>>>> 
>>>>>> Does this help at all?
>>>>>> 
>>>>>> 
>>>>>> 
>>>> 
>> http://jumpstart.doublenegative.com.au/jumpstart/examples/select/varied/$N/$N/$N/$N
>>>>>> 
>>>>>> Cheers,
>>>>>> 
>>>>>> Geoff
>>>>>> 
>>>>>> On 14/05/2010, at 12:11 AM, Benny Law wrote:
>>>>>> 
>>>>>>> We are talking about subclassing a Tapestry component here. To give
>> you
>>>>>> an
>>>>>>> example, I wanted to subclass the Select component to override how
>>>>>>> BlankOption.AUTO is interpreted. I wanted the logic to not just look
>> at
>>>>>> the
>>>>>>> required property but also to consider how many options are available
>>>> and
>>>>>>> whether there is a current value. (I find the current logic lacking
>>>>>> because,
>>>>>>> for example, the first option will always be selected as default if
>>>>>> required
>>>>>>> is true, but there may not be a meaningful default for the field.)
>> All
>>>> I
>>>>>>> needed to do was to override the showBlankOption() method, but I
>>>> couldn't
>>>>>>> because it's a private method. I ended up making a duplicate of the
>>>>>> Select
>>>>>>> component with a modified showBlankOption() method. It just didn't
>> feel
>>>>>>> right. I don't think all this talk about capturing common logic in a
>>>> base
>>>>>>> class or creating a service for it applies here.
>>>>>>> 
>>>>>>> In my opinion, a good framework should provide the option for
>> extending
>>>>>> its
>>>>>>> components easily. I believe that with proper design and careful
>>>>>>> consideration, inheritance can still be very useful. Developers
>> should
>>>>>>> understand any potential risks involved in subclassing, but closing
>> the
>>>>>> door
>>>>>>> to subclassing for the sake of backward-compatibility may be an
>>>> overkill
>>>>>>> IMHO. Everything has pros and cons, and the developer is ultimately
>>>>>>> responsible for weighing them and choosing what's best for their
>>>>>> situation.
>>>>>>> 
>>>>>>> BTW, if anyone can think of a clean way to solve my problem with the
>>>>>> Select
>>>>>>> component, please let me know. Thanks.
>>>>>>> 
>>>>>>> Benny
>>>>>> 
>>>>>> 
>>>> 
>>>> 
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>>>> For additional commands, e-mail: users-h...@tapestry.apache.org
>>>> 
>>>> 
>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
>> For additional commands, e-mail: users-h...@tapestry.apache.org
>> 
>> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

Reply via email to