MyFaces Tomahawk
  1. MyFaces Tomahawk
  2. TOMAHAWK-1610

schedule not reacting to mouseListener setting

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.1.11
    • Fix Version/s: 1.1.12
    • Component/s: Schedule
    • Labels:
      None
    • Environment:
      myfaces 2.0, myfaces 2.1, tomcat 7.x, facelets, any OS

      Description

      I'm trying to handle mouse click events over schedule entries in t:schedule
      Tomahawk component. In the page definition I have:

      <t:schedule value="#

      {allEvents.model}

      " id="myEvents" rendered="true" readonly="false" theme="#

      {allEvents.theme}

      " tooltip="true" mouseListener="#

      {allEvents.clicked}

      " entryRenderer="#

      {allEvents.renderer}

      " headerDateFormat="#

      {allEvents.headerDateFormat}

      " expandToFitEntries="true" splitWeekend="false" />

      and the method is defined as:

      public String clicked( ScheduleMouseEvent event ) { switch( event.getEventType() ) ...

      Originally, method "clicked" was void, but I changed this to returning String,
      after looking at the source code of the ScheduleTagHandler class,
      "createMetaRuleset" method.

      However, in either case, it doesn't work. "clicked" method never gets invoked,
      and in logs I can't find anything that would indicate if something was wrong.

      I was using MyFaces JSF 2.0, then upgraded to JSF 2.1 - no change. t:schedule
      component works in every aspect (i.e. displaying entries, asking for new entries
      when the model changes selectedDate etc etc) EXCEPT for capturing mouse clicks.

      This problem is present regardless of whether the component is used in facelets environment or not.

      I started a thread with this question on myfaces users mailing list. It seems that org.apache.myfaces.custom.schedule.ScheduleTagHandler defines "mouseListener" attribute handling, but it seems that in component definition for org.apache.myfaces.UISchedule class "mouseListener" is replaced with "mouseListenerExpression"

      I'm not an expert in low level component wiring, but there seems to be some discrepancy there.

        Activity

        Hide
        Leonardo Uribe added a comment -

        Thanks for the details about the issue. It helps to find what's going on.

        The bug is inside org.apache.myfaces.custom.facelets.tag.MethodRule. The original implementation in facelets 1.1.1.14 deals with MethodBinding, but when the code was moved into myfaces, all JSF 1.1 expression language code was removed, so the implementation inside tomahawk is incomplete, and needs to include the old code that deals with JSF 1.1 expression language.

        ScheduleTagHandler code is ok. But we can do it better in that part, doing some small changes over MethodRule and invoking directly to setMouseListenerExpression and skipping some wrappers.

        I checked the code in the event handling and it is ok. Unfortunately, the check for readOnly/disabled before publish events in AbstractScheduleRenderer.decode() is intentional, so it is not possible to change it by backward compatibility.

        Checking the code the event is correctly propagated, and follows JSF spec about event processing (it broadcast events and call listeners on INVOKE_APPLICACION_PHASE), so that part is also ok.

        Show
        Leonardo Uribe added a comment - Thanks for the details about the issue. It helps to find what's going on. The bug is inside org.apache.myfaces.custom.facelets.tag.MethodRule. The original implementation in facelets 1.1.1.14 deals with MethodBinding, but when the code was moved into myfaces, all JSF 1.1 expression language code was removed, so the implementation inside tomahawk is incomplete, and needs to include the old code that deals with JSF 1.1 expression language. ScheduleTagHandler code is ok. But we can do it better in that part, doing some small changes over MethodRule and invoking directly to setMouseListenerExpression and skipping some wrappers. I checked the code in the event handling and it is ok. Unfortunately, the check for readOnly/disabled before publish events in AbstractScheduleRenderer.decode() is intentional, so it is not possible to change it by backward compatibility. Checking the code the event is correctly propagated, and follows JSF spec about event processing (it broadcast events and call listeners on INVOKE_APPLICACION_PHASE), so that part is also ok.
        Hide
        milan durovic added a comment -

        One more thing: while testing handling of SCHEDULE_ENTRY_CLICKED type of ScheduleMouseEvent listener I noticed another anomaly: the schedule model's "selectedEntry" was updated AFTER the event handler was invoked. I think this should be done BEFORE, so that model state is up to date when the event handler is invoked. See this code section:

        case ScheduleMouseEvent.SCHEDULE_ENTRY_CLICKED:
        clickedEntry = model.getSelectedEntry();
        ScheduleEntry realOne = component.getSubmittedEntry();
        log.warn( "Selected component: " + realOne.getTitle() );
        break;

        the model.getSelectedEntry() call returns the entry that was selected when the PREVIOUS event was handled. The UISchedule component, on the other hand, has the correct entry in getSubmittedEntry() method.

        I guess the simple fix for this is that the component updates the model's selected entry as soon as possible, and definitely BEFORE calling even listeners.

        Show
        milan durovic added a comment - One more thing: while testing handling of SCHEDULE_ENTRY_CLICKED type of ScheduleMouseEvent listener I noticed another anomaly: the schedule model's "selectedEntry" was updated AFTER the event handler was invoked. I think this should be done BEFORE, so that model state is up to date when the event handler is invoked. See this code section: case ScheduleMouseEvent.SCHEDULE_ENTRY_CLICKED: clickedEntry = model.getSelectedEntry(); ScheduleEntry realOne = component.getSubmittedEntry(); log.warn( "Selected component: " + realOne.getTitle() ); break; the model.getSelectedEntry() call returns the entry that was selected when the PREVIOUS event was handled. The UISchedule component, on the other hand, has the correct entry in getSubmittedEntry() method. I guess the simple fix for this is that the component updates the model's selected entry as soon as possible, and definitely BEFORE calling even listeners.
        Hide
        milan durovic added a comment -

        me again. I managed to get mouse clicks handled, but the bug is still there and needs addressing. I'll provide the details of what I did with a hope it may give a hint to the maintainer where to fix the problem.

        First of all, documentation needs to be updated to reflect the fact that no mouse events will be handled UNLESS schedule is editable ("readonly" set to "false" AND "submitOnClick" is set to "true"). I don't quite understand what the meaning of "readonly" is, ie. how its setting affects component behaviour.

        Anyway, in addition to setting those flags, I decided to set mouseListenerExpression in HtmlSchedule myself. So, I defined "binding" attribute on schedule component like:

        <t:schedule value="#

        {allEvents.model}

        " id="myEvents"
        binding="#

        {allEvents.component}

        "
        rendered="true" readonly="false"
        ...

        and then in the backing bean code:

        public void setComponent( HtmlSchedule c )
        {
        Class<?>[] params =

        { ScheduleMouseEvent.class }

        ;
        component = c;
        // try to hook mouse listener here
        c.setMouseListenerExpression( ExpressionFactory.newInstance().createMethodExpression( FacesContext.getCurrentInstance().getELContext(), "#

        {allEvents.clicked}

        ", null, params ) );
        }

        after that, it mouse clicks handling worked like a charm. I suppose proper setting of mouseListenerExpression somewhere in tag handler for schedule component has not been done properly. I don't know the details of MyFaces architecture, but by looking at the code I have impression that the maintainer tried to keep backward compatibility with the old schedule component's attribute "mouseListener", but somewhere it failed to create the correct setting.

        Please let me know when this is fixed so that I can remove this temporary fix.

        By the way, I think that handling of mouse events should be allowed regardless of "readonly" setting. What if I don't want to edit the schedule, but I do want to redirect the user to a page with more details that is related to a particular entry clicked? It would be very useful.

        Thanks,
        Milan Durovic

        Show
        milan durovic added a comment - me again. I managed to get mouse clicks handled, but the bug is still there and needs addressing. I'll provide the details of what I did with a hope it may give a hint to the maintainer where to fix the problem. First of all, documentation needs to be updated to reflect the fact that no mouse events will be handled UNLESS schedule is editable ("readonly" set to "false" AND "submitOnClick" is set to "true"). I don't quite understand what the meaning of "readonly" is, ie. how its setting affects component behaviour. Anyway, in addition to setting those flags, I decided to set mouseListenerExpression in HtmlSchedule myself. So, I defined "binding" attribute on schedule component like: <t:schedule value="# {allEvents.model} " id="myEvents" binding="# {allEvents.component} " rendered="true" readonly="false" ... and then in the backing bean code: public void setComponent( HtmlSchedule c ) { Class<?>[] params = { ScheduleMouseEvent.class } ; component = c; // try to hook mouse listener here c.setMouseListenerExpression( ExpressionFactory.newInstance().createMethodExpression( FacesContext.getCurrentInstance().getELContext(), "# {allEvents.clicked} ", null, params ) ); } after that, it mouse clicks handling worked like a charm. I suppose proper setting of mouseListenerExpression somewhere in tag handler for schedule component has not been done properly. I don't know the details of MyFaces architecture, but by looking at the code I have impression that the maintainer tried to keep backward compatibility with the old schedule component's attribute "mouseListener", but somewhere it failed to create the correct setting. Please let me know when this is fixed so that I can remove this temporary fix. By the way, I think that handling of mouse events should be allowed regardless of "readonly" setting. What if I don't want to edit the schedule, but I do want to redirect the user to a page with more details that is related to a particular entry clicked? It would be very useful. Thanks, Milan Durovic

          People

          • Assignee:
            Leonardo Uribe
            Reporter:
            milan durovic
          • Votes:
            1 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development