angularjs ng-repeat with date range - angularjs

I'm trying to filter a list that contains only the entries in a range of dates with die ui-bootstrap datepicker:
When I load the page first time the filter works fine but when I change the dates in the datepickers no entry will be shown. How can I pass the data through the filter with the new date ranges?
My custom filter:
angular.module('reklaApp')
.filter('dateFilter', function () {
return function (items, fromDate, toDate) {
var filtered = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
if (item.dt > fromDate && item.dt < toDate){
filtered.push(item);
}
}
return filtered;
};
});
my Model:
var ReklaSchema = new Schema({
dt: Date,
order: Number,
});
my View:
<div class="form-group">
<span class="input-group">
<input type="text" class="form-control" datepicker-popup="dd.MM.yyyy" ng-model="fromDate" is-open="datepickers.fromDate" min-date="" max-date="maxDate" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event,'fromDate')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</span>
</div>
bis
<div class="form-group">
<span class="input-group">
<input type="text" class="form-control" datepicker-popup="dd.MM.yyyy" ng-model="toDate" is-open="datepickers.toDate" min-date="" max-date="maxDate" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event,'toDate')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</span>
</div>
my View for the Filter:
<tr ng-repeat="rekla in reklas | dateFilter:fromDate:toDate">
<td>{{rekla.dt | date: 'dd.MM.yyyy'}}</td>
<td>{{rekla.order}}</td>
</tr>
my Controller:
angular.module('reklaApp')
.controller('MainCtrl', function ($scope, $http, Reklas, Modal) {
$scope.newRekla = {};
$scope.reklas = {};
$scope.fromDate = '2015-03-31T22:00:00.000Z';
$scope.toDate = '2015-04-30T22:00:00.000Z';
Reklas.getAll()
.success(function(data) {
$scope.reklas = data;
});
UPDATE:
I think the problem is the data type of the datepicker!?
Datepicker Data:
Model Data:

Call ng-change function in datepicker and apply filter again in ng-change function or else put watch on date variables and in watch function apply filter again.

you can call filter on ng-change and apply the filter on th model like this:
<input type="text" class="form-control" datepicker-popup="dd.MM.yyyy" ng-model="toDate" is-open="datepickers.toDate" min-date="" max-date="maxDate" date-disabled="disabled(date, mode)" ng-required="true" ng-change="filterDate()" close-text="Close" />
and in controller js create method filterDate() like this:
$scope.filterDate=function(){
$scope.toDate=$filter('dateFilter')($scope.toDate);
}

Related

Angular UI date picker validation

In this plunk I have an Angular UI date picker and a message that should be shown only when the date is valid. The problem is that the message is always shown, even when form.$valid is true. Note that if you enter a valid or invalid date and then click on Validate, an alert will display correctly that the date is valid or invalid respectively.
Why is the validation message shown all the time, even when form.$valid is true?
Javascript
var app = angular.module('ui.bootstrap.demo', ['ui.bootstrap']);
app.controller('ctl', function ($scope) {
$scope.dtFrom = new Date ();
$scope.config1 = {};
$scope.config1.opened = false;
$scope.open1 = function(event){
event.preventDefault();
event.stopPropagation();
$scope.config1.opened = true;
};
$scope.validate = function(form){
if (!form.$valid) {
alert("Date invalid");
}
else {
alert("Date valid");
}
}
});
HTML
<div ng-controller="ctl">
<form name="form1" ng-submit="validate(form1)" novalidate>
<p class="input-group" name="dtFrom" style="width:160px;margin-bottom:0px;">
<input type="text" class="form-control" ng-model="dtFrom"
is-open="config1.opened" uib-datepicker-popup="MM-dd-yyyy"
close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open1($event)">
<i class="glyphicon glyphicon-calendar"></i>
</button>
</span>
</p>
<span ng-show="!form1.dtFrom.$valid">Invalid Date</span>
<br/>
<button type="submit">Validate</button>
</form>
</div>
You should create name for the input
<input type="text" class="form-control" ng-model="dtFrom"
is-open="config1.opened" uib-datepicker-popup="MM-dd-yyyy"
close-text="Close" name="date" />
<span ng-show="!form1.date.$valid">Invalid Date</span>
Here is plnkr
http://plnkr.co/edit/gc0Oefhok6Gjim66UG0K?p=preview

AngularJS $http.get not firing

I have a page that has a datepicker on it. When a date is picked I have a function being called which assigns the new date to a variable and then calls a $http.get.
The variable gets assigned fine as I have this returning to the page but the $http.get fails and I cant see why. The call syntax is fine as I use it in another function and when I look at the Network viewer in IE I can see that its not even being fired.
Any help would be great.
Thanks :-)
The HTML
<div>
<div id="date-picker" class="panel panel-heading" ng-controller="timesheetViewerCtrl">
<!--<div>
Choose A Week End Date:
<select ng-model="selectedWeek" ng-options="val for val in years"> </select>
</div>-->
<pre>Selected date is: <em>{{dt | date:'fullDate' }}</em></pre>
<div class="row">
<div class="col-md-6">
Choose a Week End Date:
<p class="input-group">
<input type="text" class="form-control" datepicker-popup="{{format}}" ng-model="dt"
is-open="opened" min-date="minDate" max-date="'2020-06-22'" datepicker-options="dateOptions"
date-disabled="isDateDisabled(date, mode)" ng-required="true" ng-change="changeSelect(dt)"
close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
<pre>{{changeDate}}
<br>To Check Filter Select any of the following (joining date) from Datepicker.
</pre>
</div>
and the JS
angular.module("timesheetApp").controller("timesheetViewerCtrl", function ($scope) {
$scope.dt = new Date();
$scope.open = function (e) {
e.preventDefault();
e.stopPropagation();
$scope.opened = true;
};
$scope.dateOptions = {
'starting-day': 1
};
$scope.format = 'dd-MM-yyyy';
$scope.isDateDisabled = function (date, mode) {
return (mode === 'day' && date.getDay() !== 0);
};
$scope.changeSelect = function (dt) {
$scope.changeDate = moment(dt).format("MM-DD-YYYY");
$http.get("/api/tblEntries/")
.then(onUserComplete, onError);
}
});
Please inject $http service in your controller declaration like
controller("timesheetViewerCtrl", function ($scope, $http)

Can't open Datepicker using calendar button

Here's my code:
<p class="input-group">
<input type="text" class="form-control date" id="startDate" placeholder="Start Date" ng-click="date.startDate=true" datepicker-popup="MM/dd/yyyy" ng-model="date.start" is-open="date.startDate" date-disabled="disabled(date, mode)" ng-required="true" close-text="Close">
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="date.startDate=true" is-open="date.startDate"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
For some reason, I can't get the calendar button to open the datepicker up... I thought hvaing just ng-click would work but that isn't working.
Here is the controller code:
self = this;
self.open = function ($event) {
$event.preventDefault();
$event.stopPropagation();
self.opened = {};
self.opened[$event.target.id] = true;
// log this to check if its setting the log
console.log(self.opened);
};

angularjs ui-bootstrap 2 datepickers is error

With uibootstrap's datepicker,I have a single page with two controls, one is starttime and one is endtime.
I want the following; when I set starttime ,the endtime's min-date is start time. But when I click the endtime I would like the fielded set to "" the.first time.
<p class="input-group">
<input class="form-control" datepicker-popup ng-model="view.starttime" is-open="dateSet.opened.startTime" min-date="'2015-05-02'" max-date="'2015-06-22'" datepicker-options="dateSet.dateOptions" date-disabled="dateSet.disabled(date, mode)" ng-required="true" show-weeks="flase" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="dateSet.openFn($event,'startTime')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
<p class="input-group">
<input class="form-control" datepicker-popup ng-model="view.endtime" is-open="dateSet.opened.endTime" min-date="view.starttime" max-date="'2015-06-22'" datepicker-options="dateSet.dateOptions" date-disabled="dateSet.dateSet.disabled(date, mode)" ng-required="true" show-weeks="flase"/>
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="dateSet.openFn($event,'endTime')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
This works for me (forked from the bootstrap demo)
$scope.updateEndDate = true;
$scope.$watch('startDate', function(val) {
if($scope.updateEndDate) $scope.endDate = val;
});
$scope.click = function() {
if ($scope.updateEndDate)
{
$scope.updateEndDate = false;
$scope.endDate = "";
}
};
HTML
{{updateEndDate}}
<div class="col-md-6">
<p class="input-group">
<input name="startDate" type="text" class="form-control"
ng-model="startDate"
is-open="opened"
ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
<div class="col-md-6">
<p class="input-group">
<input
ng-focus="click()"
name="endDate" type="text" class="form-control"
ng-model="endDate"
is-open="opened"
ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event)"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
Plunk http://plnkr.co/edit/HfihvKanQsERr4wFq9VE?p=preview
If I understood correctly, you want to set the min-date on the 'end date' picker to be the value of the 'start date' picker, BUT you want to initialize the end date picker to be null.
To do this, you need to initialize the end date to a null value. In your case, that would be $scope.view = {endtime: ''};. Since you didn't provide your controller code or a demo, I just created a simple demo below that matches what I think you want to accomplish.
var app = angular.module('daterange.demo', ['ui.bootstrap'])
.config(function(datepickerConfig, datepickerPopupConfig) {
datepickerConfig.formatYear = 'yy';
datepickerConfig.startingDay = 1;
datepickerConfig.showWeeks = false;
datepickerPopupConfig.datepickerPopup = "shortDate";
datepickerPopupConfig.closeText = "Close";
});
app.controller('DatepickerPopupDemoCtrl', function($scope) {
$scope.startdt = new Date();
$scope.enddt = '';
$scope.opened = {
startdt: false,
enddt: false
};
$scope.open = function($event, picker) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened[picker] = true;
};
$scope.$watch('startdt', function(newval) {
if ($scope.enddt !== '' && newval > $scope.enddt) {
$scope.enddt = newval;
}
});
$scope.setRangeClass = function(date, mode) {
if (mode === 'day') {
var dayToCheck = new Date(date).setHours(12, 0, 0, 0);
var startDay = new Date($scope.startdt).setHours(12, 0, 0, 0);
var endDay = new Date($scope.enddt).setHours(12, 0, 0, 0);
if (dayToCheck >= startDay && dayToCheck < endDay) {
return 'range';
}
}
return '';
};
});
#import "http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css";
.btn-default[disabled], .btn-default.disabled {
background-color: #999;
}
.range>.btn-default {
background-color: #5bb75b;
}
.range button span {
color: #fff;
font-weight: bold;
}
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.13/angular.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.0.js"></script>
<div ng-app="daterange.demo">
<div class="container" ng-controller="DatepickerPopupDemoCtrl">
<div class="row">
<div class="col-xs-12">
<h2>Popup Date Range Picker Demo</h2>
<pre>Date Range: {{startdt | date:'fullDate' }} - {{enddt | date:'fullDate' }}</pre>
</div>
<div class="col-xs-6">
<label for="startdate">Start Date</label>
<p class="input-group">
<input type="text" class="form-control" id="startdate" datepicker-popup ng-model="startdt" is-open="opened.startdt" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event, 'startdt')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
<div class="col-xs-6">
<label for="enddate">End Date</label>
<p class="input-group">
<input type="text" class="form-control" id="enddate" datepicker-popup ng-model="enddt" is-open="opened.enddt" min-date="startdt" custom-class="setRangeClass(date, mode)" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event, 'enddt')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
</div>
</div>
In my demo above, I also added a $watch function that updates the end date picker when the start date picker changes. If the start date is greater than the end date, the end date is reset. Since you don't want the end date to change when the initial digest cycles are run on the page, you have to check for an empty value for the end date.
Additionally, I'm using the new custom-class attribute to show the date range on the end calendar. If you'd like to use this feature, make sure that you're using UI Bootstrap 0.13.0+.

