【问题标题】:Primefaces calendar component show only month and yearPrimefaces 日历组件仅显示月份和年份
【发布时间】:2013-03-14 14:55:45
【问题描述】:

primefaces 日历组件默认获取日期。我可以只得到没有日期的月份和年份吗?

如何只获取月份和年份

【问题讨论】:

  • 你说的是只能获取月份和年份的组件吗?
  • 您想将年份放在首位并列出月份而不是里面的日子?或者你在预测哪种行为?
  • @AndresL:是的,在显示时,弹出窗口必须只包含月份和年份

标签: primefaces


【解决方案1】:

你可以在模式中设置它,你的情况是:

<p:calendar id="test" value="#{bean.date}" pattern="MM.yyyy" />

【讨论】:

  • 但是只显示数字,如何在标签中显示年月?
  • @CristianChaparroA。我还没有尝试使用日历,但是你可以尝试使用内脏pattern="MMMMMMMM yyyy"
  • 谢谢!但是当我尝试更改日期不起作用时,我无法选择其他日期,因为不显示日历。
【解决方案2】:

我正在阅读,但您无法从 Primefaces 开箱即用地实现此功能。

https://code.google.com/p/primefaces/issues/detail?id=3453

这个问题很老,但是一个月前的最新问题。所以他们使用这种方法:

jQuery UI DatePicker to show month year only

还有一种解决方案是只使用&lt;p:selectOneMenu&gt; 并从中获取所需内容。

干杯

