In this article I want to share a simple but useful trick which was asked frequently at the Richfaces User Forum last weeks. The use case is to allow just month and year selections from the Calendar component and hide date selection feature.
At first we will add a simple inline calendar to our form:
<rich:calendar value="#{calendarBean.selectedDate}" popup="false"/>
Then we hide the days labels list above the grid and the footer via the attributes:
<rich:calendar value="#{calendarBean.selectedDate}" popup="false" showWeekDaysBar="false" showFooter="false"/>
Now we want to hide the dates grid. As you could easily check in FireBug — the calendar is a table with one <tr> for header and six <tr> for grid itself. And the date grid <tr> elements has special ids defined. And header element <tr> has no id. So all we need to add common styleClass to calendar and write simple selector which will hide <tr> elements with id defined:
<style type="text/css"> .special tr[id]{ display:none; } </style> <rich:calendar value="#{calendarBean.selectedDate}" popup="false" showWeekDaysBar="false" showFooter="false" styleClass="special"/>
And now the last step. The calendar should pass the selected date to the bean according to value binding defined. So we need to select some date(e.g. first day of the month) when the current month scrolling occurs. We will use oncurrentdateselected attribute for that. currentdateselected event fired every time when the month/year scrolled. So finally we will have the following code:
<rich:calendar showWeekDaysBar="false" showFooter="false" value="#{calendarBean.selectedDate}" oncurrentdateselected="event.rich.component.selectDate(event.rich.date)" popup="false" styleClass="special"/>
Now after the user scrolls the months or years the first date of the chosen month will be selected and we will be able to process the selected month at server side. It will be passed to the selectedDate property of calendarBean.
All you will need to add in your concrete cases is maybe some styling(pretty easy using rich classes) or redefine the header itself(also easy using header facet and macrosubstitutions)
NOTE:Somebody could note that just currentDate could be used in order to bind selected month. And it's correct but only for inline calendar. In the sample I wrote, you really could get rid of oncurrentdateselected and use just currentDate value binding. But somebody might need the same but for popup mode. And in this case they will need to use value instead of current date because the result should appears at input and because of the fact that calendar ignores currentDay on initial rendering by design and opens on selected date month or at current month if selected date isn't defined. So for popup mode — such selected date trick could be used.