That is the way it behaves. My problem was how HtmlDataScroller interacts with HtmlDataTable for the functionality I needed.

THe HtmlDataScroller calls the setFirst(new Integer(#)) method on UIData (HtmlDataTable). This erases the EL binding of the HtmlDataTable's first attribute.

UIData:
public int getFirst()
{
 if (_first != null) return first.intValue();
...
}

So, I wanted the "_first" to be always null (I always wanted the first to come from my backing bean, even after the data scroller had been used). Therefore, by extending the HtmlDataTable, I could see if the attribute was value bound, and if so, set the value using that value binding instead of retaining the integer value passed in. So for my custom circumstance, I never wanted _first to come from an integer, instead I wanted it to come from my EL _expression_ and get set via my EL _expression_.

Summary:
There is nothing wrong with the datascroller. The only "short comming" is that it stops value binding expressions from being evaluated on the table once it sets a value on the table due to the way the attributes are checked.

Question:
In property getters of components, the code looks like (taken from UIData):
        if (_rows != null)
            return _rows.intValue();
        ValueBinding vb = getValueBinding("rows");
        Number v = vb != null ? (Number) vb.getValue(getFacesContext()) : null;
        return v != null ? v.intValue() : DEFAULT_ROWS;

In the set method, it simply has:
        _rows = new Integer(rows);
        if (rows < 0)
            throw new IllegalArgumentException("rows: " + rows);

Out of curiosity why is this not:
Getter:
        ValueBinding vb = getValueBinding("rows");
        Number v = vb != null ? (Number) vb.getValue(getFacesContext()) : null;
        return v != null ? v.intValue() : (_rows != null) ? _rows.intValue() : DEFAULT_ROWS;
Setter:
        ValueBinding vb = getValueBinding("rows");
        if (vb != null)
          vb.setValue(getFacesContext(), rows);
        else
        {
          _rows = new Integer(rows);
          if (rows < 0)
              throw new IllegalArgumentException("rows: " + rows);
        }

This way, if the component is bound using EL, anyone setting the value sets the value of the value _expression_ instead of overriding the value with a static value?

I'm sure there is a good reason, but I can't think of one off the top of my head besides the fact that not all properties have the ability to set (which could be coded around I'm sure).

-Andrew

On 4/17/06, Mike Kienenberger <[EMAIL PROTECTED]> wrote:
On 4/17/06, Andrew Robinson <[EMAIL PROTECTED]> wrote:
> Okay, I had to make a workaround and posting this here as an FYI to
> anyone who wants to do the same (or if someone has a better idea). The
> problem is the the default HtmlDataScroller sets the first to a
> integer. I needed the ability to have an EL _expression_ so I could
> get/set this value in a backing bean.
> [...]
> Here is my workaround so that EL would always be used for first.
>
> 1) create a new class that extends
> org.apache.myfaces.component.html.ext.HtmlDataTable
> 2) Override setFirst:
>   @Override
>   public void setFirst(int first)
>   {
>     ValueBinding vb = getValueBinding("first");
>     if (vb != null)
>     {
>       vb.setValue(getFacesContext(), first);
>       return;
>     }
>     else
>       super.setFirst(first);
>   }

The way we've typically handled this situation of
EL-_expression_-or-constant in other attributes is:

    public String getOperator()
    {
        if (_operator != null) return _operator;
        ValueBinding vb = getValueBinding("operator");
        return vb != null ?
_ComponentUtils.getStringValue(getFacesContext(), vb) : null;
    }

    public void setOperator(String operator)
    {
        this._operator = operator;
    }

Then in the component code, we only use "getOperator()" rather than
directly access the _operator instance variable.

If datascroller isn't working this way, please open a JIRA issue with
a similar patch.

Reply via email to