In Angular.js I'm passing a number to my view which is the length of time something takes in minutes.
<p>{{time.minutes}}</p>
I want to format this value so it displays in hours and minutes e.g (6h 42m). I tried using some of the inbuilt date functions but couldn't get anywhere. Is it better to do this sort of logic in the controller before passing it to the view or is it possible in the view?
What about this:
One line solution
<pre>
with hours: {{ (time.minutes<60) ?
(time.minutes) + 'm' : (time.minutes%60==0) ?
(time.minutes-time.minutes%60)/60 + 'h' :
((time.minutes-time.minutes%60)/60 + 'h' + ' ' + time.minutes%60 + 'm') }}
</pre>
Demo 1 Fiddle
Suggested solution
JS
if($scope.time.minutes < 60){
$scope.time.result = ($scope.time.minutes) + 'm';
}
else if($scope.time.minutes%60==0){
$scope.time.result = ($scope.time.minutes-$scope.time.minutes%60)/60 + 'h';
}
else{
$scope.time.result = (($scope.time.minutes-$scope.time.minutes%60)/60 + 'h' + ' ' + $scope.time.minutes%60 + 'm');
}
HTML
<pre>with hours: {{ time.result}}</pre>
Demo 2 Fiddle
Test:
minutes = 29 -> Output '29m'
minutes = 60 -> Output '1h'
minutes = 123 -> Output '2h 3m'
More suggested way (Directive)
Directive
app.directive('myHours', function () {
return {
restrict: 'E',
replace: true,
scope: {
myData: '='
},
template: '<pre>with hours: {{myData.result}}</pre>',
link: function (scope, elem, attrs) {
var calc = function (time) {
if (time < 60) {
return (time) + 'm';
} else if (time % 60 == 0) {
return (time - time % 60) / 60 + 'h';
} else {
return ((time - time % 60) / 60 + 'h' + ' ' + time % 60 + 'm');
}
}
scope.myData.result = calc(scope.myData.minutes);
}
};
});
HTML
<my-hours my-data="time"></my-hours>
Demo 3 Fiddle
As what Whisher mentioned, a filter is more appropriate in changing the format of your html output.
I have created a filter not long ago, that can convert the given time value based on the unit of measure in time(hours, minutes, seconds) into a specific format that suits the taste of its user.
DEMO
JAVASCRIPT
.filter('time', function() {
var conversions = {
'ss': angular.identity,
'mm': function(value) { return value * 60; },
'hh': function(value) { return value * 3600; }
};
var padding = function(value, length) {
var zeroes = length - ('' + (value)).length,
pad = '';
while(zeroes-- > 0) pad += '0';
return pad + value;
};
return function(value, unit, format, isPadded) {
var totalSeconds = conversions[unit || 'ss'](value),
hh = Math.floor(totalSeconds / 3600),
mm = Math.floor((totalSeconds % 3600) / 60),
ss = totalSeconds % 60;
format = format || 'hh:mm:ss';
isPadded = angular.isDefined(isPadded)? isPadded: true;
hh = isPadded? padding(hh, 2): hh;
mm = isPadded? padding(mm, 2): mm;
ss = isPadded? padding(ss, 2): ss;
return format.replace(/hh/, hh).replace(/mm/, mm).replace(/ss/, ss);
};
});
HTML USAGE
<!--
65 minutes converted to hh:mm:ss format which is the default format = 01:05:00
The parameter 'mm' suggests the the time value(65) is a unit of measure in minutes.
-->
<pre>{{65 | time:'mm'}}</pre>
<!--
65 minutes converted to the OP's desired output = 1h 5m
the parameter 'hhh mmm' suggests the format of the output desired
by the OP, the "hh" and "mm" text are replace with the hour value and
the minute value
the last parameter which is a boolean value suggests that the hour(hh), minute(mm),
second(ss) values are not padded. E.G. hour = 2 output would be 02. By default, this
parameter is set to true.
-->
<pre>{{65 | time:'mm':'hhh mmm':false}}</pre>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With