Primefaces calendar component show only month and year

后端 未结 12 1832
南笙
南笙 2020-12-14 03:25

primefaces calendar component is getting Date by default. Can I get only month and year without dates.

How to get only month and year

相关标签:
12条回答
  • 2020-12-14 03:43

    PrimeFaces don't have month year picker component as such. So if you want to use jQuery based external component then checkout jQuery.mtz.monthpicker

    0 讨论(0)
  • 2020-12-14 03:43

    Utilized this feature from the Primefaces Documentation:

    Another handy event is the viewChange that is fired when month and year changes. An instance of org.primefaces.event.DateViewChangeEvent is passed to the event listener providing the current month and year information.

    Made the following code: XHTML

    <p:panelGrid styleClass="monthYearOnly">
        <p:row>
            <p:column>FROM:</p:column>
            <p:column>
                <p:calendar id="from" mode="inline" value="#{callEntryBean.from}" navigator="true">
                    <p:ajax event="viewChange" listener="#{callEntryBean.updateFrom()}"/>
                </p:calendar>
            </p:column>
            <p:column>TO:</p:column>
            <p:column>
                <p:calendar id="to" mode="inline" value="#{callEntryBean.to}" navigator="true">
                    <p:ajax event="viewChange" listener="#{callEntryBean.updateTo()}"/>
                </p:calendar>
            </p:column>
            <p:column>
                <p:commandButton value="Filter" 
                    action="#{callEntryBean.filterDisplay}" update=""/>
            </p:column>
        </p:row>
    </p:panelGrid>
    

    CSS

    .monthYearOnly .ui-datepicker-calendar{
        display: none;
    }
    

    Bean

    public void updateFrom(){ 
    
        Map<String,String> requestParams = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
        LOGGER.info("before: " + from);
        Calendar c = Calendar.getInstance();
        c.setTime(from);
        c.set(Calendar.MONTH, Integer.parseInt(requestParams.get("form:from_month")) - 1);
        c.set(Calendar.YEAR, Integer.parseInt(requestParams.get("form:from_year")));
        from = c.getTime();
    
        LOGGER.info("after: " + from);
    }
    
    public void updateTo(){ 
    
        Map<String,String> requestParams = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
        LOGGER.info("before: " + to);
        Calendar c = Calendar.getInstance();
        c.setTime(to);
        c.set(Calendar.MONTH, Integer.parseInt(requestParams.get("form:to_month")) - 1);
        c.set(Calendar.YEAR, Integer.parseInt(requestParams.get("form:to_year"))); 
            c.set(Calendar.DATE,c.getActualMaximum(Calendar.DAY_OF_MONTH)); 
            to = c.getTime();
    
        Calendar now = Calendar.getInstance();
        if(c.after(now)){
            to = now.getTime();
        } 
        LOGGER.info("after: " + to);
    }
    

    Basically the ajax trigger when month or year is changed is the main feature here. Unfortunately, this is a bit of a work around since I can't retrieve the org.primefaces.event.DateViewChangeEvent. This seems to be a bug and I posted a report on the Primefaces Forum just now. Will update this post when I get some feedback there.

    Hope it helps.

    0 讨论(0)
  • 2020-12-14 03:44

    Here is how I achieved a simple month's range selector which look like this :

    month range

    The VoirCalendrier.xhtml web page :

    <h:form id="calendrierRegenererFormulaire">
       <h2><h:outputText value="#{msgs.CalendrierPlageAafficher}   "/></h2>
       <h:panelGrid columns="6">
          <h:outputLabel value="#{msgs.CalendrierDateDebut} : " for="calendrierDateDebut" />
          <p:calendar  id="calendrierDateDebut" value="#{locationsControleur.dateDebut}"
                    pattern="yyyy-MM-dd" effect="slideDown" navigator="true" mode="inline" 
                    lang="#{sessionControleur.localeInterface}" locale="#{sessionControleur.langue}" style="moisAnSeul" />
          <h:outputLabel value="#{msgs.CalendrierDateFin} : " for="calendrierDateFin" />
          <p:calendar  id="calendrierDateFin" value="#{locationsControleur.dateFin}"    
                    pattern="yyyy-MM-dd" effect="slideDown" navigator="true" mode="inline"
                    lang="#{sessionControleur.localeInterface}" locale="#{sessionControleur.langue}" style="moisAnSeul" />
          &nbsp;
          <p:commandButton value="#{msgs.CalendrierRegenerer}" update=":calendrierFormulaire" 
                     onclick="regenererCal()"/>
       </h:panelGrid>
    </h:form>
    

    To prevent the display of the calendar days, you just have to set its dislay property to none with the following code in your active css file :

    .ui-datepicker-calendar {
        display: none;
    }
    

    As noted by Daniel Slazlay above, navigating with the month/year drop downs or with the arrow icons do not change the internal date value of the p:calendar controls. To achieve this, the value of the selected month and year drop downs are read for the two p:calendar when the «regenerate calendar» button is fired. With this information, you are able to construct a date string with the format "yyyy-MM-dd" and to set the internal hidden value of the p:calendar controls For the starting month of the month range, the first day of the month is returned while for the ending month, it is the last day of the month which is returned. This is done with the followin javascript :

    function regenererCal() {
        year = $("#calendrierRegenererFormulaire\\:calendrierDateDebut .ui-datepicker-year").val();
        month = $("#calendrierRegenererFormulaire\\:calendrierDateDebut .ui-datepicker-month").val();
        $('#calendrierRegenererFormulaire\\:calendrierDateDebut_input').val(year + '-' + ('0' + (++month)).slice(-2) + '-01');
    
        year = $("#calendrierRegenererFormulaire\\:calendrierDateFin .ui-datepicker-year").val();
        month = $("#calendrierRegenererFormulaire\\:calendrierDateFin .ui-datepicker-month").val();
        lastDay = new Date(year, month + 1, 0); // To get last day of month, see http://stackoverflow.com/a/13572682/1431979
        $('#calendrierRegenererFormulaire\\:calendrierDateFin_input').val(lastDay.getFullYear() + '-' + ('0' + (lastDay.getMonth()+1)).slice(-2) + '-' + lastDay.getDate());
    
        // Check what is posted to your server
        console.log("[voirCalendrier.js]regenererCal calendrierDateDebut_input = " +     $('#calendrierRegenererFormulaire\\:calendrierDateDebut_input').val());
        console.log("[voirCalendrier.js]regenererCal calendrierDateFin_input = " +     $('#calendrierRegenererFormulaire\\:calendrierDateFin_input').val());
    }
    

    On the server side, you can check that the right information is received by the setter methods :

    ...
    formatAAAA_MM_JJ = new SimpleDateFormat("yyyy-MM-dd HH:mm", langue);
    ...
    
    public void setDateDebut(Date dateDebut) {
        this.dateDebut = dateDebut;
        logger.info("{locationsContrôleur}setDateDebut dateDebut = " + formatAAAA_MM_JJ.format(dateDebut));
    }
    
    public void setDateFin(Date dateFin) {
        this.dateFin = dateFin;
        logger.info("{locationsContrôleur}setDateFin    dateFin = " + formatAAAA_MM_JJ.format(dateFin));
    }
    

    I hope that this can help others.

    0 讨论(0)
  • 2020-12-14 03:46

    You can set this in the pattern, in your case it would be:

    <p:calendar id="test" value="#{bean.date}" pattern="MM.yyyy" />
    
    0 讨论(0)
  • 2020-12-14 03:50

    You could use the viewChange event on the p:calendar to capture the click on the next/previous month. Then you could trigger the dateSelect event by clicking the first day of the month.

    JSF:

    <p:calendar value="#{sampleBean.month}" styleClass="monthcal" mode="inline">
        <p:ajax event="viewChange" onsuccess="$('.ui-calendar[id=\''+this.source+'\'] a.ui-state-default').filter(function(){return $(this).text()*1===1;}).click();" />
    </p:calendar>
    

    To hide the pane with days, add the following to the css

    .monthcal .ui-datepicker-calendar {display: none;}
    
    0 讨论(0)
  • 2020-12-14 03:57

    I just hid the table of the day picker with CSS. I also had to create my own arrows for navigating, because the standard arrows do not fire the dateSelect event.

    Markup:

    <p:commandButton actionListener="#{bean.decrementMonth}"
        id="navLeft" update="[your components]" icon="ui-icon-triangle-1-w" />
    
    <h:panelGroup class="tableView">
        <p:calendar value="#{bean.selectedDate}" mode="inline" />
    </h:panelGroup>
    
    <p:commandButton actionListener="#{bean.incrementMonth}"
        id="navRight" update="[your components]" icon="ui-icon-triangle-1-e" />
    

    CSS:

    .tableView table,
    .tableView a.ui-datepicker-prev,
    .tableView a.ui-datepicker-next {
        display: none;
    }
    

    Bean methods:

    public void decrementMonth() throws Exception {  
        Calendar c = Calendar.getInstance();
        c.setTime(this.selectedDate);
        c.add(Calendar.MONTH, -1);
    
                //... business logic to update date dependent data
    }  
    
    public void incrementMonth() throws Exception {  
        Calendar c = Calendar.getInstance();
        c.setTime(this.selectedDate);
        c.add(Calendar.MONTH, 1);
    
                //... business logic to update date dependent data
    }  
    

    Result (PrimeFaces 3.4.2):

    PrimeFaces calendar modified to show only month and year

    0 讨论(0)
提交回复
热议问题