FAQ
Hi,

I would like to know your opinion about how to work with DataTable
using MyFaces in the typical example where a list of objects is
presented and a link for each object is generated so as to go to some
kind of maintenance form.

IMHO this can be achieved using several approaches:

1) Bind the DataTable component to a property in a JSF bean; then
create an action in the bean and associate it to the CommandLink so
whenever the link is clicked, the action will be invoked, and you will
be able to get the current object with dataTable.getRowData():

<x:dataTable var="object" binding="#{ObjectBean.objectDataTable}"
preserveDataModel="true">
<h:column>
<x:commandLink action="#{ObjectBean.chooseObjectAction}"
immediate="true">
<x:outputText value="#{object.someProperty}" />
</x:commandLink>
</h:column>
</x:dataTable>

2) Just give the value of the DataTable a collection of objects, but
use an UpdateActionListener to know which object was clicked (as now
you don't have the getRowData() available). This results in a setter
in our JSF bean being invoked when the link is clicked:

<x:dataTable var="object" value="#{ObjectBean.listOfObjects}"
preserveDataModel="true">
<h:column>
<x:commandLink action="nextPage" immediate="true">
<x:outputText value="#{object.someProperty}" />
<x:updateActionListener value="#{object.id}"
property="#{ObjectBean.id}" />
</x:commandLink>
</h:column>
</x:dataTable>

In my tests, the update action method in the JSF bean doesn't get
invoked if I set preserveDataModel="false". Don't know why...

3) Similar to 2, but using request parameters instead of the
UpdateActionListener, that can be later obtained from within the
action in the JSF bean:

<x:dataTable var="object" value="#{ObjectBean.listOfObjects}"
preserveDataModel="true">
<h:column>
<x:commandLink action="#{ObjectBean.chooseObjectAction}"
immediate="true">
<x:outputText value="#{object.someProperty}" />
<f:param value="#{object.id}" />
</x:commandLink>
</h:column>
</x:dataTable>

And then from the JSF bean, get the parameters using the FacesContext
through the getParametersMap() method.

What do you currently use? What do you think is the best approach?
What are the alternatives?

An also, what happens when the DataModel must survive between
different requests, for example, when using tabs? Is the only solution
to make the JSF bean session scoped?

Looking forward to hearing your comments ;-)

