RushilAhuja RushilAhuja - 24 days ago 8
AngularJS Question

Not able to use ng-disabled directive

All of you may find that this question has already been answered but believe that I have tried all the available solutions. So I have a button that is disabled using ng-disabled. There is a variable in the $scope and when that variable changes I want the ng-disabled attribute to change. But this is not happening

<button role="buttton" class="btn btn-lg btn-success pull-right" ng-disabled="isDisabled == 'true'" id="next">Next</button>


app.controller('goalpathController', ['$scope', '$progress', function($scope, $progress){

$scope.isDisabled = 'true';
$scope.prog = $progress.getProgress() * 25;
console.log($scope);
var isAdvancedUpload = function(){
var div = document.createElement('div');
return ( ( 'draggable' in div ) || ( 'ondragstart' in div && 'ondrop' in div ) ) && 'FormData' in window && 'FileReader' in window;
}();


var forms = document.querySelectorAll('form');
Array.prototype.forEach.call(forms, function(form){

var input = form.querySelector('input[type="file"]');

var dropBox = form.querySelector('.box');
console.log(dropBox);


var errorMsg = form.querySelector('.box__error span');

var restart = form.querySelectorAll('.box__restart');

var droppedFiles = false;
//for invoking the event listeners on the form
triggerFormSubmit = function(){
var event = document.createEvent('HTMLEvents');
event.initEvent('submit', true, false);
form.dispatchEvent(event);
};

//hidden button which is used for form submission
var ajaxFlag = document.createElement('input');
ajaxFlag.setAttribute('type', 'hidden');
ajaxFlag.setAttribute('name', 'ajax');
ajaxFlag.setAttribute('value', 1);
form.appendChild(ajaxFlag);

//automatically submit the form on file select
input.addEventListener('change', function(e){
console.log(e.target.files);
droppedFiles = e.target.files;
triggerFormSubmit();
})

if(isAdvancedUpload){

dropBox.classList.add('has-advanced-upload');
[ 'drag', 'dragstart', 'dragend', 'dragover', 'dragenter', 'dragleave', 'drop' ].forEach(function( event ){
dropBox.addEventListener( event, function( e )
{
// preventing the unwanted behaviours
e.preventDefault();
e.stopPropagation();
});
});
[ 'dragover', 'dragenter' ].forEach( function( event ){
dropBox.addEventListener( event, function()
{
dropBox.classList.add( 'is-dragover' );
});
});
[ 'dragleave', 'dragend', 'drop' ].forEach( function( event ){
dropBox.addEventListener( event, function()
{
dropBox.classList.remove( 'is-dragover' );
});
});
dropBox.addEventListener('drop', function( e ){
droppedFiles = e.dataTransfer.files; // the files that were dropped
triggerFormSubmit();

});
}
form.addEventListener('submit', function(e){
//preventing the multiple file loading at the same time
if(dropBox.classList.contains('is-uploading')){
return false;
}

dropBox.classList.add('is-uploading');
dropBox.classList.remove('is-error');

if(isAdvancedUpload){
e.preventDefault();

var ajaxData = new FormData();


if(droppedFiles){
Array.prototype.forEach.call(droppedFiles, function(file){

ajaxData.append(input.getAttribute('name'), file);
console.log(file);
for(var pair of ajaxData.entries()){
console.log(pair[0] + " " + pair[1]);
}

});
}

//ajax request
var ajax = new XMLHttpRequest();

ajax.open(form.getAttribute('method'), form.getAttribute('action'), true);


ajax.onload = function(){
dropBox.classList.remove('is-uploading');
if(ajax.status >= 200 && ajax.status < 400){
var data = JSON.parse(ajax.responseText);

console.log(data);
form.classList.add(data.success == true ? 'is-success' : 'is-error');

if(data.success){

$progress.incrementProgress();
$scope.prog = $progress.getProgress() * 25;
$scope.isDisabled = 'false';

var bar = document.getElementById('progressBar');
var btn = document.getElementById('next');


bar.setAttribute('aria-valuenow', $scope.prog);
bar.style.width=$scope.prog + '%';

console.log(bar);
console.log(btn);
console.log($scope);
}

if(!data.success){
errorMsg.textContent = data.error;
}
}
else{
alert('Error. Please, contact the webmaster!');
}
}

ajax.onerror = function(){
form.classList.remove('is-uploading');
alert('Error. Please try again!');
}
ajax.send(ajaxData);
}

});
})
}])


if you look at the bottom, I am making an ajax request and when that ajax request is fulfilled I am changing the value of the isDisabled variable and based on this I want my ng-disabled directive to vary. But this is not happening and the button is maintaining its old state.

Answer

Whenever you update your angular model it needs to be inside a digest. Most of the time angular will try to do this for you, but you have created your own ajax callback which Angular knows nothing about.

ajax.onload = function(){
    //...
};

Could beome

ajax.onload = function(){
    $scope.$apply(function(){
        //...
    });
};

This will trigger a digest cycle, so the view will actually respond to changes in your model.

Comments