简体   繁体   English

在JSF Primefaces中动态生成日期标签

[英]generate dates label dynamically in JSF primefaces

in a page I have an InputText box for the duration of a priod (months as int) and ap:calendar input for picking a intial date. 在页面中,我有一个输入文本框,用于输入priod的持续时间(以int表示的月份),并使用ap:calendar输入来选择初始日期。 I need to generate labels (month-year) for all months from the intial date. 我需要从初始日期起的所有月份都生成标签(年份)。 for example, if duration is 3 and intial date is 10-dec-2014, three following labels should be generated: Dec-2014 Jan-2015 Feb-2015 I tried to do it without backing bean: 例如,如果持续时间为3,初始日期为2014年12月10日,则应生成以下三个标签:2014年12月2014年1月2015年2月2015年我尝试在不使用bean的情况下执行此操作:

<c:forEach var="i" begin="1" end="${myBean.duration}">
                        <p:outputLabel value=" ${i+myVar} ${year+1900} " />
                        <h:panelGrid columnClasses="input, slider" columns="2">
                            <p:inputText id="inputTxt_${i}" style="width:70px;" />
                            <p:slider for="inputTxt_${i}"
                                style="padding-left: 100px; margin-left:5px">
                                <p:ajax event="slideEnd" />
                            </p:slider>
                        </h:panelGrid>

but in this way I can not correctly generates the labels. 但是以这种方式我无法正确生成标签。 Anyone knows how to do this by using JSF or Backing bean with or without a submit button(for example using events such as event="keyup" or event="dateSelect") ?? 任何人都知道如何使用带有或不带有提交按钮的JSF或Backing bean(例如,使用诸如event =“ keyup”或event =“ dateSelect”之类的事件)来完成此操作?

Whenever I do dynamic jsf-stuff like you are trying to do, I tend to create the components in java via a backing bean. 每当我像您尝试执行动态jsf-stuff一样,我都会通过后备bean在Java中创建组件。 This is mainly due to the reason that I feel more comfortable writing conditional statements or loops in an established programming language and the results become more understandable in my opinion. 这主要是由于这样的原因:我觉得用一种既定的编程语言编写条件语句或循环会更自如,并且我认为结果变得更易于理解。 To do so, you would need to define a component with a binding to a backing bean. 为此,您需要定义一个与后备豆绑定的组件。 JSF will insert that element to your bean on creation using a setter method and retrieve it via the corresponding getter on every update. JSF将在使用setter方法创建该元素时将其插入到bean中,并在每次更新时通过相应的getter对其进行检索。 In between, you can basically do whatever you want to the component. 在这两者之间,您基本上可以对组件执行任何操作。 That includes removing and adding children, changing attributes, etc. So in your case, you could define your html-markup as follows: 这包括删除和添加子级,更改属性等。因此,在您的情况下,您可以按以下方式定义html标记:

<h:form id="dateform">
    <!-- calendar for setting the date -->
    <p:calendar value="#{backingbean.date}">
        <p:ajax event="change" update=":#{p:component('dateform')}" />
    </p:calendar>
    <!-- input for setting the duration -->
    <p:inputText value="#{backingbean.duration}">
        <p:ajax event="change" update=":#{p:component('dateform')}" />
    </p:inputText>
    <!-- panel for printing the labels, bound to a backingbean -->
    <p:outputPanel binding="#{backingbean.labelPanel}" />
</h:form>

The important part here is the outputPanel provided by the primefaces library. 这里的重要部分是primefaces库提供的outputPanel。 It's content will be bound to a backing-bean and updated whenever the values for the calendar or the duration changes. 每当日历或持续时间的值更改时,其内容都将绑定到backing-bean并进行更新。 For the backing bean, apart from setters and getters for Date and duration, you would also need a getter and setter for labelPanel, so that JSF is able to populate the component to the bean: 对于后备bean,除了Date和duration的setter和getter之外,还需要labelPanel的getter和setter,以便JSF能够将组件填充到bean中:

private Date date;
private int duration;
private OutputPanel panel;

public Date getDate() {
    return this.date;
}

public void setDate(Date date) {
    this.date = date;
    this.updatePanel();
}

public int getDuration() {
    return this.duration;
}

public void setDuration(int duration) {
    this.duration = duration;
    this.updatePanel();
}

public OutputPanel getLabelPanel() {
    return this.panel;
}

