loader for ng-repeat in angular js - angularjs

I have repeated data in a table like
<td>{{todo.title}}</td>
<td>
<button ng-show="loader">Deleting...</button>
<button ng-hide="loader" ng-click="delete(todo.id)">Delete</button>
</td>
Js code:
$scope.loader = false;
$scope.delete = function(id) {
$scope.loader = true;
$http.delete(url).success(function() {
$scope.loader = false;
})
}
It's working for deleting record but deleting... Button shows for every row. I can't handle for current row.

Use loader as todo property
like this
<button ng-show="todo.loader">Deleting...</button>
<button ng-hide="todo.loader" ng-click="delete(todo)">Delete</button>
JS
$scope.delete=function(todo){
todo.loader=true;
$http.delete(url).success(function(){
todo.loader=false;
})
}
DEMO

Related

Angular 1.4: Disable button after click

I have a situation where I want to disable the button for a few seconds when clicked. Here is the code for button:
<button uib-popover="Create TO" popover-trigger="mouseenter" data-ng-click="createTransportOrder(item.confirmed_price_id)" data-ng-disabled="item.transport_order_id || !item.confirmed_price_id" class="btn btn-info btn-xs">
<i class="fa fa-truck"></i>
</button>
And here is the createTransportOrder method:
$scope.createTransportOrder = function (priceResponseId) {
var priceResponseIds = [priceResponseId];
PriceRequestsModel.createTransportOrdersByIds(priceResponseIds).then(
function (response) {
$scope.messages = response.messages;
updateSelectedPriceRequests();
getPriceRequests();
},
function (response) {
$scope.messages = response.messages;
}
)
};
I have tried a couple of things but in vain. How can I do this?
You can add setTimeout at the end of createTransportOrder
this.button.nativeElement.disabled = true;
setTimeout(function(){
this.button.nativeElement.disabled = false;
},5000);
Add #mybutton to your button <button (click)="yourclick()" #mybutton>Your button</button>
add variable #ViewChild('mybutton') button; to your component
Stackbliz demo code: https://stackblitz.com/edit/angular-disable-5second
With angular 1.4 you can change to
Set an id to your button as <button id="mybutton">
Add these code to below of click function.
document.getElementById('mybutton').disabled = true;
setTimeout(function(){
document.getElementById('mybutton').disabled = false;
},5000);

How to trigger the click event inside ng-repeat of angularjs?

I am doing the ng-repeat for showing the project list in my app. on click on the individual project I need to show the list of surveys inside the project. But when the page get loaded for first time I want to trigger the click event of first project which is default.
Below is the html code for that list project.
projectlist.html
<ul class="sidebar-nav">
<li class="sidebar-brand" >
<a>
Projects
</a>
</li>
<li ng-repeat="obj in allProjects track by $id(obj)">
<a ui-sref="survey.surveyList({id: obj.ProjectID})" ng-click="getProjSurveys(obj.ProjectID)" data-id="{{obj.ProjectID}}">{{obj.ProjectName}}<span class="projectsetting"><img src="./images/settings.png"/></span></a>
</li>
</ul>
ctrl.js
require('../styles/survey/survey.less');
angular.module("adminsuite").controller("surveyController",['getAllSurveyService','$timeout','AuthenticationService', '$scope','$rootScope', '$state', '$stateParams', function(getAllSurveyService,$timeout, AuthenticationService,$scope,$rootScope,$state,$stateParams){
$rootScope.header = "survey";
$scope.hoverIn = function(){
this.hoverEdit = true;
};
$scope.hoverOut = function(){
this.hoverEdit = false;
};
$rootScope.surveySelected = false;
console.log($('.checked').length);
console.log($('.checkbox').length);
if($state.current.name != 'login'){
$rootScope.bgGround = 'bgBlank';
$rootScope.footerbgGround = 'bgFooter';
}
$scope.supported = false;
$scope.wapLink = 'http://apidev.1pt.mobi/i/interview?uid=188A80CF0D61CA60D2F5_495F23E0FD4B9120D1E7&surveyid=20903';
$scope.success = function ($event) {
$scope.supported = true;
console.log($(".copied"));
};
$scope.fail = function (err) {
console.error('Error!', err);
};
getAllSurveyService.surveyList().then(
function( data ) {
$scope.allProjects = data;
$scope.allSurveys = data[0].Surveys;
if($scope.allSurveys.ErrorMessage){
AuthenticationService.ClearCredentials();
}
}
);
$scope.getReportDetails = function(){
return $http.get('http://localhost:8395/api/UserSurvey/GetAllSurveys', {
headers: { 'Content-Type': 'application/json','SessionID':$rootScope.token}
})
};
$scope.getProjSurveys = function(projId){
var i;
for(i in $scope.allProjects){
if(projId == $scope.allProjects[i].ProjectID){
$scope.allSurveys = $scope.allProjects[i].Surveys;
}
}
angular.element(document.querySelectorAll(".surveymodule")).removeClass('toggled');
};
$scope.toggleClass = function($event){
angular.element($event.target).toggleClass("checked");
$rootScope.selectedItems = angular.element(document.querySelectorAll(".checked")).length;
angular.element($event.target).parent().toggleClass("active");
if(angular.element(document.querySelectorAll(".checked")).length < 1){
$rootScope.global.showNewHeader= false;
};
};
}]);
on-click of the projects I am able to show data in the ui-view but for the first time on load of the page unable to trigger click event for the first project. I tried with the above code inside the controller using angular.element and trigger('click'), but it is not working for me. Please help.
This is actually angularjs issue. JQuery's trigger click event not getting triggered in angular's ng-repeat.
Check this : https://github.com/angular/angular.js/issues/3470
The problem is you are using ui-sref along with ng-click. Here the state is changing before the function completes and either reloading the controller (if both states has same controller) or changing the controller. Hence ng-click finction is not running.
remove ui-sref and use $state.go() to change the state inside ng-click
Sample code here:
HTML
<ul class="sidebar-nav">
<li class="sidebar-brand" >
<a>
Projects
</a>
</li>
<li ng-repeat="obj in allProjects track by $id(obj)">
<a ng-click="getProjSurveys(obj.ProjectID)" data-id="{{obj.ProjectID}}">{{obj.ProjectName}}<span class="projectsetting"><img src="./images/settings.png"/></span></a>
</li>
</ul>
JS:
$scope.getProjSurveys(objId){
// your codes here
$state.go('survey.surveyList({'id': objId})')
}
Instead of trying to interact with the DOM you should do something like this:
getAllSurveyService.surveyList().then(
function( data ) {
$scope.allProjects = data;
$scope.allSurveys = data[0].Surveys;
$scope.getProjSurveys($scope.allProjects[0].ProjectID)
if($scope.allSurveys.ErrorMessage){
AuthenticationService.ClearCredentials();
// $state.go('login');
}
});

Multi page form, back button to change state

I have multi page form that has a back button built in. I want to change state when chapterID reaches 0.
$state.go executes but then redirects back to gn.newChapter state
HTML:
<a ui-sref="gn.newChapter({chapterID: id})" class="btn btn-primary" ng-click="goBack()">Go Back</a>
Controller:
$scope.goBack = function() {
if (newChapterService.getChapterState() === 0) {
$state.go('gn.createGNForm');
}
else {
$scope.id = newChapterService.goBackChapter();
}
};
<a class="btn btn-primary" ng-click="goBack()">Go Back</a>
$scope.goBack = function() {
if (newChapterService.getChapterState() === 0) {
$state.go('gn.createGNForm');
}
else {
$scope.id = newChapterService.goBackChapter();
$state.go('gn.newChapter({chapterID: $scope.id})'); // I don't know your predefined paths. so just suggesting this as an answer. This line might be different according to your need.
}
};

Updating Angular originally loaded via JSONP

I have a resource that returns a JSONP payload:
app.factory('JsonService', function($resource) {
return $resource('//123.456.7.890\\:8888/user/:id/:model',
{'page': ':page', 'limit' : ':limit', 'jsonp_callback' : 'JSON_CALLBACK'},
{})
});
Which gets called by my controller:
app.controller("followersCtrl", function ($scope, $dialog, JsonService) {
...
$scope.user_id = $.globals.authed_user_id;
$scope.model = "followers"
$scope.loadJSONP = function (getPage) {
JsonService.get({
id: $scope.user_id,
page: getPage,
limit: $scope.pagination_limit,
model: $scope.model
},
function (data) {
$scope.followers = data;
$scope.noOfPages = data.page_count;
$scope.currentPage = data.page;
});
};
$scope.loadJSONP(1);
$scope.pageChanged = function (page) {
$scope.callbackPage = page;
$scope.loadJSONP(page);
};
});
Then I loop over the data returned/stored in $scope.followers:
<div ng-controller="followersCtrl">
...
// Code related to the modal omitted
...
<div ng-repeat="user in followers.data">
<img class="img img-polaroid" ng-src="{{user.image_url}}"/>
<p>{{ user.username }}</p>
<button class="btn btn-disabled" ng-show="user.is_mutual">
You Are following this user
</button>
<button class="btn btn-primary" ng-show="!user.is_mutual">
You Aren\'t following
</button>
<p>{{user.total_followers}}</p>
</div>
...
// Code related to the modal omitted
...
</div>
That all works as expected, but for the life of me I cannot figure out how to have the "You are not following" button change the value that's reflected inside the corresponding {{post.total_followers}} expression on click. Ideally, I would like to perform a PUT to actually perform the follow action, but I decided to start small and just update the value, to no avail.
Any help is appreciated. Thank you.
Is ng-click what you're looking for?
HTML:
<button class="btn btn-primary" ng-show="!user.is_mutual" ng-click="follow(user)">
You Aren\'t following
</button>
JS:
app.controller("followersCtrl",
function ($scope, $dialog, JsonService) {
$scope.follow = function(user){
// code for posting to server-side follow action
// and updating the total_followers
// $scope.user.total_followers++; // this should be ideally incremented on success callback
}
}
);

Angularjs toggle image onclick

I'm trying to toggle a button image when a user clicks it. I prefer to use angularjs instead of jquery if possible. Right now I have a working version which toggles the image when clicked, the only problem is it changes ALL the images on click. How do I reduce the scope or pass in the src attribute for the img element?
<div ng-repeat="merchant in merchants">
<div class="followrow">
<a ng-click="toggleImage()"><img id="followbutton" ng-src="{{followBtnImgUrl}}" /></a>
</div>
</div>
app.controller('FollowCtrl', function CouponCtrl($scope) {
$scope.followBtnImgUrl = '/img1'
$scope.toggleImage = function () {
if ($scope.followBtnImgUrl === '/img1.jpg') {
$scope.followBtnImgUrl = baseUrl + '/img2.jpg';
} else {
$scope.followBtnImgUrl = 'img1.jpg';
}
}
});
Can I pass in the img src attribute the function like toggleImage(this.img.src) or similar?
<div ng-repeat="merchant in merchants">
<div class="followrow">
<a ng-click="toggleImage(merchant)"><img id="followbutton" ng-src="{{merchant.imgUrl}}" />
</a>
</div>
</div>
.
app.controller('FollowCtrl', function CouponCtrl($scope) {
$scope.followBtnImgUrl = '/sth.jpg'
$scope.merchants = [{imgUrl: "img1.jpg", name:"sdf"},
{imgUrl: "img2.jpg", name: "dfsd"}];
$scope.toggleImage = function(merchant) {
if(merchant.imgUrl === $scope.followBtnImgUrl) {
merchant.imgUrl = merchant.$backupUrl;
} else {
merchant.$backupUrl = merchant.imgUrl;
merchant.imgUrl = $scope.followBtnImgUrl;
}
};
});
What you want is a new scope for each followrow. As your code stands, there's only one scope that all of the followrows are referencing.
A simple answer is to create a new controller that you attach to each followrow:
<div class="followrow" ng-controller="ImageToggleCtrl">...</div>
And then move the image toggling logic to that new controller:
app.controller('ImageToggleCtrl', function($scope) {
$scope.followBtnImgUrl = '/img1';
$scope.toggleImage = function() { /* the toggling logic */ };
});
Now, a new scope will be instantiated for each row, and the images will toggle independently.
I just added two clickable images:
<div ng-app="FormApp" ng-controller="myController" max-width="1150px;" width="1150px;" >
<input ng-show="ShowDown" type="image" style="width:250px; height:40px;" src="~/Content/Images/contactShow.png" ng-click="ShowHide()"/>
<input ng-show="ShowUp" type="image" style="width:250px; height:40px;" src="~/Content/Images/contactHide.png" ng-click="ShowHide()" />
</div>
They toggle eachothers visibility. At page load one is visible, one is not, and both clickable images call the same function:
<script type="text/javascript">
var app = angular.module('FormApp', [])
app.controller('myController', function ($scope) {
$scope.ShowDown = true;
$scope.ShowUp = false;
$scope.ShowHide = function () {
$scope.ShowDown = $scope.ShowDown ? false : true;
$scope.ShowUp = $scope.ShowUp ? false : true;
}
});
</script>

Resources