【讨论】:

    【解决方案3】:

    PrimeFaces 本身没有月份年份选择器组件。因此,如果您想使用基于 jQuery 的外部组件,请查看 jQuery.mtz.monthpicker

    【讨论】:

    • 链接已损坏。请确认更正的是否正确。
    • PrimeFaces 在最近的版本中确实有月/年选择器!
    【解决方案4】:

    我只是用 CSS 隐藏了日期选择器的表格。我还必须创建自己的导航箭头,因为标准箭头不会触发 dateSelect 事件。

    标记

    <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 方法

    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
    }  
    

    结果 (PrimeFaces 3.4.2):

    【讨论】:

      【解决方案5】:

      这是我如何实现一个简单的月份范围选择器,如下所示:

      VoirCalendrier.xhtml 网页:

      <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>
      

      为防止显示日历日,您只需在活动的 css 文件中使用以下代码将其显示属性设置为无:

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

      正如上面 Daniel Slazlay 所述,使用月/年下拉菜单或箭头图标导航不会更改 p:calendar 控件的内部日期值。为此,当触发«regenerate calendar» 按钮时,会为两个 p:calendar 读取所选月份和年份下拉列表的值。使用此信息,您可以构建格式为“yyyy-MM-dd”的日期字符串,并设置 p:calendar 控件的内部隐藏值 对于月份范围的起始月份,该月的第一天返回,而对于结束月份,则返回该月的最后一天。这是通过以下 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());
      }
      

      在服务器端,您可以检查 setter 方法是否接收到正确的信息:

      ...
      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));
      }
      

      我希望这可以帮助其他人。

      【讨论】:

        【解决方案6】:
         //<![CDATA[
        
            function showMonthYear(calendar){
        
                $('.ui-datepicker-calendar').css('display','none');
                $('.ui-datepicker').css('top', $('.ui-datepicker').offset().top+250);
        
                var month = '';
                var year = '';
        
                if($(calendar).val()){
                    month = $(calendar).val().split('/')[0];
                    year = $(calendar).val().split('/')[1];
                } else {
                    month = $.datepicker.formatDate("mm", new Date());
                    year = $.datepicker.formatDate("yy", new Date());
                }
        
                var exists = 0 != $('.ui-datepicker-year option[value='+year+']').length;
                if(!exists){
        
                    $(".ui-datepicker-year").empty();
                    var initYear = parseInt(year)-10;
                    var endYear = parseInt(year)+10;
                    while(initYear < endYear){
        
                        $(".ui-datepicker-year").append($('<option>', {value:initYear, text: initYear}));
                        initYear++;
                    }
        
                }
        
                $('.ui-datepicker-month').val(parseInt(month)-1);
                $('.ui-datepicker-year').val(year);
                $(".ui-datepicker-month").change( function(){changeMonthYear(calendar);});
                $(".ui-datepicker-year").change( function(){changeMonthYear(calendar);});
        
            }
        
            function changeMonthYear(calendar){
        
                console.log('changeMonthYear');
                $('.ui-datepicker-calendar').css('display','none');
                $(".ui-datepicker-month").change( function(){changeMonthYear(calendar);});
                $(".ui-datepicker-year").change( function(){changeMonthYear(calendar);});
        
                var month = parseInt($('.ui-datepicker-month').val())+1; 
                if(month < 10){ month = '0'+month; } 
                $(calendar).val(month+"/"+parseInt($('.ui-datepicker-year').val()));
        
            }
        
        
        //      ]]>
        </script>
        
        <p:calendar size="5"
            onclick="showMonthYear(this)" 
            maxlength="10" pattern="MM/yyyy" navigator="true" />
        

        【讨论】:

        • 您能添加一些上下文吗?也许解释一下代码?
        【解决方案7】:

        您必须添加此块才能完成带有箭头的导航:

        $(".ui-datepicker-next").click( function(){changeMonthYear(calendar);});
        $(".ui-datepicker-prev").click( function(){changeMonthYear(calendar);});
        

        【讨论】:

          【解决方案8】:

          您可以使用 p:calendar 上的 viewChange 事件来捕获下个月/上个月的点击。然后,您可以通过单击该月的第一天来触发 dateSelect 事件。

          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>
          

          要隐藏带有天数的窗格,请将以下内容添加到 css

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

          【讨论】:

            【解决方案9】:

            利用 Primefaces 文档中的此功能:

            另一个方便的事件是 viewChange,当月和 年的变化。 org.primefaces.event.DateViewChangeEvent 的一个实例 传递给提供当前月份和年份的事件监听器 信息。

            编写以下代码: 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;
            }
            

            豆子

            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);
            }
            

            基本上monthyear 改变时的ajax 触发器是这里的主要功能。不幸的是,这有点麻烦,因为我无法检索org.primefaces.event.DateViewChangeEvent。这似乎是一个错误,我刚刚在 Primefaces 论坛上发布了一份报告。当我在那里得到一些反馈时会更新这篇文章。

            希望对你有帮助。

            【讨论】:

              【解决方案10】:

              现在primeng日历有一个月份选择器选项,在p日历中使用月份作为查看选项。

              <p-calendar [(ngModel)]="dateValue" view="month" dateFormat="mm/yy" [yearNavigator]="true" yearRange="2000:2030"></p-calendar>
              

              【讨论】:

                【解决方案11】:

                你可以这样做:

                XHTML

                                 <p:column>
                                    <p:calendar id="data" locale="pt_BR" navigator="true" showOn="button"
                                                pattern="yyyy-MM-dd" mode="inline" view="month"
                                                maxdate="#{cadastroResumoPorUnidadeBean.dataAtual}"
                                                styleClass="escolha-data"
                                                value="#{cadastroResumoPorUnidadeBean.dataInicio}">
                                        <p:ajax event="viewChange" process="@this"
                                                listener="#{cadastroResumoPorUnidadeBean.onChangeDataInicio}"
                                                update="calendario"/>
                                    </p:calendar>
                                </p:column>
                

                CSS

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

                public void onChangeDataInicio(DateViewChangeEvent event) throws ParseException {
                    dataInicio = new Date();
                    SimpleDateFormat dateformat = new SimpleDateFormat("dd-M-yyyy");
                    String inicio = "01-"+event.getMonth() +"-" + event.getYear();
                    this.dataInicio = dateformat.parse(inicio);
                
                }
                

                它对我有用!

                【讨论】:

                  【解决方案12】:

                  Primefaces 的最新版本(7.0 版)刚刚添加了您需要的内容:&lt;p:datePicker /&gt;。 它的工作原理几乎与&lt;p:calendar&gt; 完全相同,但可以轻松配置为仅显示月份和年份:

                  <p:datePicker value="#{managedBean.date}" view="month" 
                          pattern="MM/yyyy" yearNavigator="true" yearRange="1986:2025" />
                  

                  For example, when a month is selected, its value is stored in a "Date" object, which will have the value:
                  (如果选择 2019 年 4 月) Mon Apr 01 00:00:00 BRT 2019
                  在这种情况下,您只需忽略日、小时、分钟等值并使用所选的月份和年份。
                  如需更多信息,请阅读Documentation 并查看Showcase

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2011-01-11
                    • 2015-08-17
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2018-06-28
                    • 2011-06-11
                    • 1970-01-01
                    相关资源
                    最近更新 更多