I'm trying to implement a custom directive that forces the user to hold a button instead of just clicking it, preventing numerous mistakes. A material design slider is present under the button to show how long the user has to click on the button.
But sometimes, there has to be moments where the button must not be clickable, for example if there is a form with incorrect values. I tried to set the ng-disabled attribute but nothing is working. What am I doing wrong ?
Js :
negoceExpedApp.directive('rkMouseHold', function ($interval, $timeout) {
return {
restrict: 'E',
scope: {
text: '=buttonText',
callback: '&callback',
isDisabled: '&isDisabled'
},
replace: true,
template: "<div style='width:fit-content'>" +
"<md-button ng-disabled='{{disabled}}' class='md-accent md-raised md-hue-400'>{{ text }} - {{ disabled }}</md-button><br>" +
"<md-progress-linear ng-show='c!=0' class='md-accent md-hue-400' md-mode='determinate' value='{{c/10}}'></md-progress-linear>" +
"</div>",
link: function (scope, element, attrs) {
scope.$watch(scope.isDisabled,(newVal)=>{
console.log("%c newVal","color:orange",newVal);
if(newVal==true){
scope.disabled = "true";
} else {
scope.disabled = 'false';
}
})
scope.c = 0;
scope.loop = null;
element.on('mousedown', () => {
scope.loop = $interval(function () {
$timeout(() => {
scope.c += 100
}, 0);
}, 100);
});
element.on('mouseup', () => {
$interval.cancel(scope.loop);
if (scope.c > 1000) {
scope.callback();
}
scope.c = 0;
})
}
}
})
Html :
<rk-mouse-hold callback="ctrl.saveForm()"
is-disabled="expedForm.$invalid"
button-text="'HOLD TO SAVE'">
</rk-mouse-hold>
ngDisabled
is just a wrap-up for regular disabled
directive, that supports interpolation. Now here how you setting disabled value
if(newVal==true){
scope.disabled = "true";
} else {
scope.disabled = 'false';
}
can be simplified to
scope.disabled = !!newVal;
And in the template
ERRONEOUS
<md-button ng-disabled='{{disabled}}' class='md-accent md-raised md-hue-400'> {{ text }} - {{ disabled }} </md-button><br>"
use ng-disabled='disabled'
instead of ng-disabled='{{disabled}}'
In this case you are passing exact boolean value, while what you doing - each time you are passing string value, which is considered as true.
After all, in your scope you defined your custom disabled like so
isDisabled: '&isDisabled'
&
is used for evaluated expressions or callback, if you want to pass a variable. Checkout this great article as for correct bindings, and replace your code to
isDisabled: '@'