0

I am using primefaces for not so long and Ive found that I cant use a <p:commandButton /> because it just can't reach the method, the method is ok, I tried it out of the table (and the subtable) and it works perfectly there (everything is inside a form) , the problem is that I need the user to be able to select all the subtable, so, I thought maybe with a button that could be possible, but seems like subtable doesn't allow that, any other way I can do this? or maybe I have to use another way for call my method from a subtable, anybody knows about it?

Thanks

some of my code

<h:form>
    <p:messages id="messages" showDetail="true" autoUpdate="true" closable="true" />  
    <p:dataTable id="case" var="ticket" value="#{CaseBean.selectedCase.tickets}">
        <p:columnGroup>
            <p:row>
                <p:column> Action:</p:column>
                <p:column>
                    <!-- This doesn't work, removed. -->
                    <p:commandButton value="Aprove" action="#{CaseBean.acept()}">
                    </p:commandButton>
                </p:column>
            </p:row>
        </p:columnGroup>

        <p:subTable var="detail" value="#{ticket.detail}">
            <f:facet name="header">
                Resume:
            </f:facet>
            <!-- some data... -->
            <p:column>
                <!-- doesn't work either -->
                <p:commandButton value="Aprove" action="#{CaseBean.aceptTicket()}">
                </p:commandButton>
            </p:column>
<!-- show my data -->

The table works perfectly, it shows all the data, the log files doesn't show any error, so, when I tried to write my commandButton out of the table it worked perfectly, if I cant write it inside a subtable its ok, but , how could I write it in the table? it doesn't show up there either.

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
jpganz18
  • 5,508
  • 17
  • 66
  • 115
  • What do you mean with *select all the subtable*? How do you select the items in the first instance. – Luiggi Mendoza Oct 21 '12 at 01:12
  • I want to set a button inside the table or the subtable that will call a method , sending the attribute (id or something) of one subtable (the one I want to select) – jpganz18 Oct 21 '12 at 01:16
  • Your code looks fine, but you say the command button doesn't show in the table nor subtable? Very odd behavior. Also,it should work if you wrap the datatable in a single form. – Luiggi Mendoza Oct 21 '12 at 01:41
  • actually the first columnGroup is not being showed... the button works when I write it out of the table , or when I delete the subtable :s but inside doesnt – jpganz18 Oct 21 '12 at 01:52
  • I don't have time for a long answer, but try creating a wrapper object that has your method in it such that for each row your object has a method->listener. This makes sure the target is appropriate and simplifies the html. If your table used "data" as the var it might look like actionListener="data.doSomething" – Daniel B. Chapman Oct 22 '12 at 04:49
  • Thanks... checking around I noticed the subtable is not a mature component yet (they say it) , so, I think some events are not being caught when is on a subtable, unfortunately actionaListener didnt work either :s – jpganz18 Oct 22 '12 at 14:34

4 Answers4

1

you welcome :) But if i was you I wouldn't use subtables, Ill think for another solution..maybe Ill do it this way, ill use two different data tables, the first contains the parent list and the second one contains the child list elements, and every selection made triggers an update of the second table...I tried it on my IDE and it works just fine

<h:form id="form">
<p:dataTable var="cas" value="#{beanCase.myListOfCase}"
    selection="#{beanCase.selectedCase}" rowKey="#{cas.idCase}"
    selectionMode="single">
    <p:ajax event="rowSelect" update=":form:TicketTable" />
    <p:column headerText="Id Case">
        <h:outputText value="#{cas.idCase}" />
    </p:column>
    <p:column headerText="Case Name ">
        <h:outputText value="#{cas.caseName}" />
    </p:column>
    <p:column headerText="Case Detail">
        <h:outputText value="#{cas.caseDetail}" />
    </p:column>
    <p:column headerText="Action">
        <p:commandButton value="Accept Case" update=":form:TicketTable"></p:commandButton>
    </p:column>
</p:dataTable>
<p:dataTable id="TicketTable" var="ticket"
    value="#{beanCase.selectedCase.tickets}">
    <p:column headerText="Ticket Number">
        <h:outputText value="#{ticket.idTicket}" />
    </p:column>
    <p:column headerText="Ticket Details">
        <h:outputText value="#{ticket.labelTicket}" />
    </p:column>
    <p:column headerText="show">
        <h:outputText value="#{ticket.show}" />
    </p:column>
    <p:column headerText="this show is brought to you by">
        <h:outputText value="#{ticket.sponsor}" />
    </p:column>
    <p:column headerText="Make a Reservation">
        <p:commandButton value="Buy" action="#{beanCase.buyTicket()}">
            <f:setPropertyActionListener value="#{ticket}"
                target="#{beanCase.selectedTicket}" />
        </p:commandButton>
    </p:column>
