如果在第二次单击时未选择日期并出现日期验证问题,则日期选择器会从日期选择器文本框中清除所选值
Posted
技术标签:
【中文标题】如果在第二次单击时未选择日期并出现日期验证问题,则日期选择器会从日期选择器文本框中清除所选值【英文标题】:Date Picker clears the selected value from date picker text box if a date is not selected on second click and issue with validation of date 【发布时间】:2017-03-02 00:13:33 【问题描述】:我已经在我的 Angular 应用程序中实现了一个带有验证的日期选择器。
html:
<div class="control-group">
<label class="control-label" for="reservation.reservedFrom">Reserved From<sup>*</sup></label>
<div class="controls input-group date" data-provide="datepicker">
<!--<input type="text" class="span4" style="width:150px" name="reservedFrom" placeholder="Reserved From" ng-model="reservation.reservedFrom" ng-change='checkErr()'
validator="required" required-error-message="Date is required" id="startDate122" />-->
<input class="form-control" type="text" name="startDate" core-date-picker ng-model="reservation.reservedFrom" >
<div class="input-group-addon">
<span class="glyphicon glyphicon-th"></span>
</div>
<span style="color:red">errMessageFrom</span>
</div> <!-- /controls -->
</div> <!-- /control-group -->
<div class="control-group">
<label class="control-label" for="reservation.reservedTill">Reserved Till<sup>*</sup></label>
<div class="controls input-group date" data-provide="datepicker">
<!--<input type="text" style="width:150px" class="span4" name="reservedTill" placeholder="Reserved Till" data-ng-model="reservation.reservedTill"
validator="required" required-error-message="Date is required" valid-method="watch" id="endDate" ng-change='checkErr()' />-->
<input class="form-control" type="text" name="EndDate" core-date-picker ng-model="reservation.reservedTill" ng-change='checkErr()' id="endDate1">
<div class="input-group-addon">
<span class="glyphicon glyphicon-th"></span>
</div>
<span style="color:red">errMessageTo</span>
</div> <!-- /controls -->
</div> <!-- /control-group -->
控制器:
myApp.controller('editReservationController', ['$scope', '$filter', 'reservationResolved', 'pocResolved', 'accountResolved', 'reservationServices', '$location', '$state',
function ($scope, $filter, reservationResolved, pocResolved, accountResolved, reservationServices, $location, $state)
$scope.reservation = new Object();
$scope.accounts = accountResolved.data;
$scope.pocs = pocResolved.data;
$scope.reservation.employee = reservationResolved.data;
$scope.updateReservation = function ()
var from = $scope.reservation.reservedFrom;
var till = $scope.reservation.reservedTill;
if ($scope.editReservationForm.$valid && $scope.checkErr())
var from = $scope.reservation.reservedFrom;
var till = $scope.reservation.reservedTill;
//var t = $scope.checkErr();
//TODO: fix it properly
$scope.reservation.reservedTill = '';
$scope.reservation.reservedFrom = '';
$scope.reservation.reservedFrom = $('#startDate').val();
$scope.reservation.reservedTill = $('#endDate').val();
reservationServices.updateReservation($scope.reservation).then(function (result)
$scope.data = result.data;
if (!result.data.error)
$state.transitionTo('employeeTalentPool',
id: $state.params.id
);
);
;
$scope.cancel = function ()
$location.path("/reservations");
;
$scope.$watch("reservation.reservedFrom", function (newValue, oldValue)
$scope.checkErr();
);
$scope.$watch("reservation.reservedTill", function (newValue, oldValue)
$scope.checkErr();
);
$scope.getCurrentDate = function()
var utcDate = new Date();
var isoExtendedDate = utcDate.toISOString();
var isoSimpleDate = isoExtendedDate.split("T")[0];
return isoSimpleDate;
$scope.checkErr = function ()
var startDateStr = $scope.reservation.reservedFrom;
var endDateStr = $scope.reservation.reservedTill;
var startDate;
if (startDateStr != undefined)
startDate = new Date(startDateStr);
var endDate;
if (endDateStr != undefined)
endDate = new Date(endDateStr);
$scope.errMessageFrom = '';
$scope.errMessageTo = '';
var myDate = new Date(); // Set this to your date in whichever timezone.
var utcDate = myDate.toUTCString();
if (startDate != undefined && startDate < new Date())
$scope.errMessageFrom = 'Start Date should be greater than or equal to present day.';
return false;
if (endDate != undefined && new Date(endDate) < new Date())
$scope.errMessageTo = 'End Date should be greater than or equal to present day.';
return false;
if (startDate != undefined && endDate != undefined && endDate <= startDate)
$scope.errMessageTo = "End date must be after start day.";
return false;
return true;
;
]);
App.js:
//Date Picker
myApp.directive('coreDatePicker', function ($compile)
return
restrict: 'A',
require: 'ngModel',
compile: function (element, attrs)
$(element[0]).datepicker(
autoclose: true,
format: "dd/mm/yyyy"
);
return this.link;
,
link: function (scope, element, attrs, ngModelCtrl)
$(element[0]).datepicker().on("change", function (e)
scope.$apply(function ()
ngModelCtrl.$setViewValue(element.val());
);
);
;
);
我将解释我正在谈论的场景。
问题 1 - 我从日历中选择了一个日期,它在日期选择器文本框中正确显示。然后我再次单击日期选择器以选择不同的日期,但后来我决定不更改当前选择的日期,因此我在日历之外单击了第二次而没有选择日期。由于我第二次没有选择日期,因此日期选择器从文本框中清除了第一次选择的日期,使其为空。我不希望这种情况发生。我希望第一个选择的日期保留在那里,除非选择了不同的日期(不是空值)。
问题 2 - 在验证日期时,我无法将所选日期与当前日期进行比较。如果所选日期小于当前日期,则应显示错误消息。但就我而言,如果我选择与今天相同的日期,则会显示错误。它应该允许我选择当天。
我使用过 Bootstrap-datepicker。如果需要更多信息,请告诉我。
提前致谢。
【问题讨论】:
Fiddle 或 Plunkr 会很有帮助。 我不知道如何通过链接控制器和指令等来创建 Plunkr 或 Fiddle...抱歉core-date-picker
这是你的 datepicker 自定义指令吗?我没有在您的代码中看到您正在使用 UI-bootstrap datepicker。
我正在使用引导日期选择器。不确定与 UI Bootstrap datepicker 有什么区别。我得到了这个应用程序。你认为我应该改用 UI 日期选择器吗?我尝试从 html 标记中删除 'core-date-picker' 并且验证变得无效
【参考方案1】:
我一眼就注意到了,
link: function (scope, element, attrs, ngModelCtrl)
$(element[0]).datepicker().on("change", function (e)
scope.$apply(function ()
ngModelCtrl.$setViewValue(element.val());
);
);
应该开火吗?我从 问题 1 了解到的是,无论是否有变化,它都会触发。你有没有想过在
尝试一些检查$(element[0]).datepicker().on("change", function (e)
scope.$apply(function ()
ngModelCtrl.$setViewValue(element.val());
);
);
试试
$(element[0]).datepicker().on("change", function (e)
scope.$apply(function ()
if(element.val())
ngModelCtrl.$setViewValue(element.val());
);
);
只需在 element.val() 上稍作检查,尝试一下不会有任何害处。
对于第二期,我认为你不能这样比较日期。
new Date()
返回
2016 年 10 月 20 日星期四 14:54:17 GMT+0800(马来半岛标准时间)
你的startDateStr
是什么
注意到new Date()
有几秒和几毫秒。
如果您只想比较 (DD/MM/yyyy)
的日期、月份和年份,我建议您先转换日期,然后再进行比较。
或者像单独比较
startDate.getDate() < new Date().getDate() // To compare a day
为了更好的选择,我建议moment。 Github.
var startDate = moment(startDateStr, 'MM-DD-YYYY').format('MMMM D');
var today = moment().format('D MMM, YYYY');
if (startDate != undefined && startDate < today)
更新
您是否尝试过将检查移至
$scope.$watch("reservation.reservedFrom", function (newValue, oldValue)
if(newValue && newValue !== oldValue)
$scope.checkErr();
);
$scope.$watch("reservation.reservedTill", function (newValue, oldValue)
if(newValue && newValue !== oldValue)
$scope.checkErr();
);
当你使用 = 比较两个日期对象时,它们是通过 valueOf 进行比较,这与日期的 getTime 相同。
但是当你使用==的时候,它们是同类型的两个不同对象,所以返回false。
所以在你的情况下^比较两个日期。正确的做法是
var startDate = moment(startDateStr, 'MM-DD-YYYY').format('MMMM D');
var today = moment().format('D MMM, YYYY');
if (startDate != undefined && startDate.getTime() < today.getTime())
这些解释取自Here。您可以查看链接以获取更多说明。
getTime
将日期转换为一个纪元等价物,它基本上是可以被计算的数字/数字值。 new Date()
是一个对象,new Date('10/20/2016')
也是一个对象,并且对象 A 不能等于对象 b。要进一步了解这一点,您可以在浏览器控制台上尝试。
new Date() === new Date();
> false
但是
new Date().getTime() === new Date().getTime()
>true;
第一个是假是假的,因为你在比较两个对象。第二个相当于与数值进行比较。毕竟
new Date().getTime()
>1477011127232
【讨论】:
请查看附件截图:它将显示我的日期格式。 s10.postimg.org/a9m9cjuqx/screenshot.jpg 我也试过 scope.$apply(function () if (element.val()) ngModelCtrl.$setViewValue(element.val()); 它没有任何区别。 @Phoenix 就像我说的,你的屏幕截图也很清楚。startDateStr
是 10/21/2016
并且您使用 new Date(startDate)
创建 startDate
。因此 startDate
不会有 Hours:Minute 和 seconds 。这就是为什么 startDate 的 HH:MM:SS
是 00:00:00
。但是,new Date()
将创建带有小时、分钟和秒的当前日期。 startDate
和 new Date() 无法比较,除非您从 new Date()
中取出秒、分钟和小时
好的,我会按照您的建议使用 moment 进行验证。第二次点击后清除日期怎么样?
还是一样:( s12.postimg.org/awc8jhvsd/screenshot.jpg请看截图。以上是关于如果在第二次单击时未选择日期并出现日期验证问题,则日期选择器会从日期选择器文本框中清除所选值的主要内容,如果未能解决你的问题,请参考以下文章
带有TextChanged事件的文本框不会在第二次输入中显示日期