ICEfaces
  1. ICEfaces
  2. ICE-7020

Pull down menus of popup calendar don't work with MyFaces

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 2.0.2
    • Fix Version/s: 2.1-Beta, 3.0
    • Component/s: ICE-Components
    • Labels:
      None
    • Environment:
      ICEfaces 2 MyFaces

      Description

      When running the compat Component Showcase, when you use down the month and year pulldowns of the popup calender, the selection reverts back to the default values (current month and year).

        Issue Links

          Activity

          Hide
          Deryk Sinotte added a comment -

          The reason is that the HtmlSelectOneMenus that are used internally in the SelectInputDateRenderer are not getting the proper client id. They are rendering out:

          id="popupDatePttrn1_sm"

          instead of:

          id="iceform:popupDatePttrn1_sm"

          The missing portion is the id for the naming container. The reason turns out to be the order of operations for dynamically adding and removing the component itself. In SelectInputDateRenderer methods .writeMonthDropdown and writeYearDropdown, the items are added to the menu before the menu is added to the calendar:

          HtmlSelectOneMenu dropDown = new HtmlSelectOneMenu();
          dropDown.setId(component.getId() + SELECT_MONTH);
          dropDown.setPartialSubmit(true);
          dropDown.setTransient(true);
          dropDown.setImmediate(component.isImmediate());
          dropDown.setDisabled(component.isDisabled() || component.isReadonly());
          dropDown.setStyleClass(component.getMonthYearDropdownClass());

          UISelectItem selectItem;
          Calendar calendar;
          int currentMonth = timeKeeper.get(Calendar.MONTH);
          for (int i = 0; i < months.length; i++) {
          selectItem = new UISelectItem();
          calendar = shiftMonth(facesContext, timeKeeper, currentDay, i - currentMonth);
          selectItem.setItemValue(converter.getAsString(facesContext, component, calendar.getTime()));
          selectItem.setItemLabel(months[i]);
          dropDown.getChildren().add(selectItem);
          if (i == currentMonth)

          { dropDown.setValue(selectItem.getItemValue()); }
          }

          //The menu is added as a child of the calendar after the menu items are set. This works in Mojarra but not MyFaces
          component.getChildren().add(dropDown);
          dropDown.encodeBegin(facesContext);
          dropDown.encodeChildren(facesContext);
          dropDown.encodeEnd(facesContext);
          component.getChildren().remove(dropDown);


          MyFaces doesn't like this because adding the menu to the calendar has the side effect of setting the parent and allowing the client id to be calculated. To appease both MyFaces and Mojarra, we just have to move the logic adding the menu to the calendar before we start setting the actual menu items:

          HtmlSelectOneMenu dropDown = new HtmlSelectOneMenu();
          dropDown.setId(component.getId() + SELECT_MONTH);
          dropDown.setPartialSubmit(true);
          dropDown.setTransient(true);
          dropDown.setImmediate(component.isImmediate());
          dropDown.setDisabled(component.isDisabled() || component.isReadonly());
          dropDown.setStyleClass(component.getMonthYearDropdownClass());

          //Add the menu to the calendar's children before adding any menu items.
          component.getChildren().add(dropDown);

          UISelectItem selectItem;
          Calendar calendar;
          int currentMonth = timeKeeper.get(Calendar.MONTH);
          for (int i = 0; i < months.length; i++) {
          selectItem = new UISelectItem();
          calendar = shiftMonth(facesContext, timeKeeper, currentDay, i - currentMonth);
          selectItem.setItemValue(converter.getAsString(facesContext, component, calendar.getTime()));
          selectItem.setItemLabel(months[i]);
          dropDown.getChildren().add(selectItem);
          if (i == currentMonth) { dropDown.setValue(selectItem.getItemValue()); }

          }

          dropDown.encodeBegin(facesContext);
          dropDown.encodeChildren(facesContext);
          dropDown.encodeEnd(facesContext);
          component.getChildren().remove(dropDown);

          Show
          Deryk Sinotte added a comment - The reason is that the HtmlSelectOneMenus that are used internally in the SelectInputDateRenderer are not getting the proper client id. They are rendering out: id="popupDatePttrn1_sm" instead of: id="iceform:popupDatePttrn1_sm" The missing portion is the id for the naming container. The reason turns out to be the order of operations for dynamically adding and removing the component itself. In SelectInputDateRenderer methods .writeMonthDropdown and writeYearDropdown, the items are added to the menu before the menu is added to the calendar: HtmlSelectOneMenu dropDown = new HtmlSelectOneMenu(); dropDown.setId(component.getId() + SELECT_MONTH); dropDown.setPartialSubmit(true); dropDown.setTransient(true); dropDown.setImmediate(component.isImmediate()); dropDown.setDisabled(component.isDisabled() || component.isReadonly()); dropDown.setStyleClass(component.getMonthYearDropdownClass()); UISelectItem selectItem; Calendar calendar; int currentMonth = timeKeeper.get(Calendar.MONTH); for (int i = 0; i < months.length; i++) { selectItem = new UISelectItem(); calendar = shiftMonth(facesContext, timeKeeper, currentDay, i - currentMonth); selectItem.setItemValue(converter.getAsString(facesContext, component, calendar.getTime())); selectItem.setItemLabel(months [i] ); dropDown.getChildren().add(selectItem); if (i == currentMonth) { dropDown.setValue(selectItem.getItemValue()); } } //The menu is added as a child of the calendar after the menu items are set. This works in Mojarra but not MyFaces component.getChildren().add(dropDown); dropDown.encodeBegin(facesContext); dropDown.encodeChildren(facesContext); dropDown.encodeEnd(facesContext); component.getChildren().remove(dropDown); MyFaces doesn't like this because adding the menu to the calendar has the side effect of setting the parent and allowing the client id to be calculated. To appease both MyFaces and Mojarra, we just have to move the logic adding the menu to the calendar before we start setting the actual menu items: HtmlSelectOneMenu dropDown = new HtmlSelectOneMenu(); dropDown.setId(component.getId() + SELECT_MONTH); dropDown.setPartialSubmit(true); dropDown.setTransient(true); dropDown.setImmediate(component.isImmediate()); dropDown.setDisabled(component.isDisabled() || component.isReadonly()); dropDown.setStyleClass(component.getMonthYearDropdownClass()); //Add the menu to the calendar's children before adding any menu items. component.getChildren().add(dropDown); UISelectItem selectItem; Calendar calendar; int currentMonth = timeKeeper.get(Calendar.MONTH); for (int i = 0; i < months.length; i++) { selectItem = new UISelectItem(); calendar = shiftMonth(facesContext, timeKeeper, currentDay, i - currentMonth); selectItem.setItemValue(converter.getAsString(facesContext, component, calendar.getTime())); selectItem.setItemLabel(months [i] ); dropDown.getChildren().add(selectItem); if (i == currentMonth) { dropDown.setValue(selectItem.getItemValue()); } } dropDown.encodeBegin(facesContext); dropDown.encodeChildren(facesContext); dropDown.encodeEnd(facesContext); component.getChildren().remove(dropDown);
          Hide
          Deryk Sinotte added a comment -

          Part of the overall compatibility work to get ICEfaces working with MyFaces.

          Show
          Deryk Sinotte added a comment - Part of the overall compatibility work to get ICEfaces working with MyFaces.
          Hide
          Deryk Sinotte added a comment -

          Changed the order so that the menus are added to the calendar before the menu items are added to the menu.

          Show
          Deryk Sinotte added a comment - Changed the order so that the menus are added to the calendar before the menu items are added to the menu.

            People

            • Assignee:
              Deryk Sinotte
              Reporter:
              Deryk Sinotte
            • Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: