AngularUI Datepicker - End Date should not be less than Start Date - angularjs

We are using AngularUI datepicker (https://angular-ui.github.io/bootstrap/) for Start and End Date.
After integration, I was not able to select weekend dates as well as my end-date can be less than start-date.
I have made a plunker for the same where I was able to select weekend dates but still can not figure out how to prevent end-date not being
less than start-date. Also end-date should not be less than start-date if I click on Today.
Plunker URL - http://plnkr.co/edit/sWmQqHRaAJDbaEQFxzZU

I was able to track down what was causing this to happen to the following code:
$scope.toggleMin = function() {
$scope.inlineOptions.minDate = $scope.inlineOptions.minDate ? null : new Date();
$scope.dateOptions.minDate = $scope.inlineOptions.minDate;
};
$scope.toggleMin();
It looks like inlineOptions.minDate is there so the ternary operator sets it to null. This effectively wipes out any minDate. I'm thinking this should be reversed, but I'm not sure of the logic. I do know when I comment out the code it works as it should as you can see in the plunker below:
http://plnkr.co/edit/Krr6HMM8c4E1xY4Zj6F1?p=preview
I think the ternary operator might need to be the following to fix this:
$scope.inlineOptions.minDate = $scope.inlineOptions.minDate ? new Date() : null;
I hope this helps.

Related

What is the right way to select by value in a dropdown?

I'm having a bit of an issue with Angular and selecting an item from a dropdown and making Angular update the model.
I've been searching through StackOverflow, but only with partial luck.
The problem is that when i'm manually setting a value on a model, my dropdown updates correct, but the model itself does not update;
$scope.setSelected = function(){
$scope.selected.id = 15;
//$scope.$apply();// $apply already in progress
}
From various answers on StackOverflow, I've found out that Angular does not know about this update and the suggested answer is to run either a $scope.$apply() or a $scope.$digest(), but both throw a $apply already in progress exception. I have a feeling that this is not the correct way for me to do it, since it doesn't make sense, that you have to trigger an event to select by value.
What is the correct way to select an item in a dropdown by a given value?
Full code example can be found at https://jsfiddle.net/c2x3jvut/
When clicking the "Select dinnerman" button, the dropdown updates correct, but the shown model and when clicking "Log selected" it only shows the selected model, but with an updated id.
You can use $filter to get whole object instead of each property.
$scope.setSelected = function(){
$scope.selected = $filter('filter')($scope.persons,15,'id')[0];
//$scope.selected.id = 15;
//$scope.$apply();// $apply already in progress
}
Here is the modified version
ng's select binds its value based on its ngModel, which is being manipulated incorrectly in the example. The correct method is to change the reference of the ngModel rather than the select's id:
$scope.setSelected = function () {
$scope.selected = $scope.persons[1]; // yes
// $scope.selected.id = 15; // no
};
Fiddle might have been updated to show the effects.
Not sure I understand your question, but still...
You may include in each entry of the dropdown:
...ng-click="setSelected(<value>)"...
and, of course, add a parameter to the function.
By the way, are you aware that in the fiddle example you are selecting ID 15 in function setSelected?
You are just updating the current model with an ID. But when you see carefully the name and age remains same. Further you need to update the whole object as below:
$scope.setSelected = function(){
$scope.selected.id = 15;
$scope.selected.name = "Dinner-man";
$scope.selected.age = 20;
}
Or anyother way to directly updates the object.

Angular UI TimePicker Bi-Directional Behaviour

I would like to know which parte of the directive source code I should modify in order to implement bi-directional behaviour with this component ?. Because upon certain conditions, I should change the time to "08:00" or leave it like it is... I saw that an isolated scope is implemented so maybe that explains the behavuour...
Thankx
The ng-model attribute on your timepicker (if it exists), represents the bound data point exposed for you to change, and be changed by this directive.
<timepicker ng-model='scopeVariableYouBindToDatePickerToHaveAccessToSelectedValue' />
If you have an example of the source code, or the directive itself, please feel free to post an example or link.
Not fully sure I understand, but here goes nothing...
$scope.update = function() {
var d = new Date();
d.setHours( 8 );
d.setMinutes( 0 );
$scope.mytime = d;
};
OR better if you do not want to have to click a button, but this watch would have to be tied to some event of course:
$scope.$watch('something_to_watch', function(new, old) {
var d = new Date();
d.setHours( 8 );
d.setMinutes( 0 );
$scope.mytime = d;
});
And as Sean Larkin said, your html would then look like this:
<timepicker ng-model='{{mytime}}' />

Is it a bad practice to use $filter inside a custom filter?

I have a custom filter that shows the name of the month given the month number
angular.module('porteApp')
.filter('monthName', function($filter) {
return function (number) {
return $filter('date')(new Date(2015, number), 'MMMM');
}
});
It works but feels wrong somehow, is it a bad practice?
{{0 | monthName}}
> january
No at all, feel free to use it, while you are not:
- writing unreadable or unmaintainable code
- writing unsecure or vulnerable code
Everything else do what you want if it save your time and do what needed

Angular date rounding down on $format

So I'm attempting to deal with dates with mongodb / mongoose / angular.
I was trying to use the as a date picker. But it requires yyyy-MM-dd format. Where the dates generated in by a mongoose schema:
created: {
type: Date,
default: Date.now
},
Those dates are this format: 2014-12-13T22:23:20.633Z
So I looked around for how people are handling binding to the data model when there is a conversion required.
I came up with the following directive.
'use strict';
angular.module('clients').directive('mongooseDateFormat', ['$filter',
function ($filter) {
return {
require: 'ngModel',
link: function (scope, element, attrs, ngModelController) {
ngModelController.$parsers.push(function (data) {
console.log(data);
data = $filter('date')(data, 'yyyy-MM-dd');
console.log(data);
return data; //converted
});
ngModelController.$formatters.push(function (data) {
console.log(data); // gets 2015-01-12T00:00:00.000Z
data = $filter('date')(data, 'yyyy-MM-dd');
console.log(data); // converts to 2015-01-11
return data; //converted
});
}
};
}
]);
So I included the console.log functions where I'm testing the values and show above in the code some sample dates in the comments.
You can see that 2015-01-12T00:00:00.000Z becomes 2015-01-11.
So the value that the sends into the filter is with the 0 time stamp and the $format(date)(data, "yyyy-MM-dd") command removes the timestamp but changes the day.
(..sigh.. expletives removed )
Being new to having to care about date formats this is just mind blowing. Is the problem that I'm not using a timezone? By that I mean that mongodb and mongoose are not generating a timezone? Why would a date with a zero time round down to the previous date when you attempt to format it?
I could continue complaining about how odd this is and make myself sound stupid when someone tells me the easy answer. I'll just post and see if anyone knows.
<input type="text" data-mongoose-date-format data-ng-model="client.mydate">
or
<input type="date" data-mongoose-date-format data-ng-model="client.mydate">
They both bind after you enter the date and it is converted and return a date one day less.
It's because Z at the end of your time string tells that this is UTC and date filter converts date to your local timezone. If you use Angularjs 1.3.* you can add timezone parameter:
$filter('date')(data, 'yyyy-MM-dd', 'UTC');
I'm using the meanjs.org boiler plate as well, and I've been trying to work through this same problem for several hours now. I was storing it as a Date, but couldn't use it with ng-model because of the above mentioned formatting error. So I created the directive above, only to find that I need angular 1.3 to get the time zone param for $filter if I don't want it to automatically subtract 8 hours. But I found it's a real pain to upgrade angular to 1.3 because lots other stuff breaks, so I decided to revert back to 1.2 instead of following that rabbit hole.
But, I kid you not, I was able to circumvent the entire problem by simply changing the mongoose datatype from Date to String in my server model. This eliminates the automatic time zone conversion, but still allows you to use the date filter in your data bindings.
{{show.date | date: 'mediumDate'}}
Despite being stored in mongo as a string, it still formats perfectly, without the pesky automatic timezone conversion.
Also, when the date is stored as a string, it surprisingly needs no conversion at all when using in the edit form.
<input type="date" data-ng-model="show.date" id="date" class="form-control" placeholder="Show date" required>
Works just fine, you don't need a directive.
I realize from a data schema point of view, it's always preferable to store dates as type Date. But, to me, this is a much simpler solution until the boilerplate comes out of the box with angular 1.3, which will make it much easier to avoid the automatic time zone conversion of stored dates.

Previous - Next week on angular.js

I'm trying to implement a previous - next week stats which will change the url depending on StartDate and EndDate values of a datepicker but will show stats of a week (like from 11-11-13 18-11-13 and so on).
Any suggestions or ideas?
I know this is old, but in case someone stubles on it looking for an answer, here is one.
I do not know your code structure, so I will assume you have a controller with a structure/method like this:
// this is tied to your HTML with ng-model (I assume)
this.currentDate = new Date();
// tie this to your "next week" button with ng-click
this.iterateDate = function() {
var nextWeek = new Date(this.currentDate.valueOf());
// adding/subtracting 7 for next/previous week. Can be less for your use case
nextWeek.setDate(nextWeek.getDate() + 7);
// update the model value (if this is your approach)
this.currentDate = nextWeek;
};
Again, without knowing how you structured your controller it is hard to give an exact implementation. The iterateDate function should do what you ask for though.
Credit to #AnthonyWJones for his date change function.

Resources