I have a directive date-picker.js and view as selectDate.html. I want to set minDate for the date picker when the value of another datepicker changes. How to achieve that?
.directive('selectDate', ['moment', function(moment) {
return {
restrict: 'E',
require:'^ngModel',
templateUrl: 'views/selectDate.html',
replace: true,
scope: {
ngModel: '='
},
link: function($scope, element, attrs) {
$scope.date = $scope.ngModel;
$scope.dateOptions = {
startingDay: 1,
showWeeks: false
};
$scope.dateStatus = {
opened: false
};
$scope.openDatePopup = function() {
$scope.dateStatus.opened = true;
};
$scope.$watch('date', function (newValue, oldValue) {
if (newValue !== oldValue) {
var date = moment(newValue);
$scope.ngModel = date.format('YYYY-MM-DD');
}
});
}
};
selectDate.html
<span class="select-date">
<input type="text" readonly="readonly" datepicker-popup="dd.MM.yyyy" datepicker-options="{startingDay: 1, showWeeks: true}" ng-model="date" show-button-bar="false" current-text="Heute" close-text="Schließen" is- open="dateStatus.opened" min-date="'2014-01-01'" class="form-control" required="required" ng-click="openDatePopup()">
</span>
I am using it like below:
From <select-date ng-model="fromDate"></select-date>
To <select-date ng-model="toDate"></select-date>
I want to set minDate of toDate to fromDate value.
Well you can user ui-bootstrap directive which is lot easier,below is the code
$scope.dateOptions = {
formatYear: 'yyyy',
startingDay: 1
};
$scope.opened = true;
$scope.minDate= new Date();
var maxDate = new Date();
maxDate.setFullYear (maxDate.getFullYear() + 2);//enable for 2 future years..
$scope.maxDate= maxDate;
Your HTML will look like this
<input type="text" class="form-control selection-box"
id="datepicker"
datepicker-popup="{{dateFormat}}"
ng-model="selectedDate" is-open="opened"
ng-class="{'date-changed':colorChange[$parent.$parent.$index +'-'+ $parent.$index]}"
min-date="minDate" max-date="maxDate"
datepicker-options="dateOptions" readonly="readonly"
ng-change="changeDate()"
close-text="Close" ng-required="true" />
To answer OP's question you can have following code changes.
From <select-date ng-model="fromDate" min-date="fromMinDate"></select-date>
To <select-date ng-model="toDate" min-date="toMinDate"></select-date>
<span class="select-date">
<input type="text" readonly="readonly" datepicker-popup="dd.MM.yyyy" datepicker-options="{startingDay: 1, showWeeks: true}" ng-model="date" show-button-bar="false" current-text="Heute" close-text="Schließen" is- open="dateStatus.opened" min-date="setMinDate" class="form-control" required="required" ng-click="openDatePopup()">
</span>
Below are changes in your directive.
.directive('selectDate', ['moment', function(moment) {
return {
restrict: 'E',
require:'^ngModel',
templateUrl: 'views/selectDate.html',
replace: true,
scope: {
ngModel: '='
minDate: '#'//which date input we are changing...
},
link: function($scope, element, attrs) {
$scope.date = $scope.ngModel;
$scope.selectedDateType = $scope.minDate=='fromMinDate'?'From':'To';
$scope.dateOptions = {
startingDay: 1,
showWeeks: false
};
$scope.dateStatus = {
opened: false
};
$scope.openDatePopup = function() {
$scope.dateStatus.opened = true;
$scope.setMinDate = new Date();//for From date..
};
$scope.$watch('date', function (newValue, oldValue) {
if (newValue !== oldValue) {
var date = moment(newValue);
$scope.ngModel = date.format('YYYY-MM-DD');
if($scope.selectedDateType=='From'){
$scope.setMinDate = $scope.fromDate;//for To date
}
}
});
}
};
Related
everyone.
I have a trouble with angularjs. I created custom directive for input[type="text"] and passed into variable as model. But ng-change event called function with previous value of variable.
Example:
State: 0, Type 1, In function - 0.
State: 1, Type 548, In function - 1.
State:548, Type 3, In function 548.
My html:
<div ng-controller="simpleCTRL">
<mr-textfield is-required="true" value="val" title="Minutes" type="text" change="ChangeVal()"></mr-textfield>
<input type="text" ng-model="val" ng-change="ChangeVal()"/>
</div>
</div>
And js:
<!-- language: lang-js -->
angular.module('SimpleInterestApp', [])
.controller('simpleCTRL', function($scope) {
$scope.val = 0;
$scope.ChangeVal = function() {
console.log($scope.val);
};
})
.directive('mrTextfield', function () {
return {
restrict: 'E',
template: "<div class='textfield'><input type='{{::type}}' ng-required='isRequired' ng-model='value' ng-change='change()'><span class='bar'></span><label>{{::title}}</label></div>",
replace: true,
transclude: true,
scope: {
value:"=",
title:"#",
type:"#",
isRequired:"=",
change:"&"
}
};
});
Wrap console.log inside a $timeout.
$scope.ChangeVal = function() {
$timeout(function() {
console.log($scope.val);
})
};
See working plunker.
I am using angular-material-datetimepicker in my modal to enter date and time. However, angular sends all data server side in json and that changes the time to UTC. On reloading my client side, UTC time is displayed which I do not want. How do I make the client display my local time (GMT +2 in my case)? How do I manipulate only the date part of the json string? I've seen confusing solutions on other similar SO q's and forums. Thanks.
On the modal html
<div class="time">
<md-input-container class="md-input-has-placeholder start_time">
<label>Start Date/Time</label>
<input mdc-datetime-picker="" date="true" time="true" type="text" id="datetime" placeholder="Start" min-date="date" format="DD/MM/YYYY hh:mm" ng-model="Project.StartAt" class=" md-input">
</md-input-container>
<md-input-container class="md-input-has-placeholder endtime">
<label>End Date/Time</label>
<input mdc-datetime-picker="" date="true" time="true" type="text" id="datetime" placeholder="End" min-date="date" format="DD/MM/YYYY hh:mm" ng-model="Project.EndAt" class=" md-input">
</md-input-container>
</div>
angular
$scope.editProject = function(data) {
$scope.showSelected = true;
$scope.SelectedProject = data;
var fromDate = moment(data.start).format('DD/MM/YYYY LT');
var endDate = moment(data.end).format('DD/MM/YYYY LT');
$scope.Project = {
ProjectID : data.projectID,
Client : data.client,
Title : data.title,
Description: data.description,
Employees: data.employees,
StartAt : fromDate,
EndAt : endDate,
IsFullDay : false
}
$scope.ShowModal()
},
$scope.ShowModal = function(){
$scope.option = {
templateUrl: 'modalContent.html',
controller: 'modalController',
controllerAs: '$ctrl',
backdrop: 'static',
resolve: {
Project : function () {
return $scope.Project;
},
SelectedProject : function () {
return $scope.SelectedProject;
},
projects: function () {
return $ctrl.projects;
}
}
};
var modal = $uibModal.open($scope.option);
modal.result.then(function (data) {
$scope.Project = data.project;
switch (data.operation){
case 'Save':
//Save here
$http({
method: 'POST',
url: '/',
data: $scope.Project
}).then(function(response){
if(response.data.status){
$scope.projects.push(Project);
}
})
break;
You can apply filter for that like :
$scope.yourDate= $filter('date')(new Date($scope.yourDate), 'yyyy-MM-dd'); // Try different format as per your requirement
Don't forget to inject dependency $filter.
I want's to get the value of ng-model within the the ng-repeat on my own directive and use the value of that ng-model in the directive for a fuction.
here is a plunker to see code in action :
https://plnkr.co/edit/MaI8DOtdc4yucXgNo05p?p=preview
here is my directive code :
(function() {
'use strict';
angular.module('barname.rtEditor', [])
.directive('rtEditor', rtEditor);
function rtEditor() {
return {
restrict: 'E',
replace: true,
templateUrl: 'rt-ht.html',
compile: compile
};
function compile() {
return {
post: function(scope, element, attrs) {
scope.com = {
inp: [{
name: 'video',
model: scope.vimodel,
command: 'insertHTML',
modelcommand: scope.vimodel
}, {
name: 'pic',
model: scope.pimodel,
command: 'insertImage',
modelcommand: scope.pimodel
}, {
name: 'link',
model: scope.linkmodel,
command: 'createLink',
modelcommand: scope.linkmodel
}]
};
scope.$watch('vimodel', function(newValue, oldValue) {
console.log('vim model watch :-> ', newValue);
});
scope.$watch('texmodel', function(newValue, oldValue) {
console.log('text model watch :-> ', newValue);
});
scope.execIn = function(cmd, val) {
console.log('cmd val :->', cmd + ' | ' + val);
scope.vimodel = '';
scope.texmodel = '';
};
}
};
}
}
})();
and here is the html code :
<div>
<div ng-repeat="inp in com.inp" id="{{inp.name}}">
<label>{{inp.name}} :</label>
<input type="text" ng-model="inp.model" />
<span ng-click="execIn(inp.command, inp.modelcommand)">doIt!</span>
</div>
<br>
<hr>
<br>
<div>
<label>widout ng repeat:</label>
<input type="text" ng-model="texmodel" />
<span ng-click="execIn('textIn', texmodel)">doIt!</span>
</div>
</div>
I can easily get the value of the ng-model without ng-repeat
I'm trying to make use of the bootstrap-datepicker.
I have an existing AngularJS directive, but when setting the initial value, it does not update when making use of a date range.
HTML
<div class="input-group input-daterange" id="fromToDate" calendar ng-model="vm.fromToDate">
<input type="text" class="form-control input-sm" required ng-model="vm.bookingFromDate">
<span class="input-group-addon">to</span>
<input type="text" class="form-control input-sm" required ng-model="vm.bookingToDate">
</div>
Directive
// this directive updates the value, once it has been selected, but not when the initial value has been set**
function calendar() {
return {
require: 'ngModel',
link: function($scope, el, attr, ngModel) {
$(el)
.datepicker({
autoclose: true,
todayHighlight: true,
todayBtn: 'linked',
onSelect: function(dateText) {
$scope.$apply(function() {
ngModel.$setViewValue(dateText);
});
}
});
}
};
};
Then, I tried the following directive (found here), but this doesn't work either for a date range - instead:
function calendar() {
return {
require: '?ngModel',
restrict: 'A',
link: function ($scope, element, attrs, controller) {
var updateModel, onblur;
if (controller != null) {
updateModel = function (event) {
element.datepicker('hide');
element.blur();
};
onblur = function () {
var date = element.val();
return $scope.$apply(function () {
return controller.$setViewValue(date);
});
};
controller.$render = function() {
var date = controller.$viewValue;
element.datepicker().data().datepicker.date = date.from.toDate();
element.datepicker('setValue');
element.datepicker('update');
return controller.$viewValue;
};
}
return attrs.$observe('bdatepicker', function (value) {
var options = {
format: "yyyy/mm/dd",
todayBtn: "linked",
autoclose: true,
todayHighlight: true
};
return element.datepicker(options).on('changeDate', updateModel).on('blur', onblur);
});
}
};
};
Any assistance would be appreciated!
Thanks!
[Update]
CodePen to illustrate the issue:
<p data-height="322" data-theme-id="dark" data-slug-hash="BLkagb" data-default-tab="js,result" data-user="Programm3r" data-embed-version="2" class="codepen">See the Pen Bootstrap-Datepicker (Range) AngularJS by Richard (#Programm3r) on CodePen.</p>
<script async src="//assets.codepen.io/assets/embed/ei.js"></script>
You could use the following library to solve the issue. datepicker
Edit: to resolve disappearance of date.
<input type="text" class="form-control input-sm" ng-model="vm.bookingFromDate" id="fromDate">
<span class="input-group-addon">to </span>
<input type="text" class="form-control input-sm" ng-model="vm.bookingToDate" id="toDate">
in controller
$('#fromDate').val(vm.bookingFromDate);
$('#toDate').val(vm.bookingToDate);
I am using the plugin bootstrap-datetimepicker with knockout js. I've done a handler to dynamically manage and MaxDate MinDate, as I show below:
ko.bindingHandlers.dateTimePicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().dateTimePickerOptions || {};
$(element).datetimepicker(options);
//when a user changes the date, update the view model
ko.utils.registerEventHandler(element, "dp.change", function (event) {
var value = valueAccessor();
if (ko.isObservable(value)) {
if (event.date && event.date != null && !(event.date instanceof Date)) {
value(event.date.toDate());
} else {
//value(event.date);
value(undefined);
}
}
});
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
var picker = $(element).data("DateTimePicker");
if (picker) {
picker.destroy();
}
});
},
update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var picker = $(element).data("DateTimePicker");
//when the view model is updated, update the widget
if (picker) {
//Usamos moment para convertir a fecha ya que utiliza este plugin adicional datetimepicker
var koDate = moment(ko.utils.unwrapObservable(valueAccessor()) || '');
if (koDate.isValid()) picker.date(koDate.toDate() || null);
}
}
};
ko.bindingHandlers.minDate = {
update: function (element, valueAccessor) {
var value = moment(ko.utils.unwrapObservable(valueAccessor()) || ''),
picker = $(element).data("DateTimePicker");
if (value.isValid() && picker) {
picker.minDate(value.toDate());
}
}
};
ko.bindingHandlers.maxDate = {
update: function (element, valueAccessor) {
var value = moment(ko.utils.unwrapObservable(valueAccessor()) || ''),
picker = $(element).data("DateTimePicker");
if (value.isValid() && picker) {
picker.maxDate(value.toDate());
}
}
};
I use it as follows:
<div class="input-group" data-bind="dateTimePicker: NuevaTarea.FechaInicio, dateTimePickerOptions: { format: 'L', showClear: true }, minDate: NuevaTarea.minDate, maxDate: NuevaTarea.maxDate">
<input type="text" class="form-control" />
<div class="input-group-addon">
<i class="fa fa-calendar"></i>
</div>
</div>
The problem is when change the NuevaTarea.minDate and NuevaTarea.maxDate, the date of MaxDate is assigned to NuevaTarea.FechaInicio.
Someone could help me create an observable MaxDate MinDate and properly functioning? No I'm doing wrong.
The version of plugin is 4.15.35.
https://github.com/Eonasdan/bootstrap-datetimepicker
ko.bindingHandlers.dateTimePicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().dateTimePickerOptions || {};
$(element).datetimepicker(options);
//when a user changes the date, update the view model
ko.utils.registerEventHandler(element, "dp.change", function (event) {
var value = valueAccessor();
if (ko.isObservable(value)) {
if (event.date && event.date != null && !(event.date instanceof Date)) {
value(event.date.toDate());
} else {
//value(event.date);
value(undefined);
}
}
});
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
var picker = $(element).data("DateTimePicker");
if (picker) {
picker.destroy();
}
});
},
update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var picker = $(element).data("DateTimePicker");
//when the view model is updated, update the widget
if (picker) {
//Usamos moment para convertir a fecha ya que utiliza este plugin adicional datetimepicker
var koDate = moment(ko.utils.unwrapObservable(valueAccessor()) || '');
if (koDate.isValid()) picker.date(koDate.toDate() || null);
}
}
};
ko.bindingHandlers.minDate = {
update: function (element, valueAccessor) {
var value = moment(ko.utils.unwrapObservable(valueAccessor()) || ''),
picker = $(element).data("DateTimePicker");
if (value.isValid() && picker) {
picker.minDate(value.toDate());
}
}
};
ko.bindingHandlers.maxDate = {
update: function (element, valueAccessor) {
var value = moment(ko.utils.unwrapObservable(valueAccessor()) || ''),
picker = $(element).data("DateTimePicker");
if (value.isValid() && picker) {
picker.maxDate(value.toDate());
}
}
};
function ViewModel() {
var self = this;
self.NuevaTarea = {
FechaInicio: ko.observable(),
FechaFin: ko.observable(),
minDate: ko.observable(),
maxDate: ko.observable()
};
self.NuevaTarea.minDate(new Date()) ;
//Not is working apply value null, help here!! I Like that this field is empty on start
self.NuevaTarea.FechaInicio(null);
}
ko.applyBindings(new ViewModel());
body{height:300px; padding:20px;}
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.15.35/css/bootstrap-datetimepicker.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datetimepicker/4.15.35/js/bootstrap-datetimepicker.min.js"></script>
<div class="form-group">
<label class="control-label">Min Date:</label>
<div class="input-group" data-bind="dateTimePicker: NuevaTarea.minDate, dateTimePickerOptions: { format: 'L', showClear: true }">
<input type="text" class="form-control" />
<div class="input-group-addon">
<i class="glyphicon glyphicon-calendar"></i>
</div>
</div>
</div>
<div class="form-group">
<label class="control-label">Fecha Inicio:</label>
<div class="input-group" data-bind="dateTimePicker: NuevaTarea.FechaInicio, dateTimePickerOptions: { format: 'L', showClear: true }, minDate: NuevaTarea.minDate, maxDate: NuevaTarea.maxDate">
<input type="text" class="form-control" />
<div class="input-group-addon">
<i class="glyphicon glyphicon-calendar"></i>
</div>
</div>
</div>
Thanks for your help but I already solved only just set, useCurrent: false options.
<div class="input-group" data-bind="dateTimePicker: NuevaTarea.FechaInicio, dateTimePickerOptions: { format: 'L', showClear: true, useCurrent: false }, minDate: NuevaTarea.minDate, maxDate: NuevaTarea.maxDate">
<input type="text" class="form-control" />
<div class="input-group-addon">
<i class="fa fa-calendar"></i>
</div>
</div>