</p:dataTable>

before that you must create the data model classes for the Case and ticket

public class CaseDataModel extends ListDataModel<Case> implements
    SelectableDataModel<Case> {
CaseDAO caseDAO = new CaseDAO();

public CaseDataModel() {
}

public CaseDataModel(List<Case> cases) {
    super(cases);
}

@Override
public Case getRowData(String arg0) {
    List<Case> listOfMyObjet = (List<Case>) caseDAO.findAll();
    for (Case obj : listOfMyObjet) {
        if (String.valueOf(obj.getIdCase()).equals(arg0))
            ;
        return obj;
    }
    return null;
}

@Override
public String getRowKey(Case arg0) {
    return String.valueOf(arg0.getIdCase());
}

}

  • Thank you, that is also a good solution!! I decided to make it with one table and then one actionlistener, on the oncomplete I call to a dialog that displays the detail (what a subtable had)... I think was the best and easy option, i just didnt see it from first ... thanks for the help! – jpganz18 Oct 23 '12 at 14:37
0

The first columnGroup is not rendered because in your first row the number of columns is 2, one for "action" and the other for the commandButton while in your subtable you just used two rows one for "Resume" and other contains only one Column for the other commandButton. The number of columns should be the same in every row, so you must use colspan or rowspan to make sure of that. As for the rest using a DataTable will do the job, I didn't understand what you wanna do exactly but I all assume that you want to select myObject from displayed list of objects within a dataTable. So in order to achieve that, the UidataTable must return an object to the backed Bean.

public class myObjectDataModel extends ListDataModel<myObject> implements SelectableDataModel<myObject> {    

    public myObjectDataModel() {  
    }  

    public myObjectDataModel(List<myObject> data) {  
        super(data);  
    }  

    @Override  
    public myObject getRowData(String rowKey) {         
       List<myObject> listOfMyObjet = (List<myObject>) yourDao.getListOfmyOjects();//get your list

        for(myObject obj : listOfMyObjet) {  
            if(obj.getIdObject().equals(rowKey))  
                return obj;  
        }  

        return null;  
    }  

    @Override  
    public Object getRowKey(myObject obj) {  
        return obj.getIdObject();  
    }
}

The backed bean:

public class tableBean {
    private List<myObject> _Objects;
    private myObjectDataModel myListOfObjects;
    private myObject selectedObject;
    //getters and setters
    public tableBean(){
        myObjectDataModel = new myObjectDataModel(_Objects);
    }
    //...
}

xhtml:

<p:dataTable id="table" var="case"
    value="#{tableBean.myObjectDataModel}"
    selection="#{tableBean.selectedObject}" selectionMode="single"
    rowKey="#{case.IdObject}">
    <p:column>

        <p:commandButton value="
    Aprove" action="#{tableBean.someMethod()}">
        </p:commandButton>
    </p:column>

</p:dataTable>

and make sure to use Ajax — commandButton update attribute, or <p:ajax> — to refresh your UI.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 1
    thanks for the answer, but i need to use subtables... or maybe not, this is want i want to do... I have an object... it has some attributes that i want to show, and it has a list on it, and each list has other list, so, thats why i am basically using subtables, to show all the content of a table and the subtable...and I want to have one button to select the subtable – jpganz18 Oct 21 '12 at 20:21
0

Try removing the p:columnGroup from your JSF page. You don't need it for this (and this might be the cause of your problem). Think of it like this: a table exists of rows and rows exist of columns. ;-)

siebz0r
  • 18,867
  • 14
  • 64
  • 107
0

The #{CaseBean} has got to be in the view scope in order to get this to work, or if you want to keep it request scoped, the #{CaseBean.selectedCase.tickets} has to prepared in the (post)constructor on some request parameters so that it's exactly the same as it was during displaying the table.

When the form is submitted, JSF will namely reiterate over the table in order to find the command component responsible for the action. However, if the bean is request scoped and the value behind #{CaseBean.selectedCase} or #{CaseBean.selectedCase.tickets} is not the same as it was during displaying the table, then JSF won't be able to identify the button which invoked the action.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555