I have a form where I need users to input a time duration, in the resource this is saved as minutes (or milliseconds, easy change). I need the directive to take the second/millisecond value then create 3 separate inputs for the minutes, seconds & milliseconds.
Users can then modify each of the components and the directive will then update the model with the seconds/millisecond value of the 3 components.
I seem to be able to take the model value, create the 3 inputs and using moment.js create the separate components of time.
Directive
angular.module('myExampleApp')
.directive('lapTimeInput', function () {
var tpl = '<div class="lap_time_input"> \
<input ng-model="lap_time.minutes" type="number" class="minutes" placeholder="00" min="0" max="15" step="1"> \
<span class="lap-time-sep">:</span> \
<input ng-model="lap_time.seconds" type="number" class="seconds" placeholder="00" min="0" max="59" step="1"> \
<span class="lap-time-sep">.</span> \
<input ng-model="lap_time.milliseconds" type="number" class="milliseconds" placeholder="000" min="0" max="999" step="1"> \
</div>';
return {
restrict: 'A',
template: tpl,
replace: true,
require: 'ngModel',
scope: {
},
link: function (scope, element, attrs, ngModel) {
if (!ngModel) return;
scope.$watch(function () {
return ngModel.$modelValue;
}, function(newValue) {
// Using moment.js to extract min, sec & ms parts
var duration = moment.duration(newValue, 'seconds');
scope.lap_time = {
minutes: duration.minutes(),
seconds: duration.seconds(),
milliseconds: duration.milliseconds()
}
});
}
};
});
Controller
$scope.lap = Lap.get({ id: 1 }); // $resource contains .lap_time property
// OR
$scope.lap = {
lap_time: 90.999
}
HTML
<input type="text" lap-time-input ng-model="lap.lap_time" />
This Plunker will hopefully be a bit clearer
http://plnkr.co/edit/xmNtlItembSUFFZzaT9n?p=preview
Now I'm not even sure I've gone down the right path with using $watch on ngModel, I would guess not. As I understand it I need the directive to do 3 things:
Even just a nudge in the right direction would be a great help
This is what I managed to come up with. Not exact answer but should help you on your way.
Template
Updated the template and passed in the lap time as an attribute to be retrieved via the directive scope (see directive section)
<div lap-time-input="lap.lap_time"></div>
Controller
angular.module('myExampleApp')
.controller('myExampleCtrl', function ($scope) {
// This would usually be a $resouce return via a serice
$scope.lap = {
lap_time: 90.999
};
// watch value of lap time change here when you update minute/second/millisecond
$scope.$watch('lap.lap_time', function (newLapTime) {
console.log('newLapTime', newLapTime);
});
});
Directive
Added the second/milliseconds input field to the template. You probably don't need it, but I put it there for visual/debug reason.
angular.module('myExampleApp')
.directive('lapTimeInput', function () {
var tpl = '<div class="lap_time_input"> \
<input ng-model="lapTimeInput" type="number" placeholder="00.00"> \
<input ng-model="lap_time.minutes" type="number" class="minutes" placeholder="00" min="0" max="15" step="1"> \
<span class="lap-time-sep">:</span> \
<input ng-model="lap_time.seconds" type="number" class="seconds" placeholder="00" min="0" max="59" step="1"> \
<span class="lap-time-sep">.</span> \
<input ng-model="lap_time.milliseconds" type="number" class="milliseconds" placeholder="000" min="0" max="999" step="1"> \
</div>';
return {
restrict: 'A',
template: tpl,
replace: true,
scope: {
lapTimeInput: '='
},
link: function (scope) {
// watch for changes in lapTimeInput and update the lap_time model/object
scope.$watch('lapTimeInput', function (newValue) {
var duration = moment.duration(newValue, 'seconds');
scope.lap_time = {
minutes: duration.minutes(),
seconds: duration.seconds(),
milliseconds: duration.milliseconds()
}
});
// watch for changes in the lap_time model/object
scope.$watchCollection('lap_time', function (newTime, oldTime) {
console.log(newTime);
// convert back to lap time with momentjs here
scope.lapTimeInput = moment.duration(newTime, 'seconds').asSeconds();
});
}
};
});
JSFIDDLE
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