How to have at least two datepickers of ui-bootstrap on a single page?

I want to have several datepickers on a page. But with the default solution from UI-Bootstrap it is not possible, no one of datepickers may be opened. The conflict with each other. Here is my code:
<div>
<div class="form-horizontal pull-left">
<input type="text" datepicker-popup="dd-MMMM-yyyy" ng-model="dt" is-open="opened" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true"/>
<button class="btn" ng-click="open()"><span class="glyphicon glyphicon-calendar"></span></button>
</div>
<div class="form-horizontal pull-left">
<input type="text" datepicker-popup="dd-MMMM-yyyy" ng-model="dt" is-open="opened" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" />
<button class="btn" ng-click="open()"><span class="glyphicon glyphicon-calendar"></span></button>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</div>
I just did a copy/paste of the datepicker code from the site http://angular-ui.github.io/bootstrap/#/datepicker. They conflict with each other. When I click <input> field to open a datepicker no one can be opened properly, both are opened for a second and immediately disappear.
How may I have several datepickers on a single page?
Rather than using a different function you can use a different is-open attribute and then pass the attribute in through the ng-click function. You still need different models:
<div>
<div class="form-horizontal pull-left">
<input type="text" datepicker-popup="dd-MMMM-yyyy" ng-model="dt1" is-open="opened1" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true"/>
<button class="btn" ng-click="open($event,'opened1')"><span class="glyphicon glyphicon-calendar"></span></button>
</div>
<div class="form-horizontal pull-left">
<input type="text" datepicker-popup="dd-MMMM-yyyy" ng-model="dt2" is-open="opened2" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" />
<button class="btn" ng-click="open($event,'opened2')"><span class="glyphicon glyphicon-calendar"></span></button>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</div>
And inside controller:
$scope.open = function($event,opened) {
$event.preventDefault();
$event.stopPropagation();
$scope[opened] = true;
};
I'm still learning Angular and UI-Bootstrap, so take that into account when reading my answer. I did something similar to BlueMonk, but in a flexible way that keeps my controller code from having to know about the instances of the datepicker on the page.
I put all of the datepicker code in my controller into a single namespace:
$scope.datePicker = (function () {
var method = {};
method.instances = [];
method.open = function ($event, instance) {
$event.preventDefault();
$event.stopPropagation();
method.instances[instance] = true;
};
method.options = {
'show-weeks': false,
startingDay: 0
};
var formats = ['MM/dd/yyyy', 'dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
method.format = formats[0];
return method;
}());
And then used the following markup:
<p class="input-group">
<input type="text" class="form-control" ng-model="editableEmployee.dateHired" datepicker-popup="{{datePicker.format}}" datepicker-options="datePicker.options" is-open="datePicker.instances['dateHired']" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="datePicker.open($event, 'dateHired')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
<p class="input-group">
<input type="text" class="form-control" ng-model="editableEmployee.dateFired" datepicker-popup="{{datePicker.format}}" datepicker-options="datePicker.options" is-open="datePicker.instances['dateFired']" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="datePicker.open($event, 'dateFired')"><i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
This worked like a charm for me.
This should work (different models, open flag, and functions):
<div>
<div class="form-horizontal pull-left">
<input type="text" datepicker-popup="dd-MMMM-yyyy" ng-model="dt1" is-open="opened1" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true"/>
<button class="btn" ng-click="open1()"><span class="glyphicon glyphicon-calendar"></span></button>
</div>
<div class="form-horizontal pull-left">
<input type="text" datepicker-popup="dd-MMMM-yyyy" ng-model="dt2" is-open="opened2" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" />
<button class="btn" ng-click="open2()"><span class="glyphicon glyphicon-calendar"></span></button>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</div>
And inside controller:
$scope.open1 = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened1 = true;
};
$scope.open2 = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened2 = true;
};
Here is what worked for me:
$id is scope id, provided by angular.
ctrl.opened = {};
ctrl.openDatatimePicker = function ($event, id) {
$event.preventDefault();
$event.stopPropagation();
ctrl.opened[id] = true;
}
<input type="text"
class="form-control"
uib-datepicker-popup="{{vm.datepickerFormat}}"
ng-model="x.FraDato"
is-open="vm.opened[$id]"
datepicker-options="vm.datepickerOptions"
ng-required="true"
ng-click="vm.openDatatimePicker($event,$id)"/>
No Additional changes are necessary. As long as you wrap each date input in it's own controller div the scope will reside with that input
Example:
<div ng-controller="DatepickerDemoCtrl">
<div class="form-horizontal pull-left">
<input type="text" datepicker-popup="dd-MMMM-yyyy" ng-model="dt" is-open="opened" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true"/>
<button class="btn" ng-click="open($event)"><span class="glyphicon glyphicon-calendar"></span></button>
</div>
</div>
<div ng-controller="DatepickerDemoCtrl">
<div class="form-horizontal pull-left">
<input type="text" datepicker-popup="dd-MMMM-yyyy" ng-model="dt" is-open="opened" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" />
<button class="btn" ng-click="open($event)"><span class="glyphicon glyphicon-calendar"></span></button>
</div>
</div>
though its an old question but answring for someone who fall in to same problem as i did.
i assigned the datepicker onfocus to that element and it workd great.
Sample code.
$(document).on('focus','.datepicker',function(){
$(this).datepicker();
});
Can open multi datepickers of ui-bootstrap on a single page
JS
$scope.open = {};
$scope.openCalendar = function (e, date) {
e.preventDefault();
e.stopPropagation();
if ($scope.open[date] === true) {
$scope.open = {};
} else {
$scope.open = {};
$scope.open[date] = true;
}
};
HTML
<input type="text" id="created1" name="created1" datetime-picker="" datepicker-options="dateOptions" timepicker-options="timeOptions" ng-click="openCalendar($event, 'created1')" placeholder="0000/00/00 00:00" is-open="open.created1" autocomplete="off" class="form-control" ng-model="vm.condition.created1">
<input type="text" id="created2" name="created2" datetime-picker="" datepicker-options="dateOptions" timepicker-options="timeOptions" ng-click="openCalendar($event, 'created2')" placeholder="0000/00/00 00:00" is-open="open.created2" autocomplete="off" class="form-control" ng-model="vm.condition.created2">

Resources