public void setLabelPanel(OutputPanel panel) {
    this.panel = panel;
}

private void updatePanel() {
    if (this.panel != null) {
        this.panel.getChildren().clear();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(this.date);
        for (int i = 0; i < this.duration; i++) {
            calendar.add(Calendar.MONTH, 1);
            OutputLabel label = new OutputLabel();
            label.setValue(calendar.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()));
            this.panel.getChildren().add(label);
        }
    }
}

As you can see, every time the setter for date or duration is called, the code will dynamically build OutputLabel elements and add them to the OutputPanel managed by your bean. 如您所见,每次调用日期或持续时间的setter时,代码将动态生成OutputLabel元素并将其添加到由bean管理的OutputPanel中。

I'm sure there are loads of other solutions for your problem, but this is the way I personally would implement this and it usually works fine. 我确定您的问题还有很多其他解决方案,但是这是我个人实现此问题的方式,通常效果很好。

I think your xhtml-Structure is not correct. 我认为您的xhtml-Structure不正确。

  • You are missing the closing </c:forEach> 您缺少结束语</c:forEach>
  • If closed at the end of the code-snippet you would get {i} Sliders 如果在代码段末尾关闭,则会获得{i}滑块

Assuming you want one slider and {i} outputs of the dates 假设您需要一个滑块和日期的{i}输出

  • Establish a BackingBean to hold your values 建立BackingBean来保存您的价值观
  • values are: "monthCount" holding the integer, "dateList" holding the (calculated) dates 值是:“ monthCount”保存整数,“ dateList”保存(计算的)日期
  • listener-Method to calculate the dates, according to integer-input by the slider public void listenerMonthCount(SlideEndEvent ae) listener-根据滑块输入的整数计算日期的方法public void listenerMonthCount(SlideEndEvent ae)

     <h:form id="form"> <h:panelGrid columns="2"> <p:inputText id="monthCount" style="width:70px;" value="#{backingBean.monthCount}" /> <p:slider for="monthCount" style="padding-left: 100px; margin-left:5px" maxValue="12"> <p:ajax event="slideEnd" process="@form" listener="#{backingBean.listenerMonthCount}" update="form" /> </p:slider> </h:panelGrid> <ui:repeat var="month" value="#{backingBean.dateList}"> <h:outputText value="#{month}"> <f:convertDateTime pattern="MMM-yyyy" /> </h:outputText> <br /> </ui:repeat> </h:form> 

Explanation in more detail: The p:ajax -Tag not only needs the event -Attribute, but also needs to be told what to do. 更详细的解释: p:ajax -Tag不仅需要event -Attribute,而且还需要被告知该怎么做。 So define the listener listener="#{backingBean.listenerMonthCount}" . 因此,定义监听器listener="#{backingBean.listenerMonthCount}" For the listener to know the newly chosen monthValue, it must be transferred to the server process="@form" is used to transfer all values in this form from the client to server. 为了使侦听器知道新选择的monthValue,必须将其传输到服务器, process="@form"用于将这种形式的所有值从客户端传输到服务器。 update="form" instructs to update all values after the listener is processed. update="form"指示在处理侦听器后更新所有值。

The <ui:repeat> -Block contains rendering of your output. <ui:repeat> -Block包含输出的呈现。 It iterates over the List<Date> and assignes every item to the variable month . 遍历List<Date>并将每个项目分配给变量month This is printed and formatted with f:convertDataTime wich takes a Java-DateFormatPattern as pattern -Attribute. 这是使用f:convertDataTime打印和格式化的,它采用Java-DateFormatPattern作为pattern -Attribute。

In your Backing-Bean you essentially need this 在您的Backing-Bean中,您基本上需要这个

private int monthCount = 0; // +getter/setter

private List<Date> dateList = new ArrayList<Date>(); // +getter/setter

public void listenerMonthCount(SlideEndEvent ae) {
    dateList.clear(); // clear the list to remove entries from possible old runs
    if (monthCount > 0) {
        Date now = new Date();
        dateList.add(now); // add first date
        Calendar cal = Calendar.getInstance();
        for (int i = 1; i < monthCount; i++) {
            cal.setTime(dateList.get(dateList.size() - 1)); // get last date from list and set calendar
            cal.add(Calendar.MONTH, 1);// add one month
            dateList.add(cal.getTime()); // add calculated date
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM