I'm dynamically generating a list of actions within my form. Example, save, approve, reject. When you click one of those actions, I'd like a spinner to appear within that button until I get a successful response from the server.
I have the following code.
buttons
<button type="submit" value="{{e.label}}" ng-click="getCtrlScope().formData.requestAction=e.action;" class="btn {{e.btnStyle}}" ng-repeat="e in buttonActions">
<span ng-show="saveState == 'save'"> {{e.label}} </span>
<span ng-show="saveState == 'loading'"> {{e.label}}
<i class="fa fa-spinner fa-spin"></i>
</span>
<span ng-show="saveState == 'completed'"> {{e.label}}
<i class="fa fa-check"></i>
</span>
</button>
js
$scope.saveState = 'save' ;
$scope.save = function() {
$scope.saveState = 'loading'
$http.post('../reviewRequest.json', $scope.formData).then(
function(response) {
$scope.saveState = 'save'
}, function(response) {
});
};
As you can probable see, when you click an action all my buttons will start spinning. How do I limit the spin to a single button?
This is not a good practic, as mentioned by @fantarama, you should use a property inside the element, not the $scope.
Anyway, if you don't mind to, you could store the element you clicked on with your ng-click call
ng-click="getCtrlScope(e)..."
Store that element in some variable:
function getCtrlScope(element) {
$scope.clickedElement = element;
...
}
Then, in your HTML:
<span ng-show="saveState == 'save' && e !== clickedElement"> {{e.label}} </span>
<span ng-show="saveState == 'loading' && e === clickedElement"> {{e.label}}
<i class="fa fa-spinner fa-spin"></i>
</span>
<span ng-show="saveState == 'completed' && e === clickedElement"> {{e.label}}
<i class="fa fa-check"></i>
</span>
EDIT
Assuming your POST call is located in the getCtrlScope, you could do something like:
ng-show
conditionsHTML:
<button type="submit" value="{{e.label}}" ng-click="getCtrlScope(e).formData.requestAction=e.action;" class="btn {{e.btnStyle}}" ng-repeat="e in buttonActions">
<span ng-show="e.saveState == 'save'"> {{e.label}} </span>
<span ng-show="e.saveState == 'loading'"> {{e.label}}
<i class="fa fa-spinner fa-spin"></i>
</span>
<span ng-show="e.saveState == 'completed'"> {{e.label}}
<i class="fa fa-check"></i>
</span>
</button>
JS:
$scope.save = function(element) {
element.saveState = 'loading'
$http.post('../reviewRequest.json', $scope.formData).then(
function(response) {
element.saveState = 'save'
}, function(response) {
});
};
Based on your Plunker, I modified it a little. As you can see, the state of each button changes in an independant way as you click on them.
See the result here.