【问题标题】:JQuery DateRangePicker to JSF Composite Component with AJAXJQuery DateRangePicker 到带有 AJAX 的 JSF 复合组件
【发布时间】:2015-11-22 11:58:18
【问题描述】:

我目前正在尝试在 Java Server Faces 2.2 中构建一个包含 JQuery 日期范围选择器 (http://www.daterangepicker.com/) 的复合组件。到目前为止它工作正常,但我正在尝试向它添加 ajax 行为并且无法使其正常工作。我基本上希望在调用“应用”按钮时触发 ajax 事件。

到目前为止我所拥有的......

public class DateRange
{

    private LocalDate startDate = LocalDate.now();
    private LocalDate endDate = LocalDate.now();

    ...

}

日期范围转换器:

@Named
@ApplicationScoped
public class DateRangeConverter implements Converter, Serializable
{

    private static final long serialVersionUID = 1L;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value)
    {
        if (value == null || value.isEmpty())
            return null;

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
        DateRange dateRange = new DateRange(LocalDate.parse(value.split("-")[0].trim(), formatter), LocalDate.parse(value.split("-")[1].trim(), formatter));
        return dateRange;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value)
    {
        return value.toString();
    }

}

复合组件:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:cc="http://java.sun.com/jsf/composite">

<cc:interface>
    <cc:attribute name="value" required="true" />
    <cc:attribute name="styleClass" default="form-control" />

    <cc:attribute name="applyLabel" default="Apply" type="java.lang.String" />
    <cc:attribute name="cancelLabel" default="Cancel"
        type="java.lang.String" />
    <cc:attribute name="pattern" default="MM/dd/yyyy"
        type="java.lang.String" />

    <cc:clientBehavior name="rangeSelected" event="change"
        targets="rangepicker" />
</cc:interface>

<cc:implementation>
    <h:inputText value="#{cc.attrs.value}"
        styleClass="#{cc.attrs.styleClass} dateRangePicker" id="rangepicker"
        converter="#{dateRangeConverter}" onkeydown="return false;">
    </h:inputText>

    <h:outputScript library="js" name="moment.min.js" target="body" />
    <h:outputScript library="js" name="daterangepicker.js" target="body" />

    <script type="text/javascript">
        jQuery(document).ready(function() {
              var id = '#{cc.clientId}';
              $(document.getElementById('#{cc.clientId}:rangepicker')).daterangepicker({

                locale: {
                    applyLabel: '#{cc.attrs.applyLabel}',
                    cancelLabel: '#{cc.attrs.cancelLabel}',
                    format: '{cc.attrs.pattern}'
                    }
              })
        });
        </script>
</cc:implementation>
</html>

以及显示它的 .xhtml 页面:

<h:form id="frmDRPickerNoAjax">
                <cc:dateRangePicker id="ccDateRange"
                    value="#{helloWorldBean.dateRange}" applyLabel="Apply">

                </cc:dateRangePicker>

                <h:commandButton styleClass="btn btn-primary" value="Gogogoo">
                    <f:ajax render="@form" execute="@form" />
                </h:commandButton>
            </h:form>

<h:form id="frmDRPickerAjax">
                <cc:dateRangePicker id="ccDateRange"
                    value="#{helloWorldBean.dateRangeAjax}">
                    <f:ajax event="rangeSelected" render="@form" />
                </cc:dateRangePicker>

                    <h:outputText
                        value="#{helloWorldBean.getDateRangeAsString(helloWorldBean.dateRangeAjax)}"
                        escape="false" />
            </h:form>

没有 AJAX 的版本运行良好,符合预期。我只是无法让 ajax 调用正常工作。模糊似乎是错误的事件,因为每当我在日期范围选择器中选择一个选项时都会触发它,因为实际输入失去了焦点。当应用按钮被按下时,日期范围选择器还提供一个 javascript 回调。但是,我不知道如何从该 javascript 函数触发任何事件/ajax 请求。

感谢任何帮助。

【问题讨论】:

  • 我不熟悉 jQuery 日期选择器 API,但我可以看出,当输入值由 JavaScript 而不是用户输入操作时,确实不会触发 HTML DOM change 事件。基本上,您需要寻找一些选项,允许您在选择日期时附加回调函数,然后手动强制$element.trigger("change")
  • TYVM!像魅力一样工作!

标签: jquery ajax jsf-2 composite-component


【解决方案1】:

正如@BalusC 所述,解决方案是触发DOM 更改事件。

所以,在我的复合组件中,我将脚本部分更改为

<script type="text/javascript">
        jQuery(document).ready(function() {
              var id = '#{cc.clientId}';
              $(document.getElementById('#{cc.clientId}:rangepicker')).daterangepicker({

                locale: {
                    applyLabel: '#{cc.attrs.applyLabel}',
                    cancelLabel: '#{cc.attrs.cancelLabel}',
                    format: '{cc.attrs.pattern}'
                    }
              },
function(start, end, label) {
   $(document.getElementById('#{cc.clientId}:rangepicker')).trigger('change');
})
        });
        </script>

AJAX 事件现在按预期触发。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-23
    • 2012-07-11
    • 1970-01-01
    • 1970-01-01
    • 2015-08-29
    • 2014-02-21
    • 1970-01-01
    • 2012-11-11
    相关资源
    最近更新 更多