0

I'm working with JSF and primefaces. I want to update a row when I click on the button (pencil). I used the first code from this tutorial (Primefaces docs), but dosent work in my case. the problem is : when i click the button (pencil) to update a row, nothing change. i have always the old values

This is my JSF code :

<f:view>
    <h:form id="form">
        <p:growl id="msgs" showDetail="true"/>


        <p:dataTable id="tservice" var="item" value="#{serviceMBean.services}" editable="true" style="margin-bottom:20px">
            <f:facet name="header"> edit </f:facet>
            <p:ajax event="rowEdit" listener="#{serviceMBean.onRowEdit}" update=":form:msgs" />
            <p:ajax event="rowEditCancel" listener="#{serviceMBean.onRowCancel}" update=":form:msgs" />
            <p:column headerText="Libelle du service">
                <p:cellEditor>
                    <f:facet name="output"><h:outputText value="#{item.libelleservice}" /></f:facet>
                    <f:facet name="input">
                        <p:inputText value="#{item.libelleservice}" style="width:100%" label="Libelle"/>
                    </f:facet>
                </p:cellEditor>
            </p:column>

            <p:column headerText="Utilisateurs/Service">
                <p:cellEditor>
                    <f:facet name="output"><h:outputText value="#{item.nbruserservice}" /></f:facet>
                    <f:facet name="input">
                        <p:inputText value="#{item.nbruserservice}" style="width:100%" label="Nbre Users"/>
                    </f:facet>
                </p:cellEditor>
            </p:column>

            <p:column style="width:32px">
                <p:rowEditor />

            </p:column>

And this is my managed bean code:

@Named(value = "serviceMBean")
@ViewScoped
public class ServiceMBean implements Serializable {

    private List<Service> serviceList;
    private Service s;

    @EJB
    private ServiceManager serviceManager;

    public ServiceMBean() {}

    public void modifierService(Service s1) {
        this.serviceManager.updateService(s1);
    }

    public void onRowEdit(RowEditEvent event) {
        Service s2 = (Service) event.getObject();
        System.out.println("--->" + s2.getNbruserservice());
        FacesMessage msg = new FacesMessage("Service Modifié", ((Service) event.getObject()).getLibelleservice());
        this.modifierService(s2);
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    public void onRowCancel(RowEditEvent event) {
        FacesMessage msg = new FacesMessage("Modification annulée", ((Service) event.getObject()).getLibelleservice());
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }
}

And this is my code for ServiceManager:

public void updateService(Object service) {
    em.merge(service);
}

I think the setter in my JSF page doesn't work. Any solutions or suggestions?

Tiny
  • 27,221
  • 105
  • 339
  • 599
redoff
  • 1,124
  • 11
  • 18
  • What doesn't work? What do you expect to happen, and what happens instead? – Predrag Maric Dec 15 '14 at 15:20
  • when i click the button (pencil) to update a row, nothing change. i have always the old values – redoff Dec 15 '14 at 15:22
  • Can you please change attribute in your `updateService` function to `ServiceManager` ? `public void updateService(ServiceManager service)` and tell me if it works ? – Silwest Dec 15 '14 at 15:56
  • thank you for answer, but dosent work :(. Actually, ServiceManager it's my session class, and ServiceMBean it's a managedbean – redoff Dec 15 '14 at 16:11
  • The problem is in the jsf or setter, the jsf dont take the new values, because i made this example : `public void onRowEdit(RowEditEvent event) { Service s2 = (Service)event.getObject(); System.out.println("--->"+s2.getNbruserservice()); s2.setNbreUserservice(5); // this the change FacesMessage msg = new FacesMessage("Service Modifié", ((Service) event.getObject()).getLibelleservice()); this.modifierService(s2); FacesContext.getCurrentInstance().addMessage(null, msg); }` and the value 5 is persisted on database, so all the methods works fine – redoff Dec 15 '14 at 16:37
  • The difference between the primefaces example and yours is that you are using CDI, while the primefaces examples work directly on the old fashioned JSF annotations. That ViewScoped annotation is not taken from the wrong package by any chance is it? It must be javax.faces.view.ViewScoped and NOT javax.faces.bean.ViewScoped. ViewScoped in combination with CDI will only work from JSF 2.2 and up. – Gimby Dec 15 '14 at 17:08
  • the import is javax.faces.view.ViewScoped, i think it's the right import like you said – redoff Dec 15 '14 at 17:13
  • It is indeed; too bad as that would have made the problem incredibly easy. Now for a second test: add a PostConstruct annotated method to the ServiceMBean and do a simple System.out.println() in there (or do some logging). While you operate the same page, there should be only one instance of the bean created and as such you get only one System.out print. Is that true or do you get a println for each action you do on the page? – Gimby Dec 15 '14 at 17:16
  • thank you @Gimby for your answer. So i try this : `@PostConstruct public void init(){ System.out.println("->"+s); }` it's give null – redoff Dec 15 '14 at 17:30
  • but i have only one "sys.out" after every refresh of the page – redoff Dec 15 '14 at 17:38
  • thank u @Gimby for your help, after adding a annotated method (@PostConstruct) works fine with some change. i posted the solution below – redoff Dec 15 '14 at 21:28

1 Answers1

0

Solution : Add a void method with @PostConstruct.

Example : @PostConstruct

@PostConstruct
public void initialiser() {
    serviceList = this.getServices();
}
  1. Don't forget the getter and setter of serviceList
  2. In the JSF page, the value of datatable will be : value="#{ServiceMBean.serviceList}"
Tiny
  • 27,221
  • 105
  • 339
  • 599
redoff
  • 1,124
  • 11
  • 18
  • Well my suggestion was only for debugging purposes to see if a new bean wasn't created for every primefaces ajax action... I wouldn't know why adding this method would fix anything specifically. It probably had more to do with how and when you initialize your bean. – Gimby Dec 17 '14 at 15:03
  • i think the getters are called after every ajax event (maybe, i'm not sure). there is 2 solutions, firstly we can use initialization in the constructor for all variables. Or we can work with @PostConstruct. i found this article, so interesting : http://stackoverflow.com/questions/3406555/why-use-postconstruct – redoff Dec 18 '14 at 11:28