eventSelectListener null in @ViewScoped managed bean

UI Components for JSF
Post Reply
ufasoli
Posts: 42
Joined: 05 May 2010, 19:55

21 Jun 2010, 17:14

Hi I'm having some problems when using the p:schedule component coupled with a ViewScoped managed bean, each time an event is selected the appropriate method is called but "getScheduleEvent()" returns always null.

If I change my managed bean to Session scoped I don't have his problem anymore.

Am I doing something wrong ?

here is my code :

Code: Select all


@ManagedBean(name = "validationConges")
@ViewScoped
@RolesAllowed({"admin", "dirigeant"})
public class ValidationCongesMBean implements Serializable {

    @ManagedProperty(value = "#{sessionBean}")
    private SessionMBean sessionBean;
   
    private DefaultScheduleEvent selected;
    private DefaultScheduleModel model;


    @PostConstruct
    public void init() {



 model = new DefaultScheduleModel();
            model.addEvent(new DefaultScheduleEvent("test", new Date(), new Date(), new Conge()));
            List<Conge> congesEnAttente = dbFinder.findAllWhere(
                    Conge.class,
                    String.format(
                    "e.validateur.idUtilisateur = %s AND e.etat.etat = 'EN_ATTENTE'", sessionBean.getUser().getIdUtilisateur()),
                    0,
                    0,
                    null);

            int i = 1;
            for (Conge c : congesEnAttente) {

                for (IntervaleConge ic : c.getIntervales()) {

                    DefaultScheduleEvent event = new DefaultScheduleEvent(ic.getTypeConge().getNom(), ic.getDateDebut(), ic.getDateFin());
                    event.setStyleClass("resource-" + i);

                    model.addEvent(event);

                }
                i++;
            }

    }




    public void onEventSelect(ScheduleEntrySelectEvent selectEvent) {



        this.selected = (DefaultScheduleEvent) selectEvent.getScheduleEvent();



    }

   
}

here is my xhtml page

Code: Select all

<p:schedule eventSelectListener="#{validationConges.onEventSelect}" value="#{validationConges.model}" draggable="false" editable="true"
                            id="conges-en-attente"/>

I'm using glassfish V3, JSF2 and Primefaces 2.0.2

cagatay.civici
Prime
Posts: 18616
Joined: 05 Jan 2009, 00:21
Location: Cybertron
Contact:

21 Jun 2010, 19:27

Strange, online example also uses view scope.

ufasoli
Posts: 42
Joined: 05 May 2010, 19:55

22 Jun 2010, 09:15

yes it's strange, what I've realized is that the first time I select an event a new instance of the ViewScoped is created, the second time I select an event this does not happen, however the result is always the same I always get null "getScheduleEvent()" :(

ufasoli
Posts: 42
Joined: 05 May 2010, 19:55

23 Jun 2010, 10:55

Ok so I've managed to solve my problem by using an eventListener

Code: Select all

      <p:schedule eventSelectListener="#{validationConges.onEventSelect}" value="#{validationConges.model}" draggable="false" editable="true"
                            id="conges-en-attente" widgetVar="mySchedule"
                            onEventSelectUpdate="conges-en-attente,msg,selection-conge-container" initialDate="#{validationConges.dateDebutSchedule}">
                    <f:event listener="#{validationConges.preRenderSchedule}" type="preRenderComponent"/>
                </p:schedule>
I'm having another problem though, I'm trying to attach a ContextMenu to the schedule, but if I use the 'for' attribute I get :

Code: Select all

javax.faces.FacesException: Cannot find component 'conges-en-attente' in view.
if I place them inside the same form (the schedule and contextMenu) it works but when I update the schedule after a user selects an event the context menu stops working (it shows up, but when I click on an action the ajax request is not fired).
here is the code for the context menu :

Code: Select all

 <h:form prependId="false">
                <p:contextMenu for="conges-en-attente"  widgetVar="ctxMenu" id="ctx-menu"  >

                    <p:menuitem action="#{validationConges.setCongeState('VALIDE')}" value="Accepter" update="conges-en-attente,msg,selection-conge-container" />
                    <p:menuitem value="Refuser" action="#{validationConges.setCongeState('REFUSE')}" update="conges-en-attente,msg,selection-conge-container" />
                </p:contextMenu>
            </h:form>
any Ideas?

cagatay.civici
Prime
Posts: 18616
Joined: 05 Jan 2009, 00:21
Location: Cybertron
Contact:

23 Jun 2010, 12:01

New viewscope created? that should not happen, can you post validationConges code?

ufasoli
Posts: 42
Joined: 05 May 2010, 19:55

23 Jun 2010, 14:16

sorry there was a typo, what I meant is that a new instance of the ViewScoped managed bean is created.

Here is the code for the managed bean, before I changed it in order to implement the eventListener

Code: Select all


@ManagedBean(name = "validationConges")
@ViewScoped
@RolesAllowed({"admin", "dirigeant"})
public class ValidationCongesMBean implements Serializable {

    @ManagedProperty(value = "#{sessionBean}")
    private SessionMBean sessionBean;
    @EJB
    private DBFinderBean dbFinder;
    @EJB
    CongeBean congeBean;
    private LazyDataModel<Conge> conges = null;
    private Conge selected;
    private DefaultScheduleModel model;
    private Date dateDebutSchedule = new Date();


   @PostConstruct
    public void init() {

                
        model = new DefaultScheduleModel();

       // Database query
        List<Conge> congesEnAttente = dbFinder.findAllWhere(
                Conge.class,
                String.format(
                "e.validateur.idUtilisateur = %s AND e.etat.etat = 'EN_ATTENTE'", sessionBean.getUser().getIdUtilisateur()),
                0,
                0,
                null);

        int i = 1;
        for (Conge c : congesEnAttente) {


            for (IntervaleConge ic : c.getIntervales()) {

                DefaultScheduleEvent event = new DefaultScheduleEvent(ic.getTypeConge().getNom() + "(" + c.getEtat().getEtat() + ")", ic.getDateDebut(), ic.getDateFin(), c);

                if (selected != null && c.getIdConge() == selected.getIdConge()) {

                    event.setStyleClass("current-conge");
                } else {

                    event.setStyleClass("resource-" + i);
                }


                model.addEvent(event);

            }
            i++;
        }





    }


    public void onEventSelect(ScheduleEntrySelectEvent selectEvent) {


        DefaultScheduleEvent selectedEvent = (DefaultScheduleEvent) selectEvent.getScheduleEvent();
        this.selected = (Conge)selectedEvent.getData();

     

        if (this.selected != null) {

            this.dateDebutSchedule = selectedEvent.getStartDate();


        }
        Conge selectedConge = dbFinder.findById(Conge.class, ((Conge)this.selected.getData()).getIdConge());

        for(ScheduleEvent event : model.getEvents()){

            DefaultScheduleEvent ev = (DefaultScheduleEvent) event;

            if(((Conge)ev.getData()).getIdConge() == selectedConge.getIdConge()){

                ev.setStyleClass("current-conge");
                model.updateEvent(ev);
            }

        }

    }


}



panda
Posts: 6
Joined: 27 Oct 2010, 04:15

27 Oct 2010, 04:22

I have exactly the same problem, ScheduleEntrySelectEvent#getScheduleEvent() returns null in request scope while it works when I switch the bean to session scope. I believe the reason why it works in the showcase example is that eventModel is populated in the constructor with identically events each time the bean is instantiated.

Shall I raise an issue for this?

JSF2/PrimeFaces 2.1

panda
Posts: 6
Joined: 27 Oct 2010, 04:15

05 Nov 2010, 09:24

I solved the issue now as follows:
(1) created a custom DefaultScheduleEvent implementation that allows me to specify my own ids for ScheduleEvents (instead of relying on the DefaultScheduleModel to create ids in the addEvent() method using UUIDs)
(2) created a custom LazyScheduleModel that overwrites the getEvent() method and fetches the data (based on the id) from the underlying persistence store should it not be found in the current instance of the LazyScheduleModel

Code: Select all

	private class LazyDefaultScheduleEvent extends DefaultScheduleEvent {
		public LazyDefaultScheduleEvent(final String id, final String title, final Date start, final Date end, final Object data) {
			super(title, start, end, data);
			super.setId(id);
		}

		@Override
		public String getId() {
			return super.getId();
		}

		@Override
		public void setId(final String id) {
// don't let DefaultScheduleModel#addEvent() overwrite the id set in the ctor
		}
	}

Code: Select all

	private class LazyGroupReservationScheduleModel extends LazyScheduleModel {
		@Override
		public ScheduleEvent getEvent(final String id) {
			ScheduleEvent scheduleEvent = super.getEvent(id);
			if (null != scheduleEvent) {
				return scheduleEvent;
			}

			long groupReservationId = Long.valueOf(id);
			GroupReservationBean groupReservationBean = groupReservationService.retrieveGroupReservation(groupReservationId);
			return createScheduleEvent(groupReservationBean);
		}
Things would be easier if DefaultScheduleModel would provide a way to supply custom ids, or if at least the member variable events would be protected (and not private). Would appreciate if support for custom id generators would be added in one of the next releases.

JSF2/PrimeFaces 2.1/Majorra 2.0.2

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 57 guests