1

Im trying to implement the modification of an entity in JSF using Primefaces.

My main view, which lists the users is the following:

<p:growl id="growlEditUnit" showDetail="true" life="12000" />
    <p:dialog id="dialogEditUnit" header="Edit Unit" widgetVar="editUnitDialog" showEffect="fade" hideEffect="fade" resizable="false" >
        <ui:include src="editUnit.xhtml" />
    </p:dialog>

<h:form id="form2">  

        <p:dataTable id="units" var="unit" value="#{unitController.unitsOfLoggedInUser}" >  

            <f:facet name="header">  
                Click Edit or Delete after selecting a unit to modify or remove it  
            </f:facet>  

            <p:column headerText="Code">  
                #{unit.unitCode}  
            </p:column>  

            <p:column headerText="Name">  
                #{unit.unitName}  
            </p:column>  

            <p:column headerText="Semester" >  
                #{unit.semester}  
            </p:column>  

            <p:column headerText="Academic Year">  
                #{unit.academicYear}  
            </p:column>

            <p:column headerText="Twitter Username">  
                #{unit.twitterUsername}  
            </p:column>

            <p:column headerText="Actions">  
                <p:commandButton id="editButton" value="Edit" action="#{unitController.setCurrent(unit)}" update=":dialogEditUnit" oncomplete"editUnitDialog.show()" />  
            </p:column>  

        </p:dataTable> 


    </h:form>

This view lists all the data correctly. However, when I press the current, my aim is to set the current attribute of the managed bean (code listed below) with the unit based on the button clicked. After this I try to update the edit dialog, so it will be filled with the values of that unit, and then make it visible using the oncomplete attribute. However, it seems that the managed been method setCurrent(unit) is never called when clicking the edit button. Subsequently the dialog is shown empty. Can someone help me with what am I doing wrong? I am posting the managed bean code too.

@ManagedBean(name = "unitController")
@ViewScoped
public class UnitController implements Serializable {

private Unit current;

private List<Unit> unitsOfLoggedInUser;

@ManagedProperty(value="#{loginController.checkedUser}")
private Lecturer lecturer;

@EJB
private web.effectinet.ejb.UnitFacade ejbFacade;
@EJB
private web.effectinet.ejb.LecturerFacade lecturerFacade;

public UnitController() {
}

@PostConstruct
public void init(){
    if (lecturer.getLecturerId() == null)
        unitsOfLoggedInUser = null;
    else
        unitsOfLoggedInUser = (List<Unit>) lecturer.getUnitCollection();
}

public List<Unit> getUnitsOfLoggedInUser() {

        return unitsOfLoggedInUser;

}

public void setCurrent(Unit current) {
    this.current = current;
}

public Lecturer getLecturer() {
    return lecturer;
}

public void setLecturer(Lecturer lecturer) {
    this.lecturer = lecturer;
}
interboy
  • 856
  • 1
  • 11
  • 25
  • Please exclude points 2 until with 5 here: http://stackoverflow.com/questions/2118656/hcommandlink-hcommandbutton-is-not-being-invoked/2120183#2120183 – BalusC Jun 26 '12 at 14:24
  • @BalusC From what you said in the answer below, it seems to be a problem of not calling the action attribute right? From all the points in the above link, it seemed that only 4 was applying to me. However, I tried to fix it as you suggest (setting business rules in the post construct and making it view scoped), but the action attribute is still not called. Can you please have a look at the new code because I edited the question. Any further suggestions? Thank you – interboy Jun 26 '12 at 15:47
  • Are you really positive that the `setCurrent()` method is never called? Have you debugged it? Put a debug breakpoint or a poor man's `System.out.println()` line on that method. Another possible cause could be just a JavaScript error. Check the browser's builtin JavaScript console. Press F12 in Chrome/IE9/Firefox+Firebug. – BalusC Jun 26 '12 at 17:11
  • @BalusC When you told me to check the Java Script console, I had already turned back to the first version of a SessionBean. However, I am noticing a very strange behavior. If Firebug is open (both in Chrome and Firefox), I mean just opened to the Script tab, the method setCurrent gets called. While if it is closed, nothing happens and the method is not called. What could be the cause of this? – interboy Jun 26 '12 at 17:41
  • How exactly are you checking if the `setCurrent()` method is called? Is this based on own assumptions based on behaviour, or based on a real debugger or a sysout/logger line? – BalusC Jun 26 '12 at 17:50
  • No, it is based on a real debugger. I use Netbeans and have put a breakpoint at that method. @BalusC – interboy Jun 26 '12 at 17:52
  • 1
    Okay, then it's a JS problem. Are there any errors in the JS console? What PF version are you using? – BalusC Jun 26 '12 at 17:53
  • @BalusC I was checking again and it is not a matter if the console is open or not. There are no errors in the console. However, from the second and subsequent clicks to the button the POST request contains this (javax.faces.ViewState 3664246302305566926:4150961408954857115). while on the first click there is no view state send. Regarding the behavious, the first time, the debugger does not stop, while from the second and forward it does stop. Im using PrimeFaces 3.2 – interboy Jun 26 '12 at 18:14
  • This confirms point 7, but that should not be a problem in PrimeFaces. Or was you not using a PrimeFaces command link/button to update the datatable, but instead the ``? – BalusC Jun 26 '12 at 18:15
  • No I was using the `` However, I had temporarily removed these attributes from the `commandButton` `update=":dialogEditUnit" oncomplete="editUnitDialog.show()` temporarily. I added them now, but they are not working either if it is the first time that I press the any other time. Really frustrating! @BalusC – interboy Jun 26 '12 at 18:23

1 Answers1

0

The action attribute of the commandButton is rendered without information on the value of the unit variable.

To pass the unit to the action method of your managed bean, then you need to pass the ID of unit in an <f:param> child tag of commandButton.

<p:commandButton action="#{managedBean.actionMethod}" ........>
   <f:param name="unitid" value="#{unit.id}" /> 
</p:commandButton>

From your action method you can get the request parameter by the name from the ExternalContext and this will give you the ID of the unit that the commandButton was pressed for in your dataTable.

maple_shaft
  • 10,435
  • 6
  • 46
  • 74
  • Are you sure about that? Because I am passing the whole unit object in the action method `editUnitController.setCurrent(unit)`. The unit object, which is part of the dataTable elements defines the button to which the unit belonged too. @maple_shaft – interboy Jun 26 '12 at 14:22
  • 1
    It should work just fine. See also #3 of this answer: http://stackoverflow.com/questions/4994458/how-can-i-pass-a-parameter-to-a-commandlink-inside-a-datatable – BalusC Jun 26 '12 at 14:22
  • @BalusC But I am doing the same with what point 3 says, therefore passing the whole object by having a method in the backing bean that accepts that kind of object. However, that method is not being called in the backing bean – interboy Jun 26 '12 at 14:33
  • @BalusC This will only work if using Servlet 3.0 and EL 2.2 but yes you are correct. I don't like to make assumptions. – maple_shaft Jun 26 '12 at 14:34
  • @interboy: Yes, I know. Please read the comment on your question. – BalusC Jun 26 '12 at 14:34
  • @Maple: if OP didn't use EL 2.2, the datatable wouldn't show anything at all. Check its (strange) `value` attribute. – BalusC Jun 26 '12 at 14:34