对话框内的JQuery Datepicker的修正

时间:2011-09-01 02:40:29

标签: javascript jquery jquery-ui

我正在编写一个广泛使用JQuery UI的调度应用程序。其中一个要求是带有所有调度选项的模态对话框(非常类似于Windows 7任务计划程序)。

我想要的是这样的东西(但在对话框内):

http://jqueryui.com/demos/datepicker/#date-range

当我们在对话框中有这个时,它总是抛出一个异常,所以我们把它改成了一些自定义行为。

问题是,当您选择日期时,日期选择器不会关闭。显然这是一个错误(http://bugs.jqueryui.com/ticket/4453),我想知道是否有人修复它。

编辑: HTML / ASP.Net:

<div id="dialog-sched" title="Schedule/Run A TestRun" style="display: none">
    <label for="txtSelectedTest">Test/Group Name:</label>
    <asp:TextBox ID="txtSelectedTest" runat="server" ReadOnly="true" Style="margin-left: 10px;
        margin-top: 2px;" />
    <br />
    <label for="ddlRunOnPool">Pool:</label>
    <asp:DropDownList ID="ddlRunOnPool" runat="server" Width="150px" Style="margin-left: 90px;
        margin-top: 2px;" />
    <br />
    <label for="ddlRunOnAgent">Agent:</label>
    <asp:DropDownList ID="ddlRunOnAgent" runat="server" Width="150px" Style="margin-left: 80px;
        margin-top: 2px;" />
    <br />
    <div style="float: left">
        <label for="RunStyle">Run Style:</label>
        <asp:RadioButtonList ID="RunStyle" runat="server" EnableViewState="false">
            <asp:ListItem Value="Now" Text="Now" Selected="true" />
            <asp:ListItem Value="Once" Text="Once" />
            <asp:ListItem Value="Daily" Text="Daily" />
            <asp:ListItem Value="Weekly" Text="Weekly" />
        </asp:RadioButtonList>
    </div>
    <!--Start time: shows up for Once, Daily, and Weekly-->
    <div id="sched_Start" class="DialogInputPane">
        <label for="start_date">Start Date:&nbsp;</label>
        <input type="text" id="start_date" readonly="readonly" runat="server" />
        <label for="start_hr">Run Time:</label>
        <input type="text" id="start_hr" maxlength="2" size="2" runat="server" />
        <label for="start_min">:</label>
        <input type="text" id="start_min" maxlength="2" size="2" runat="server" />
        <asp:DropDownList ID="start_AMPM" runat="server">
            <asp:ListItem Value="AM">AM</asp:ListItem>
            <asp:ListItem Value="PM">PM</asp:ListItem>
        </asp:DropDownList>
    </div>
    <!--recurrence: Daily and Weekly - Includes recur every and expire date -->
    <div id="sched_Recurrence" class="DialogInputPane">
        <!--Expire Date-->
        <label for="sched_expire_forever">Expires:</label>
        <asp:CheckBox ID="sched_expire_forever" Checked="true" EnableViewState="false" runat="server" />
        <input type="text" id="expire_date" readonly="readonly" runat="server" />
        <!--recurrence-->
        <label for="sched_FrequencyTB">Every </label>
        <input type="text" id="sched_FrequencyTB" value="1" style="width: 2em" runat="server" />
        Days/Weeks
    </div>
    <!--Days of the week: only for weekly-->
    <div id="sched_weekdays" class="DialogInputPane">
        <asp:CheckBox ID="chkSunday" Text="Sun" runat="server" EnableViewState="false" />
        <asp:CheckBox ID="chkMonday" Text="Mon" runat="server" EnableViewState="false" />
        <asp:CheckBox ID="chkTuesday" Text="Tues" runat="server" EnableViewState="false" />
        <asp:CheckBox ID="chkWednesday" Text="Wed" runat="server" EnableViewState="false" />
        <asp:CheckBox ID="chkThursday" Text="Thurs" runat="server" EnableViewState="false" />
        <asp:CheckBox ID="chkFriday" Text="Fri" runat="server" EnableViewState="false" />
        <asp:CheckBox ID="chkSaturday" Text="Sat" runat="server" EnableViewState="false" />
    </div>
    <ul id="sched_errors" style="clear: both; line-height: 1.5em;"></ul>
</div>

使用Javascript:

function openScheduleDialog() {
var $start_hr = $("#start_hr"),
    $start_min = $("#start_min"), 
    $start_AMPM = $("#start_AMPM"),
    RunNow = $("#RunStyle_0"),
    RunOnce = $("#RunStyle_1"), 
    RunDaily = $("#RunStyle_2"),
    RunWeekly = $("#RunStyle_3"),
    datepickerOptions = { changeMonth: true, numberOfMonths: 1, minDate: "+0"},
    $expire_date = $("#expire_date").datepicker(datepickerOptions),
    $start_date = $("#start_date").datepicker(datepickerOptions);

function initializeDialogPanes() {
    $start_date.datepicker("setDate", "+0");
    if (RunNow.is(":checked")) {
        $("#sched_Start, #sched_weekdays, #sched_Recurrence").hide();
    } else if (RunOnce.is(":checked")) {
        $("#sched_Start").show();
        $("#sched_Recurrence, #sched_weekdays").hide();
    } else if (RunDaily.is(":checked")) {
        $("#sched_Start, #sched_Recurrence").show();
        $("#sched_weekdays").hide();
        $expire_date.datepicker("setDate", "+0");
    } else if (RunWeekly.is(":checked")) {
        $expire_date.datepicker("setDate", "+7");
        $("#sched_Start, #sched_weekdays, #sched_Recurrence").show();
    }
}

// Make it so the User Can Only Select a Pool or an Agent, not both.
mutuallyExclusiveDropdowns("#ddlRunOnPool", "#ddlRunOnAgent");

// Make it so that the user cannot set the expire date before the start date,
// and if they set the start date after the expire date, the expire date changes
// to the same value as the new start date
var $dates = $("#start_date, #expire_date").datepicker({
    defaultDate: "+1w",
    changeMonth: true,
    numberOfMonths: 3,
    onSelect: function (selectedDate) {
        var option = this.id == "start_date" ? "minDate" : "maxDate";
        $dates.not(this).datepicker("option", option, selectedDate);
    }
});

// When the user checks the "Expires" Checkbox, the end_date textbox
// should be enabled. If it is unchecked, the textbox should be disabled.
// Also, this checkbox is by default checked.
$("#sched_expire_forever").click(function () {
    if ($(this).is(":checked")) {
        $expire_date.removeAttr('disabled');
    } else {
        $expire_date.attr("disabled", "disabled");
    }
}).attr("checked", "checked");

// Constrains the scheduled time input to be a positive integer
$start_hr.format({ precision: 0, allow_negative: false });
$start_min.format({ precision: 0, allow_negative: false });

// When the user presses a key in the start_hr textbox, this
// checks to see if the textbox has reached it's maxlength (2)
// and focuses on the next textbox if it does.
$start_hr.keyup(function () {
    if ($(this).val().length >= $(this).attr("maxlength")) {
        $start_min.focus();
    }
});

// When the user clicks different RunStyle Radiobuttons, certains
// parts of the ui should become visible/be hidden.
$("#RunStyle").click(function () { initializeDialogPanes(); });

$('#dialog-sched').dialog({
    autoOpen: true,
    closeText: "",
    resizable: true,
    height: 'auto',
    maxHeight: 480,
    width: 540,
    maxWidth: 640,
    modal: true,
    open: function () {
        var now = new Date(),
            mins = now.getMinutes().toString();

        // This puts the Dialog inside the form so controls get their
        // values posted back.
        $(this).parent().appendTo("form");

        // Set the time to right now
        if (mins.length === 1) {
            mins = "0" + mins;
        }
        $start_min.val(mins);
        $start_hr.val(now.getHours() % 12 + 1);
        $start_AMPM.val(now.getHours() < 11 ? "AM" : "PM");

        // Open the Correct Panes
        initializeDialogPanes();
    },
    buttons: {
        'Schedule': function () {
            // Scheduling Stuff
            ...
            // End Scheduling Stuff
        },
        'Cancel': function () {
            $(this).dialog('close');
        }
    }
});
}

3 个答案:

答案 0 :(得分:1)

我意识到这是一个旧线程,但我遇到了同样的问题。这是一个演示它的JSFiddle: Fiddle

<div id="dialog">
    <fieldset>
        Some text: <input type="text" id="defaultField" size="30">
        Date: <input type="text" id="datepicker" size="30">
    </fieldset>
</div>

$("#datepicker" ).datepicker({onSelect: function(dateText, inst){
    $("#datepicker").datepicker("hide");
    //$("#datepicker").blur(); //this has no effect
    //$("#defaultField").focus(); //uncomment this line to make datepicker close
}});

$("#dialog").dialog(
        {
            resizable: false,
            height: 300,
            width: 400,
            modal: true,
            buttons: {
                Cancel: function () {
                    $(this).dialog("close");
                }
            }
        });

我找到的唯一解决方法是将焦点显式设置为datepicker的Select事件中的另一个输入。

答案 1 :(得分:0)

根据http://bugs.jqueryui.com/ticket/4453修复了该错误。看起来像别的东西。将脚本文件更新为最新版本。

答案 2 :(得分:0)

Example of dialog with datepicker inside

在问题发布后编辑

一次又一次地重新初始化日期选择器会导致错误。

首先在这里初始化:

$expire_date = $("#expire_date").datepicker(datepickerOptions),

然后在这里

$expire_date.datepicker("setDate", "+7");

在这里:

var $dates = $("#start_date, #expire_date").datepicker({
defaultDate: "+1w",
changeMonth: true,
numberOfMonths: 3,
onSelect: function (selectedDate) {
    var option = this.id == "start_date" ? "minDate" : "maxDate";
    $dates.not(this).datepicker("option", option, selectedDate);
}
});

请参阅problem with jquery datepicker onselect,了解如何在初始化datepicker后设置选项和onSelect事件。

看起来你可能必须更新的是:

var $dates = $("#start_date, #expire_date").datepicker('option', {
    onSelect: function(selectedDate) {
        var option = this.id == "start_date" ? "minDate" : "maxDate";
        $dates.not(this).datepicker("option", option, selectedDate);
    }
    }, {
        defaultDate: '+1w'
    }, {
        changeMonth: true
    }, {
        numberOfMonths: '3'
    });

小提琴示例:http://jsfiddle.net/az25g/