I have JSON data as below:
[
{
"morning":"5:36 am",
"evening":"7:00 pm"
}
]
I want to compare JSON data with current time. Ex: is morning > current time ?
HTML:
<div ng-repeat="item in schedule">
<div>Morning - {{item.morning}}</div>
<div>Eveing - {{item.evening}}</div>
</div>
I have specified the AngularJS part to display the Data and It's working. Now I want to compare the {{item.morning}} with current time and display a message in front of {{item.morning}} as "Time up" based on condition.
Please let me know how can I compare time in AngularJS. Thanks in advance.
As #PWKad mentioned, you should use a date library like moment.js.
One reason for that, might be that trying to implement it yourself can end with an ugly, quick-and-(really)-diry code like this:
Controller:
$scope.isTimeUp = function(time) {
var hour, minute;
if(time.split(" ")[1] == 'pm' && time.split(":")[0] != '12') {
hour = parseInt(time.split(":")[0]) + 12;
} else {
hour = parseInt(time.split(":")[0]);
}
minute = parseInt(time.split(":")[1]);
var today = new Date();
var givenDate = new Date();
givenDate.setHours(hour);
givenDate.setMinutes(minute);
if(givenDate < today) {
return true;
} else {
return false;
}
}
html:
<div ng-repeat="item in schedule">
<div>
Morning - {{item.morning}}
<span ng-if="isTimeUp(item.morning)">
Time's up!
</span>
</div>
<div>
Eveing - {{item.evening}}
<span ng-if="isTimeUp(item.evening)">
Time's up!
</span>
</div>
</div>
...and this is following your markup. You might want to implement a custom filter instead. But again, use moment.js.
Anyways, it seems to be working, though I haven't put much thought in it or tested it too much - see demo.
Related
I'm building a widget in ServiceNow and am trying to incorporate some css styling for a selected button. After digging around online, I think I got the basic structure down, but am still a bit confused about how to ensure a button has been selected and then styling it accordingly.
Below is what my HTML looks like:
<div class="chiclets">
<button class="btn btn-slots" ng-class="{'btn-selected':selectedSlot.apptTime == slot.apptTime }" ng-click="selectedSlot = time" ng-repeat="time in c.availTime">{{time.apptTime}}</button>
</div>
This produces a set of available time slots from my c.availTime object array:
My client script for the object array looks like this:
$scope.getTimeSlots = function(date, place) {
date = moment(date).format("YYYY-MM-DD")
//every time a date is chosen, first clear time array
c.availTime = [];
for(var a=0; a<c.data.avail.length; a++){
if(date == c.data.avail[a].start_date && place == c.data.avail[a].appointment_location) {
c.availTime.push({
apptTime:c.data.avail[a].start_time,
availability: c.data.avail[a].availability
});
}
}
};
My question is if a user clicks on 9am time slot for example, is my ng-click capturing that time correctly. If so, how do I format my ng-class so that the btn-selected class has a background of red (for example).
Thanks!
Your test is selectedSlot.apptTime == slot.apptTime.
Shouldn't it be selectedSlot.apptTime == time.apptTime?
Because I don't see a slot variable.
I guess the test could even be selectedSlot == time (same reference).
Create one more property isSelected = false and set it as true on ng-click and apply class if isSelected property is true.
See code below
css
<style>
.btn-selected {backgraound-color:red}
</style>
html
<div class="chiclets">
<button class="btn btn-slots" ng-class="{'btn-selected':time.isSelected == true }" ng-click="btnClick($index)" ng-repeat="time in c.availTime">{{time.apptTime}}</button>
</div>
Js
$scope.getTimeSlots = function(date, place) {
date = moment(date).format("YYYY-MM-DD")
//every time a date is chosen, first clear time array
c.availTime = [];
for(var a=0; a<c.data.avail.length; a++){
if(date == c.data.avail[a].start_date && place == c.data.avail[a].appointment_location) {
c.availTime.push({
apptTime:c.data.avail[a].start_time,
availability: c.data.avail[a].availability,
isSelected : false
});
}
}
};
$scope.btnClick = function(index) {
angular.foreach( c.availTime,function(v,k){
if(k == index){
v.isSelected = true;
} else {
v.isSelected = false;
}
})
}
I've a table with 5 cells in the header, each cell correspond to a week (example: week 01, week 02 and so on).
In the first cell the week is given like this:
<div class="monthCells">Week {{vm.selectedPeriod}}</div>
and the result is the text : "Week 01" in the header cell.
The code in the controller to show the week number is:
return moment.utc(this.date).format("WW");
It returns always the number of the FIRST week of the selected month,
the user can with a date picker go from month to month, and in the table it will show the weeks in that month.
What's the best way to display the other 4 weeks?
Because I only get the number for the first week, so what do I put in the other 4 cells?
I was thinking about a counter, so it adds +1 to the number I get with:
return moment.utc(this.date).format("WW");
but the problem is, this won't be in a ng-repeat, but the table header is static, so one solution I was thinking about was put something like this in the 5 header cells:
{{vm.selectedPeriod}}
{{vm.selectedPeriod +1}}
{{vm.selectedPeriod +2}}
{{vm.selectedPeriod +3}}
{{vm.selectedPeriod +4}}
So when the user switches month, every week number will be correct but it won't work because I get a string from my function and can't figure out how to parse it in that function with momentJS.
If someone has a solution for my idea, or if there is a better way to achieve this, please let me know
edit SOLUTION:
at the end I found a solution with only using momentJS.
{{vm.date | amDateFormat : 'WW'}}
{{vm.date | amAdd : '1' : 'w' | amDateFormat : 'WW'}}
{{vm.date | amAdd : '2' : 'w' | amDateFormat : 'WW'}}
I would do this with a simple and smart filter like I created in this >> Demo fiddle:
View
<div ng-controller="MyCtrl">
<div class="monthCells">Week {{currentDate|dateWeekFilter:0}}</div>
<div class="monthCells">Week {{currentDate|dateWeekFilter:1}}</div>
<div class="monthCells">Week {{currentDate|dateWeekFilter:2}}</div>
<div class="monthCells">Week {{currentDate|dateWeekFilter:3}}</div>
</div>
AngularJS application
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function ($scope) {
$scope.currentDate = moment.utc();
});
myApp.filter('dateWeekFilter', function () {
return function (date, weeksToAdd) {
return moment(date).add(weeksToAdd, 'w').format("WW");
}
});
Full solution which includes: selectedPeriod scope and datepicker
>> Demo fiddle:
View
<div ng-controller="MyCtrl">
<datepicker>
<input ng-model="datePickerDate" ng-change="dateChanged()" type="text"/>
</datepicker>
<div class="monthCells">Week {{currentDate|dateWeekFilter:selectedPeriod}}</div>
<div class="monthCells">Week {{currentDate|dateWeekFilter:selectedPeriod+1}}</div>
<div class="monthCells">Week {{currentDate|dateWeekFilter:selectedPeriod+2}}</div>
<div class="monthCells">Week {{currentDate|dateWeekFilter:selectedPeriod+3}}</div>
</div>
AngularJS application
var myApp = angular.module('myApp',['720kb.datepicker']);
myApp.controller('MyCtrl', function ($scope) {
//Init
$scope.currentDate = moment.utc();
$scope.datePickerDate = $scope.currentDate.toDate();
$scope.selectedPeriod = 0;
//date change handling
$scope.dateChanged = function () {
$scope.currentDate = moment.utc($scope.datePickerDate);
}
});
myApp.filter('dateWeekFilter', function () {
return function (date, weeksToAdd) {
return moment(date).add(weeksToAdd, 'w').format("WW");
}
});
I'm using this angularJS datepicker in my application and would like to know if there is a way to display only months and years in the calendar and remove the days?
This is how I'm using the datepicker:
<datepicker date-format="MM yy" button-prev-title="previous month" button-next-title="next month" button-prev="<i class='fa fa-arrow-left'></i>" button-next="<i class='fa fa-arrow-right'></i>" id="dtDate" name="dtDate" >
<input ng-model="dtDate" />
</datepicker>
I tried to add date-format="MM yy" but it only changes the selected date and not the datepicker itself.
I think you might be interested in using this git repository that I created.
https://github.com/morfsys/multiple-month-picker
This is how you can use it in your project:
HTML
<input type="text" multiple-month-picker />
JS
//Initiate your app by injecting 'mmp-morfsys'
var app = angular.module('app-name', ['mmp-morfsys'])
It helps you to select multiple months across multiple years. The best thing? It is on AngularJS.
I hope it helps you.
I have the same problem with angularjs-datepicker.
I used another datepicker: angularjs-material.
Here is how you can use it:
<md-datepicker ng-model="startDate" md-mode="month" md-placeholder="dd/MM/yyyy" md-date-locale="mylocale" md-open-on-focus></md-datepicker>
And then in your controller:
function pad(n) {return n < 10 ? "0"+n : n;}
$scope.mylocale = {
formatDate: function(date) {
var d=new Date(date);
if(isNaN(d.getTime())) {
return '';
} else {
return pad(d.getDate())+"/"+pad(d.getMonth()+1)+"/"+d.getFullYear();
}
},
parseDate: function(date) {
var ds = date.split('/');
var d=new Date(ds[2],ds[1]-1,ds[0]);
if(isNaN(d.getTime())&&d!=''){
return new Date(NaN);
} else {
return d;
}
} };
And it is working. Just make sure that you properly handle case when input is invalid (form.startDate.$invalid).
If someone has a solution for angularjs-datepicker, please let us know.
I have been trying to achieve feedback like functionality using json data such that when I click on any star all the stars in the current row get selected(their css change).
Just like we normally see in the 5 star feedback.
I am currently struggle with the following code, can anyone help?
$scope.itemClicked = function (status, job) {
if (status.isActive) {
status.isActive = false;
} else {
angular.forEach(job.statuscollection, function(status) {
status.isActive = false;
});
status.isActive = true;
}
}
http://plnkr.co/edit/VA1XWWrG3pghEcWli06F?p=info
the current code allows me to select a specific item in the row, all I want is to change the css of all the Preceeding items in the row along with the current item.
any help would be really appreciated.
thanks
I am not sure what you are actually looking for but I think you can achieve the functionality by using loop limit with the parent index. Here's an example of code demonstration.
<div ng-repeat="fb in feedback" ng-init="outerIndex = $index">
{{fb.question}}
<br/>
<span style="margin-left:10px" ng-repeat="star in fb.stars"
ng-init="innerIndex = $index">
<button class="btn btn-default" ng-class="{ 'btn-info': star.isActive === true}" ng-click="itemClicked(star, fb)"> {{star.icon}} </button>
</span>
<br/><br/>
</div>
$scope.itemClicked = function (outer, inner) {
/* changing disabling all the items first */
for(var loop = 0; loop < outer.stars.length; loop++){
outer.stars[loop].isActive = false;
}
for(var loop = 0; loop < outer.stars.length; loop++){
if(outer.stars[loop] !== inner )
outer.stars[loop].isActive = true;
else
break;
}
inner.isActive = true;
}
http://plnkr.co/edit/1R9tqXM0yinvBQxfKNgD?p=preview
You can replace the buttons with your star icons. Hope this helps.
Looking at the documentation I'm supposed to prepend :: to the expression and it should remove itself. What I don't get is why it sometimes works and sometimes doesn't.
I've created a Plunker here that 80% of the time will run all the correct oneTime $$watchListener expressions (buttons should not work).
Yet sometimes in the Launch preview in full mode it doesn't fire and the buttons change the values.
I'm posting this because I just upgraded and they fail 100% of the time on my dev environment using the code below
<div class="user-location">
<span ng-if="::get.edit">
<span ng-if="::user.postal">
<span ng-bind="::user.postal"></span>
</span>
<span ng-if="::!user.postal">
<span>No postal</span>
</span>
Edit
</span>
<span ng-if="::!get.edit">
<span ng-bind="::user.postal"></span>
</span>
</div>
Anyone else have this issue or know of a sure fire way to trigger it?
Looking at the code:
// https://code.angularjs.org/1.3.0-beta.19/angular.js line 11404
if (!parsedExpression) {
if (exp.charAt(0) === ':' && exp.charAt(1) === ':') { // Expressions get through here
oneTime = true;
exp = exp.substring(2);
}
...
if (parsedExpression.constant) {
parsedExpression.$$watchDelegate = constantWatchDelegate;
} else if (oneTime) {
parsedExpression.$$watchDelegate = parsedExpression.literal ? // Get through here as well but the
oneTimeLiteralWatchDelegate : oneTimeWatchDelegate; // $$watchDelegate method never gets called
}
...