Search Discussions

  • Broekelmann, Mathias at May 6, 2005 at 11:54 am
    Hi Enrique,

    I use an instance of javax.faces.model.DataModel as a value for the
    datatable. The value is held by a bean which holds the instance of the
    DataModel. The DataModel instance is used to iterate through the rows of
    the datatable. When an action is called on a row I only have to get the
    current row from the DataModel to find the row on which the action was
    called.

    The JSF-Page contains:

    <h:dataTable value="bean.valuesModel" var="object">
    <h:column>
    <h:commandLink action="#{bean.chooseObjectAction}">
    <x:outputText value="#{object.someProperty}" />
    </h:commandLink>
    </h:column>
    </h:dataTable>

    The Bean contains:

    public class SomeBeanClass
    {
    DataModel mValueModel;

    public DataModel getValuesModel()
    {
    if(mValueModel == null)
    {
    mValueModel = new ListDataModel(initializeValues());
    }
    return mValueModel;
    }

    public String chooseObjectAction()
    {
    Object currentObject = getValuesModel().getRowData();
    }
    }

    Hope this helps a little bit.

    Mathias

    -----Original Message-----
    From: Enrique Medina
    Sent: Thursday, May 05, 2005 6:58 PM
    To: MyFaces Discussion
    Subject: DataTable discussion


    Hi,

    I would like to know your opinion about how to work with DataTable
    using MyFaces in the typical example where a list of objects is
    presented and a link for each object is generated so as to go to some
    kind of maintenance form.

    IMHO this can be achieved using several approaches:

    1) Bind the DataTable component to a property in a JSF bean; then
    create an action in the bean and associate it to the CommandLink so
    whenever the link is clicked, the action will be invoked, and you will
    be able to get the current object with dataTable.getRowData():

    <x:dataTable var="object" binding="#{ObjectBean.objectDataTable}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink action="#{ObjectBean.chooseObjectAction}"
    immediate="true">
    <x:outputText value="#{object.someProperty}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    2) Just give the value of the DataTable a collection of objects, but
    use an UpdateActionListener to know which object was clicked (as now
    you don't have the getRowData() available). This results in a setter
    in our JSF bean being invoked when the link is clicked:

    <x:dataTable var="object" value="#{ObjectBean.listOfObjects}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink action="nextPage" immediate="true">
    <x:outputText value="#{object.someProperty}" />
    <x:updateActionListener value="#{object.id}"
    property="#{ObjectBean.id}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    In my tests, the update action method in the JSF bean doesn't get
    invoked if I set preserveDataModel="false". Don't know why...

    3) Similar to 2, but using request parameters instead of the
    UpdateActionListener, that can be later obtained from within the
    action in the JSF bean:

    <x:dataTable var="object" value="#{ObjectBean.listOfObjects}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink action="#{ObjectBean.chooseObjectAction}"
    immediate="true">
    <x:outputText value="#{object.someProperty}" />
    <f:param value="#{object.id}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    And then from the JSF bean, get the parameters using the FacesContext
    through the getParametersMap() method.

    What do you currently use? What do you think is the best approach?
    What are the alternatives?

    An also, what happens when the DataModel must survive between
    different requests, for example, when using tabs? Is the only solution
    to make the JSF bean session scoped?

    Looking forward to hearing your comments ;-)
  • Enrique Medina at May 6, 2005 at 1:18 pm
    Thanks for your comments Mathias.

    I am currently using both the value and a binding to do it:

    The JSF-Page contains:

    <h:dataTable value="bean.valuesModel" binding="mDataModel" var="object">
    <h:column>
    <h:commandLink action="#{bean.chooseObjectAction}">
    <x:outputText value="#{object.someProperty}" />
    </h:commandLink>
    </h:column>
    </h:dataTable>

    The Bean contains:

    public class SomeBeanClass
    {
    UIData mDataModel;

    // Here goes the setter and the getter for the UIData object.

    public List getValuesModel()
    {
    return initializeValues();
    }

    public String chooseObjectAction()
    {
    Object currentObject = this.mDataModel.getRowData();
    }
    }

    Does this makes sense?
    On 5/6/05, Broekelmann, Mathias wrote:
    Hi Enrique,

    I use an instance of javax.faces.model.DataModel as a value for the
    datatable. The value is held by a bean which holds the instance of the
    DataModel. The DataModel instance is used to iterate through the rows of
    the datatable. When an action is called on a row I only have to get the
    current row from the DataModel to find the row on which the action was
    called.

    The JSF-Page contains:

    <h:dataTable value="bean.valuesModel" var="object">
    <h:column>
    <h:commandLink action="#{bean.chooseObjectAction}">
    <x:outputText value="#{object.someProperty}" />
    </h:commandLink>
    </h:column>
    </h:dataTable>

    The Bean contains:

    public class SomeBeanClass
    {
    DataModel mValueModel;

    public DataModel getValuesModel()
    {
    if(mValueModel == null)
    {
    mValueModel = new ListDataModel(initializeValues());
    }
    return mValueModel;
    }

    public String chooseObjectAction()
    {
    Object currentObject = getValuesModel().getRowData();
    }
    }

    Hope this helps a little bit.

    Mathias

    -----Original Message-----
    From: Enrique Medina
    Sent: Thursday, May 05, 2005 6:58 PM
    To: MyFaces Discussion
    Subject: DataTable discussion


    Hi,

    I would like to know your opinion about how to work with DataTable
    using MyFaces in the typical example where a list of objects is
    presented and a link for each object is generated so as to go to some
    kind of maintenance form.

    IMHO this can be achieved using several approaches:

    1) Bind the DataTable component to a property in a JSF bean; then
    create an action in the bean and associate it to the CommandLink so
    whenever the link is clicked, the action will be invoked, and you will
    be able to get the current object with dataTable.getRowData():

    <x:dataTable var="object" binding="#{ObjectBean.objectDataTable}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink action="#{ObjectBean.chooseObjectAction}"
    immediate="true">
    <x:outputText value="#{object.someProperty}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    2) Just give the value of the DataTable a collection of objects, but
    use an UpdateActionListener to know which object was clicked (as now
    you don't have the getRowData() available). This results in a setter
    in our JSF bean being invoked when the link is clicked:

    <x:dataTable var="object" value="#{ObjectBean.listOfObjects}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink action="nextPage" immediate="true">
    <x:outputText value="#{object.someProperty}" />
    <x:updateActionListener value="#{object.id}"
    property="#{ObjectBean.id}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    In my tests, the update action method in the JSF bean doesn't get
    invoked if I set preserveDataModel="false". Don't know why...

    3) Similar to 2, but using request parameters instead of the
    UpdateActionListener, that can be later obtained from within the
    action in the JSF bean:

    <x:dataTable var="object" value="#{ObjectBean.listOfObjects}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink action="#{ObjectBean.chooseObjectAction}"
    immediate="true">
    <x:outputText value="#{object.someProperty}" />
    <f:param value="#{object.id}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    And then from the JSF bean, get the parameters using the FacesContext
    through the getParametersMap() method.

    What do you currently use? What do you think is the best approach?
    What are the alternatives?

    An also, what happens when the DataModel must survive between
    different requests, for example, when using tabs? Is the only solution
    to make the JSF bean session scoped?

    Looking forward to hearing your comments ;-)
  • Broekelmann, Mathias at May 6, 2005 at 1:51 pm
    - You don't have to use a component binding to get access to the
    datamodel. Simply return an instance of DataModel by the method
    getValuesModel() instead of the List. You can use the existing DataModel
    instances like ListDataModel - see javadoc for more subclasses of
    DataModel.

    - Hold the returned DataModel in an instance variable to get the current
    row of the datatable

    - Keep in Mind: the datatable component uses the same instance of the
    returned DataModel instance to iterate through the rows.

    - I think you just forget it: to use value binding you must wrap the
    statements like this: #{bean.valuesModel}

    Mathias

    -----Original Message-----
    From: Enrique Medina
    Sent: Friday, May 06, 2005 3:18 PM
    To: Broekelmann, Mathias
    Cc: MyFaces Discussion
    Subject: Re: DataTable discussion


    Thanks for your comments Mathias.

    I am currently using both the value and a binding to do it:

    The JSF-Page contains:

    <h:dataTable value="bean.valuesModel" binding="mDataModel"
    var="object">
    <h:column>
    <h:commandLink action="#{bean.chooseObjectAction}">
    <x:outputText value="#{object.someProperty}" />
    </h:commandLink>
    </h:column>
    </h:dataTable>

    The Bean contains:

    public class SomeBeanClass
    {
    UIData mDataModel;

    // Here goes the setter and the getter for the UIData object.

    public List getValuesModel()
    {
    return initializeValues();
    }

    public String chooseObjectAction()
    {
    Object currentObject = this.mDataModel.getRowData();
    }
    }

    Does this makes sense?
    On 5/6/05, Broekelmann, Mathias wrote:
    Hi Enrique,

    I use an instance of javax.faces.model.DataModel as a value for the
    datatable. The value is held by a bean which holds the
    instance of the
    DataModel. The DataModel instance is used to iterate
    through the rows of
    the datatable. When an action is called on a row I only
    have to get the
    current row from the DataModel to find the row on which the
    action was
    called.

    The JSF-Page contains:

    <h:dataTable value="bean.valuesModel" var="object">
    <h:column>
    <h:commandLink action="#{bean.chooseObjectAction}">
    <x:outputText value="#{object.someProperty}" />
    </h:commandLink>
    </h:column>
    </h:dataTable>

    The Bean contains:

    public class SomeBeanClass
    {
    DataModel mValueModel;

    public DataModel getValuesModel()
    {
    if(mValueModel == null)
    {
    mValueModel = new ListDataModel(initializeValues());
    }
    return mValueModel;
    }

    public String chooseObjectAction()
    {
    Object currentObject = getValuesModel().getRowData();
    }
    }

    Hope this helps a little bit.

    Mathias

    -----Original Message-----
    From: Enrique Medina
    Sent: Thursday, May 05, 2005 6:58 PM
    To: MyFaces Discussion
    Subject: DataTable discussion


    Hi,

    I would like to know your opinion about how to work with DataTable
    using MyFaces in the typical example where a list of objects is
    presented and a link for each object is generated so as
    to go to some
    kind of maintenance form.

    IMHO this can be achieved using several approaches:

    1) Bind the DataTable component to a property in a JSF bean; then
    create an action in the bean and associate it to the
    CommandLink so
    whenever the link is clicked, the action will be invoked,
    and you will
    be able to get the current object with dataTable.getRowData():

    <x:dataTable var="object" binding="#{ObjectBean.objectDataTable}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink action="#{ObjectBean.chooseObjectAction}"
    immediate="true">
    <x:outputText value="#{object.someProperty}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    2) Just give the value of the DataTable a collection of
    objects, but
    use an UpdateActionListener to know which object was
    clicked (as now
    you don't have the getRowData() available). This results
    in a setter
    in our JSF bean being invoked when the link is clicked:

    <x:dataTable var="object" value="#{ObjectBean.listOfObjects}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink action="nextPage" immediate="true">
    <x:outputText value="#{object.someProperty}" />
    <x:updateActionListener value="#{object.id}"
    property="#{ObjectBean.id}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    In my tests, the update action method in the JSF bean doesn't get
    invoked if I set preserveDataModel="false". Don't know why...

    3) Similar to 2, but using request parameters instead of the
    UpdateActionListener, that can be later obtained from within the
    action in the JSF bean:

    <x:dataTable var="object" value="#{ObjectBean.listOfObjects}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink action="#{ObjectBean.chooseObjectAction}"
    immediate="true">
    <x:outputText value="#{object.someProperty}" />
    <f:param value="#{object.id}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    And then from the JSF bean, get the parameters using the
    FacesContext
    through the getParametersMap() method.

    What do you currently use? What do you think is the best approach?
    What are the alternatives?

    An also, what happens when the DataModel must survive between
    different requests, for example, when using tabs? Is the
    only solution
    to make the JSF bean session scoped?

    Looking forward to hearing your comments ;-)
  • Enrique Medina at May 6, 2005 at 2:12 pm
    Ok. Thanks for your support. I was a little confused about it ;-)
    On 5/6/05, Broekelmann, Mathias wrote:


    - You don't have to use a component binding to get access to the
    datamodel. Simply return an instance of DataModel by the method
    getValuesModel() instead of the List. You can use the existing DataModel
    instances like ListDataModel - see javadoc for more subclasses of
    DataModel.

    - Hold the returned DataModel in an instance variable to get the current
    row of the datatable

    - Keep in Mind: the datatable component uses the same instance of the
    returned DataModel instance to iterate through the rows.

    - I think you just forget it: to use value binding you must wrap the
    statements like this: #{bean.valuesModel}

    Mathias
    -----Original Message-----
    From: Enrique Medina
    Sent: Friday, May 06, 2005 3:18 PM
    To: Broekelmann, Mathias
    Cc: MyFaces Discussion
    Subject: Re: DataTable discussion


    Thanks for your comments Mathias.

    I am currently using both the value and a binding to do it:

    The JSF-Page contains:

    <h:dataTable value="bean.valuesModel" binding="mDataModel"
    var="object">
    <h:column>
    <h:commandLink action="#{bean.chooseObjectAction}">
    <x:outputText value="#{object.someProperty}" />
    </h:commandLink>
    </h:column>
    </h:dataTable>

    The Bean contains:

    public class SomeBeanClass
    {
    UIData mDataModel;

    // Here goes the setter and the getter for the UIData object.

    public List getValuesModel()
    {
    return initializeValues();
    }

    public String chooseObjectAction()
    {
    Object currentObject = this.mDataModel.getRowData();
    }
    }

    Does this makes sense?
    On 5/6/05, Broekelmann, Mathias wrote:
    Hi Enrique,

    I use an instance of javax.faces.model.DataModel as a value for the
    datatable. The value is held by a bean which holds the
    instance of the
    DataModel. The DataModel instance is used to iterate
    through the rows of
    the datatable. When an action is called on a row I only
    have to get the
    current row from the DataModel to find the row on which the
    action was
    called.

    The JSF-Page contains:

    <h:dataTable value="bean.valuesModel" var="object">
    <h:column>
    <h:commandLink action="#{bean.chooseObjectAction}">
    <x:outputText value="#{object.someProperty}" />
    </h:commandLink>
    </h:column>
    </h:dataTable>

    The Bean contains:

    public class SomeBeanClass
    {
    DataModel mValueModel;

    public DataModel getValuesModel()
    {
    if(mValueModel == null)
    {
    mValueModel = new ListDataModel(initializeValues());
    }
    return mValueModel;
    }

    public String chooseObjectAction()
    {
    Object currentObject = getValuesModel().getRowData();
    }
    }

    Hope this helps a little bit.

    Mathias

    -----Original Message-----
    From: Enrique Medina
    Sent: Thursday, May 05, 2005 6:58 PM
    To: MyFaces Discussion
    Subject: DataTable discussion


    Hi,

    I would like to know your opinion about how to work with DataTable
    using MyFaces in the typical example where a list of objects is
    presented and a link for each object is generated so as
    to go to some
    kind of maintenance form.

    IMHO this can be achieved using several approaches:

    1) Bind the DataTable component to a property in a JSF bean; then
    create an action in the bean and associate it to the
    CommandLink so
    whenever the link is clicked, the action will be invoked,
    and you will
    be able to get the current object with dataTable.getRowData():

    <x:dataTable var="object" binding="#{ObjectBean.objectDataTable}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink action="#{ObjectBean.chooseObjectAction}"
    immediate="true">
    <x:outputText value="#{object.someProperty}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    2) Just give the value of the DataTable a collection of
    objects, but
    use an UpdateActionListener to know which object was
    clicked (as now
    you don't have the getRowData() available). This results
    in a setter
    in our JSF bean being invoked when the link is clicked:

    <x:dataTable var="object" value="#{ObjectBean.listOfObjects}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink action="nextPage" immediate="true">
    <x:outputText value="#{object.someProperty}" />
    <x:updateActionListener value="#{object.id}"
    property="#{ObjectBean.id}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    In my tests, the update action method in the JSF bean doesn't get
    invoked if I set preserveDataModel="false". Don't know why...

    3) Similar to 2, but using request parameters instead of the
    UpdateActionListener, that can be later obtained from within the
    action in the JSF bean:

    <x:dataTable var="object" value="#{ObjectBean.listOfObjects}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink action="#{ObjectBean.chooseObjectAction}"
    immediate="true">
    <x:outputText value="#{object.someProperty}" />
    <f:param value="#{object.id}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    And then from the JSF bean, get the parameters using the
    FacesContext
    through the getParametersMap() method.

    What do you currently use? What do you think is the best approach?
    What are the alternatives?

    An also, what happens when the DataModel must survive between
    different requests, for example, when using tabs? Is the
    only solution
    to make the JSF bean session scoped?

    Looking forward to hearing your comments ;-)
  • Broekelmann, Mathias at May 9, 2005 at 7:23 am
    Hi Enrique,

    I´ve forwarded your mail to the myfaces user list since you have send it to me only.

    You can use the solution for request scoped beans too. You just have to make sure that the datamodel gets initialized if it is null.
    My datamodels are usally filled with rows from a database call. Every time the datamodel needs to be initialized the rows where loaded from the database and the datamodel is initialized again.
    If you need a state between the requests you may use the x:savestate component which allows you to serialize the state of objects during requests.

    Mathias
    -----Original Message-----
    From: Broekelmann, Mathias
    Sent: Monday, May 09, 2005 9:16 AM
    To: MyFaces Discussion
    Subject: FW: DataTable discussion



    -----Original Message-----
    From: Enrique Medina
    Sent: Sunday, May 08, 2005 7:25 PM
    To: Broekelmann, Mathias
    Subject: Re: DataTable discussion


    Hi again,

    I've been making some testing, and I've come the the conclusion that
    your solution only works with session scoped beans, doesn't it?

    What needs to be done so it can work with request scoped beans? I've
    tried to put a setter (setValuesModel), bu it doesn't get called...
    On 5/6/05, Broekelmann, Mathias wrote:


    - You don't have to use a component binding to get access to the
    datamodel. Simply return an instance of DataModel by the method
    getValuesModel() instead of the List. You can use the
    existing DataModel
    instances like ListDataModel - see javadoc for more subclasses of
    DataModel.

    - Hold the returned DataModel in an instance variable to
    get the current
    row of the datatable

    - Keep in Mind: the datatable component uses the same
    instance of the
    returned DataModel instance to iterate through the rows.

    - I think you just forget it: to use value binding you
    must wrap the
    statements like this: #{bean.valuesModel}

    Mathias
    -----Original Message-----
    From: Enrique Medina
    Sent: Friday, May 06, 2005 3:18 PM
    To: Broekelmann, Mathias
    Cc: MyFaces Discussion
    Subject: Re: DataTable discussion


    Thanks for your comments Mathias.

    I am currently using both the value and a binding to do it:

    The JSF-Page contains:

    <h:dataTable value="bean.valuesModel" binding="mDataModel"
    var="object">
    <h:column>
    <h:commandLink action="#{bean.chooseObjectAction}">
    <x:outputText value="#{object.someProperty}" />
    </h:commandLink>
    </h:column>
    </h:dataTable>

    The Bean contains:

    public class SomeBeanClass
    {
    UIData mDataModel;

    // Here goes the setter and the getter for the UIData object.

    public List getValuesModel()
    {
    return initializeValues();
    }

    public String chooseObjectAction()
    {
    Object currentObject = this.mDataModel.getRowData();
    }
    }

    Does this makes sense?
    On 5/6/05, Broekelmann, Mathias wrote:
    Hi Enrique,

    I use an instance of javax.faces.model.DataModel as a
    value for the
    datatable. The value is held by a bean which holds the
    instance of the
    DataModel. The DataModel instance is used to iterate
    through the rows of
    the datatable. When an action is called on a row I only
    have to get the
    current row from the DataModel to find the row on which the
    action was
    called.

    The JSF-Page contains:

    <h:dataTable value="bean.valuesModel" var="object">
    <h:column>
    <h:commandLink action="#{bean.chooseObjectAction}">
    <x:outputText value="#{object.someProperty}" />
    </h:commandLink>
    </h:column>
    </h:dataTable>

    The Bean contains:

    public class SomeBeanClass
    {
    DataModel mValueModel;

    public DataModel getValuesModel()
    {
    if(mValueModel == null)
    {
    mValueModel = new ListDataModel(initializeValues());
    }
    return mValueModel;
    }

    public String chooseObjectAction()
    {
    Object currentObject = getValuesModel().getRowData();
    }
    }

    Hope this helps a little bit.

    Mathias

    -----Original Message-----
    From: Enrique Medina
    Sent: Thursday, May 05, 2005 6:58 PM
    To: MyFaces Discussion
    Subject: DataTable discussion


    Hi,

    I would like to know your opinion about how to work
    with DataTable
    using MyFaces in the typical example where a list of
    objects is
    presented and a link for each object is generated so as
    to go to some
    kind of maintenance form.

    IMHO this can be achieved using several approaches:

    1) Bind the DataTable component to a property in a
    JSF bean; then
    create an action in the bean and associate it to the
    CommandLink so
    whenever the link is clicked, the action will be invoked,
    and you will
    be able to get the current object with
    dataTable.getRowData():
    <x:dataTable var="object"
    binding="#{ObjectBean.objectDataTable}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink
    action="#{ObjectBean.chooseObjectAction}"
    immediate="true">
    <x:outputText value="#{object.someProperty}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    2) Just give the value of the DataTable a collection of
    objects, but
    use an UpdateActionListener to know which object was
    clicked (as now
    you don't have the getRowData() available). This results
    in a setter
    in our JSF bean being invoked when the link is clicked:

    <x:dataTable var="object"
    value="#{ObjectBean.listOfObjects}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink action="nextPage" immediate="true">
    <x:outputText value="#{object.someProperty}" />
    <x:updateActionListener value="#{object.id}"
    property="#{ObjectBean.id}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    In my tests, the update action method in the JSF bean
    doesn't get
    invoked if I set preserveDataModel="false". Don't
    know why...
    3) Similar to 2, but using request parameters instead of the
    UpdateActionListener, that can be later obtained from
    within the
    action in the JSF bean:

    <x:dataTable var="object"
    value="#{ObjectBean.listOfObjects}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink
    action="#{ObjectBean.chooseObjectAction}"
    immediate="true">
    <x:outputText value="#{object.someProperty}" />
    <f:param value="#{object.id}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    And then from the JSF bean, get the parameters using the
    FacesContext
    through the getParametersMap() method.

    What do you currently use? What do you think is the
    best approach?
    What are the alternatives?

    An also, what happens when the DataModel must
    survive between
    different requests, for example, when using tabs? Is the
    only solution
    to make the JSF bean session scoped?

    Looking forward to hearing your comments ;-)
  • Carlos Fernandez at May 20, 2005 at 10:19 pm
    Mathias,

    I am relatively new to JSF and ran across this thread when researching how
    best to leverage the framework.

    I have been developing a sample application using client side state. My
    understanding was that a JSF application should be able to utilize either
    client/server side state - and that using client side state was actually
    preferable during the development phase. Which leads me to my question of
    DataModel serialization.

    Neither DataModel nor any of its concrete subclasses in the JSF spec
    implement serializable. MyFaces includes a number of package private
    DataModel classes for use by various UIData components.

    When you wrote:

    --> If you need a state between the requests you may use the x:savestate
    component which allows you to serialize the state of objects during
    requests.

    Were you referring to serializing the "underlying" data structure from the
    DB (e.g. list, set etc) that is ultimately wrapped by the DataModel? That
    seems to add a bit of unnecessary complexity - another public property to
    manage and the relationship between the datastructure and its DataModel
    wrapper.

    Do you know if there is a compelling reason why DataModel doesn't implement
    serializable? Is this simply a way to discourage people from potentially
    serializing large data sets? Otherwise I will just implement my own set of
    serializable DataModel classes.

    Best regards,

    Carlos

    -----Original Message-----
    From: Broekelmann, Mathias
    Sent: Monday, May 09, 2005 3:23 AM
    To: MyFaces Discussion
    Subject: RE: DataTable discussion

    Hi Enrique,

    I´ve forwarded your mail to the myfaces user list since you have send it to
    me only.

    You can use the solution for request scoped beans too. You just have to make
    sure that the datamodel gets initialized if it is null.
    My datamodels are usally filled with rows from a database call. Every time
    the datamodel needs to be initialized the rows where loaded from the
    database and the datamodel is initialized again.
    If you need a state between the requests you may use the x:savestate
    component which allows you to serialize the state of objects during
    requests.

    Mathias
    -----Original Message-----
    From: Broekelmann, Mathias
    Sent: Monday, May 09, 2005 9:16 AM
    To: MyFaces Discussion
    Subject: FW: DataTable discussion



    -----Original Message-----
    From: Enrique Medina
    Sent: Sunday, May 08, 2005 7:25 PM
    To: Broekelmann, Mathias
    Subject: Re: DataTable discussion


    Hi again,

    I've been making some testing, and I've come the the conclusion that
    your solution only works with session scoped beans, doesn't it?

    What needs to be done so it can work with request scoped beans? I've
    tried to put a setter (setValuesModel), bu it doesn't get called...
    On 5/6/05, Broekelmann, Mathias wrote:


    - You don't have to use a component binding to get access to the
    datamodel. Simply return an instance of DataModel by the method
    getValuesModel() instead of the List. You can use the
    existing DataModel
    instances like ListDataModel - see javadoc for more subclasses of
    DataModel.

    - Hold the returned DataModel in an instance variable to
    get the current
    row of the datatable

    - Keep in Mind: the datatable component uses the same
    instance of the
    returned DataModel instance to iterate through the rows.

    - I think you just forget it: to use value binding you
    must wrap the
    statements like this: #{bean.valuesModel}

    Mathias
    -----Original Message-----
    From: Enrique Medina
    Sent: Friday, May 06, 2005 3:18 PM
    To: Broekelmann, Mathias
    Cc: MyFaces Discussion
    Subject: Re: DataTable discussion


    Thanks for your comments Mathias.

    I am currently using both the value and a binding to do it:

    The JSF-Page contains:

    <h:dataTable value="bean.valuesModel" binding="mDataModel"
    var="object">
    <h:column>
    <h:commandLink action="#{bean.chooseObjectAction}">
    <x:outputText value="#{object.someProperty}" />
    </h:commandLink>
    </h:column>
    </h:dataTable>

    The Bean contains:

    public class SomeBeanClass
    {
    UIData mDataModel;

    // Here goes the setter and the getter for the UIData object.

    public List getValuesModel()
    {
    return initializeValues();
    }

    public String chooseObjectAction()
    {
    Object currentObject = this.mDataModel.getRowData();
    }
    }

    Does this makes sense?
    On 5/6/05, Broekelmann, Mathias wrote:
    Hi Enrique,

    I use an instance of javax.faces.model.DataModel as a
    value for the
    datatable. The value is held by a bean which holds the
    instance of the
    DataModel. The DataModel instance is used to iterate
    through the rows of
    the datatable. When an action is called on a row I only
    have to get the
    current row from the DataModel to find the row on which the
    action was
    called.

    The JSF-Page contains:

    <h:dataTable value="bean.valuesModel" var="object">
    <h:column>
    <h:commandLink action="#{bean.chooseObjectAction}">
    <x:outputText value="#{object.someProperty}" />
    </h:commandLink>
    </h:column>
    </h:dataTable>

    The Bean contains:

    public class SomeBeanClass
    {
    DataModel mValueModel;

    public DataModel getValuesModel()
    {
    if(mValueModel == null)
    {
    mValueModel = new ListDataModel(initializeValues());
    }
    return mValueModel;
    }

    public String chooseObjectAction()
    {
    Object currentObject = getValuesModel().getRowData();
    }
    }

    Hope this helps a little bit.

    Mathias

    -----Original Message-----
    From: Enrique Medina
    Sent: Thursday, May 05, 2005 6:58 PM
    To: MyFaces Discussion
    Subject: DataTable discussion


    Hi,

    I would like to know your opinion about how to work
    with DataTable
    using MyFaces in the typical example where a list of
    objects is
    presented and a link for each object is generated so as
    to go to some
    kind of maintenance form.

    IMHO this can be achieved using several approaches:

    1) Bind the DataTable component to a property in a
    JSF bean; then
    create an action in the bean and associate it to the
    CommandLink so
    whenever the link is clicked, the action will be invoked,
    and you will
    be able to get the current object with
    dataTable.getRowData():
    <x:dataTable var="object"
    binding="#{ObjectBean.objectDataTable}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink
    action="#{ObjectBean.chooseObjectAction}"
    immediate="true">
    <x:outputText value="#{object.someProperty}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    2) Just give the value of the DataTable a collection of
    objects, but
    use an UpdateActionListener to know which object was
    clicked (as now
    you don't have the getRowData() available). This results
    in a setter
    in our JSF bean being invoked when the link is clicked:

    <x:dataTable var="object"
    value="#{ObjectBean.listOfObjects}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink action="nextPage" immediate="true">
    <x:outputText value="#{object.someProperty}" />
    <x:updateActionListener value="#{object.id}"
    property="#{ObjectBean.id}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    In my tests, the update action method in the JSF bean
    doesn't get
    invoked if I set preserveDataModel="false". Don't
    know why...
    3) Similar to 2, but using request parameters instead of the
    UpdateActionListener, that can be later obtained from
    within the
    action in the JSF bean:

    <x:dataTable var="object"
    value="#{ObjectBean.listOfObjects}"
    preserveDataModel="true">
    <h:column>
    <x:commandLink
    action="#{ObjectBean.chooseObjectAction}"
    immediate="true">
    <x:outputText value="#{object.someProperty}" />
    <f:param value="#{object.id}" />
    </x:commandLink>
    </h:column>
    </x:dataTable>

    And then from the JSF bean, get the parameters using the
    FacesContext
    through the getParametersMap() method.

    What do you currently use? What do you think is the
    best approach?
    What are the alternatives?

    An also, what happens when the DataModel must
    survive between
    different requests, for example, when using tabs? Is the
    only solution
    to make the JSF bean session scoped?

    Looking forward to hearing your comments ;-)

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupusers @
categoriesmyfaces
postedMay 5, '05 at 4:58p
activeMay 20, '05 at 10:19p
posts7
users3
websitemyfaces.apache.org

People

Translate

site design / logo © 2019 Grokbase