ng-class only for current scope in ng-repeat angularjs - javascript

I'm having trouble with the ng-class part of AngularJS.
The only thing I figured out was adding the class after a success or error to allll buttons where the ng-click was on.
But I only want to add/change the class of the currently clicked element. Is that even possible in a way?
<section ng-repeat="user in users">
<button class="btn" ng-click="myFunction(user);" ng-class="{invalid:errors,done:success}"></button>
</section>
<script>
function UsersController($scope, $http) {
$http.get('/users.json').success(function(users) {
$scope.users = users;
$scope.errors = false;
$scope.success = false;
});
$scope.myFunction = function(user) {
$http.post('/myUrl/'+user.id, student)
.success(function(data, status, headers, config) {
// $scope.success = true;
user.success = true;
})
.error(function(data, status, headers, config) {
// $scope.errors = true;
user.errors = true;
});
}
}
</script>
What I want is just the current scope, but that doesn't work.
My function does work, except for passing the ng-class values trough.

Another solution:
<section ng-repeat="user in users">
<button class="btn" ng-click="myFunction(user)"
ng-class="{invalid: isInvalid(user), done: isSuccess(user)}">{{user.name}}</button>
</section>
So you create isInvalid and isSuccess functions and pass in current user object:
$scope.isSuccess = function(user) {
return user === $scope.state.success;
};
$scope.isInvalid = function(user) {
return user === $scope.state.errors;
};
These two functions can decide if current user is invalid or successful. For example when there is an error you set it like this:
$scope.state = {
success: false,
errors: user
};
Demo: http://plnkr.co/edit/RDJy9VsRkhAO0cFnb6AV?p=preview

Have a property on the scope to represent the current user and a test for it in the ng-class expression:
$scope.currentUser = null;
$scope.myFunction = function(user) {
$http.post('/myUrl/'+user.id, student)
.success(function(data, status, headers, config) {
$scope.currentUser = user;
user.success = true;
})
.error(function(data, status, headers, config) {
user.errors = true;
});
};
ng-class="{invalid:user.errors && currentUser == user,done:user.success && currentUser == user}"

Instead of attaching the function myFunction to the $scope, you want to attach it to each user as such...
for(var i=0;i<users.length;i++){
users[i].myFunction= function(id){...}
}
and then for your ng-class you do.
ng-class={invalid: user.errors, done:user.success}

Related

Why are the functions being called in my angular html bindings receiving null values?

I am creating a simple web app that represents something like a trip planner. Just offers some simple itinerary options from a list of locations in a DB I made. My feed page is supposed to display pictures of each attraction, and each attraction is a clickable card that will lead you to another page with some more info on that attraction.
//
// init app
var tripperApp = angular.module('tripperApp', ["ui.router", 'ionic', 'LocalStorageModule']);
//
// setup routing
tripperApp.config(function($stateProvider, $urlRouterProvider) {
// For any unmatched url, redirect to /state1
$urlRouterProvider.otherwise("/splash");
// Now set up the states
$stateProvider
.state('splash', {
url: "/splash",
templateUrl: "partials/splash.html",
controller: "splashCtrl"
})
.state("login", {
url: "/login",
templateUrl: "partials/login.html",
controller: "loginCtrl"
})
.state("signup", {
url: "/signup",
templateUrl: "partials/signup.html",
controller: "signupCtrl"
})
.state("reset-password", {
url: "/reset-password",
templateUrl: "partials/reset-password.html",
controller: "resetPasswordCtrl"
})
.state("set-password", {
url: "/set-password/:user_id/:password_reset_hash",
templateUrl: "partials/set-password.html",
controller: "resetPasswordCtrl"
})
.state("feed", {
url: "/feed",
templateUrl: "partials/feed.html",
controller: "feedCtrl"
})
.state("wishlist", {
url: "/wishlist",
templateUrl: "partials/feed.html",
controller: "wishlistCtrl"
})
.state("specificwishlist", {
url: "/wishlist/:user_id",
templateUrl: "partials/feed.html",
controller: "wishlistCtrl"
})
.state("share", {
url: "/share",
templateUrl: "partials/share.html",
controller: "shareCtrl"
})
.state("attraction", {
url: "/attraction/:attraction_id",
templateUrl: "partials/attraction.html",
controller: "attractionCtrl"
});
});
This is my app.js file where I initialize all my routings and controllers. I think I am literally having problems with everything (I have a backend and everything in Nodejs, but that isn't working right because all of the values it receives is null - more on that later...).
The main problem I am seeing is that nearly all the data I am receiving is null. Nothing is really loading right - but I know that I have a proper connection to my DB. Because there are some places where I can see the correct results. Let me explain:
This is my services/feed.js file (I don't think it's very important):
//
// feed service: used to get setup filters and then query for a feed using those filters
tripperApp.factory("feedService", ["$rootScope", "api", function($rootScope, api) {
var feedService = {};
api.get("filters").success(function(data, status, headers, config) {
$rootScope.filters = data;
})
.error(function(data, status, headers, config) {
// #TODO - gracefully handle error
});
feedService.runSearch = function($rootScope, session, callback) {
// add on more results
api.post("search", {
"start": $rootScope.currentSpot
})
.success(function(data, status, headers, config) {
// copy results into array
for (var i = 0; i < data.length; i++) {
$rootScope.results.push(data[i]);
}
$rootScope.currentSpot += data.length;
// call callback
callback(true); // success!
})
.error(function(data, status, headers, config) {
callback(false); // error!
});
};
feedService.getWishlist = function($rootScope, session, callback) {
// get all results
api.post("wishlist", {
"attraction_ids": session.picks
})
.success(function(data, status, headers, config) {
// copy results into array
$rootScope.results = data;
callback(true); // success!
})
.error(function(data, status, headers, config) {
callback(false); // error!
});
};
// column-related functions
$rootScope.columns = function() {
var columns = 1;
var windowWidth = window.innerWidth;
if (windowWidth > 1300) {
columns = 5;
} else if (windowWidth > 1100) {
columns = 4;
} else if (windowWidth > 640) {
columns = 3;
} else if (windowWidth > 300) {
columns = 2;
}
var rv = [];
for (var i = 0; i < columns; i++) {
rv.push(i);
}
return rv;
}
$rootScope.getColumn = function(data, columnNumber) {
var columns = $rootScope.columns().length;
var rv = [];
for (var i = columnNumber; i < data.length; i += columns) {
rv.push(data[i]);
}
return rv;
}
$rootScope.columnClasses = function() {
var columns = $rootScope.columns().length;
return {
"col-33": (columns == 3),
"col-25": (columns == 4),
"col-20": (columns == 5),
"col-50": (columns == 2)
};
}
// generate thumbnail of a url
$rootScope.thumb = function(filename) {
return filename + ".thumb.jpeg";
}
return feedService;
}]);
This is my controller (controller/feed.js) file:
//
// feed controller
tripperApp.controller("feedCtrl", function($scope, $rootScope, session, feedService, $ionicScrollDelegate) {
// setup feed page (only once)
if (typeof($rootScope.feed) == "undefined") {
// first time loading - setup scope
$rootScope.feed = {
results: [],
currentSpot: 0
}
}
// auto scroll down (if appropriate)
window.setTimeout(function() {
if (typeof($rootScope.feed.lastScrollPosition) != "undefined") {
$ionicScrollDelegate.$getByHandle('feedScroll').scrollTo(0, $rootScope.feed.lastScrollPosition, false);
}
}, 0);
// tell feed template that this is NOT for a wish
$scope.wishlist = false;
// don't display share button on feed
$scope.displayShare = function() {
return false;
}
// query and display results
$scope.loadResults = function() {
feedService.runSearch($rootScope.feed, session, function(success) {
if (!success) {
// #TODO - handle error
}
$scope.$broadcast('scroll.infiniteScrollComplete');
});
}
// whether an attraction is picked
$scope.attractionIsPicked = function(attraction_id) {
return session.picks.indexOf(attraction_id) != -1;
};
// when a result is picked/unpicked
$scope.resultPicked = function(result) {
var attraction_id = result.id;
console.log(result);
console.log(attraction_id);
if (session.picks.indexOf(attraction_id) == -1) {
// not yet picked, so lets pick it
session.pickPlace(attraction_id);
} else {
// its picked, so lets unpick it
session.unpickPlace(attraction_id);
}
}
$rootScope.clickedResult = undefined;
$scope.resultClicked = function(result) {
$rootScope.clickedResult = result;
console.log("result: \n");
console.log(result);
$rootScope.feed.lastScrollPosition =
$ionicScrollDelegate.$getByHandle('feedScroll').getScrollPosition().top;
}
});
There are a couple of functions I am specifically having problems with:
resultPicked() in controller/feed.js and thumb() in services/feed.js. I am getting null values for both of these.
My partial/feed.html file is as such:
<ion-view>
<ion-header-bar class="bar bar-positive" align-title="center">
<div class="buttons">
<button class="button ion-navicon-round button-light" ng-click="toggleLeftMenu(); " style="font-size: 22px"></button>
</div>
<h1 class="title" ng-show="wishlist==false">New York Attractions</h1>
<h1 class="title" ng-show="wishlist==true">
<span ng-show="feed.user.name == 'Your'">Your</span>
<span ng-show="feed.user.name != 'Your'">{{feed.user.name}}'s</span>
Wish List
</h1>
<div class="buttons" ng-show="displayShare()">
<button class="button ion-android-share button-light" style="font-size: 22px" ng-click="sharePage();"></button>
</div>
</ion-header-bar>
<ion-content class="padding feed-page" delegate-handle="feedScroll">
<ion-list>
<!-- display results in columns -->
<div class="row">
<div class="col" ng-class="columnClasses()" ng-repeat="column in columns()" >
<div class="card" ng-repeat="result in getColumn(feed.results, column)" ng-show="feed.results.length > 0">
<div class="item item-image">
<a>
<img ng-src="{{thumb(result.src)}}" ui-sref="attraction({attraction_id: result.id})" ng-click="resultClicked(result)">
</a>
</div>
<div class="item item-bottom-sect">
<div class="row">
<div class="col-75 col-wrap">
<a ui-sref="attraction({attraction_id: result.id})" ng-click="resultClicked(result)" class="item-title">{{result.title}}</a>
</div>
<div class="col-25 right col-wrap">
<span ng-click="resultPicked(result)">
<span class="ion-heart heart heart-selected" ng-show="attractionIsPicked(result.id)" class="heart-selected"></span>
<span class="ion-heart heart" ng-show="!attractionIsPicked(result.id)"></span>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</ion-list>
<ion-infinite-scroll
ng-if="!resultsLoaded"
on-infinite="loadResults()"
distance="10%">
</ion-infinite-scroll>
</ion-content>
</ion-view>
Now, in my feed, there are two called to resultClicked() and one to resultPicked(). resultClicked(result) will return results just fine - but resultPicked(results) will always gets a null value! Also, thumb(result.src) always gets a null value. I have absolutely ZERO idea what - this is just things I'm confirming from console.logs. Is there anything glaringly wrong with the code?
Edit:
Here is a picture displaying what I am talking about. The cards are all "broken links" because the value im getting back is null (undefined) as shown in console. The "results" are also null, as shown in the console, when called from resultPicked(), but not from resultClicked().

How to reset form after submit in AngularJS

I am new to AngularJS and trying to do a project. I have a form which works perfectly. However, there is only one thing that I should do. After adding a customer, I need to clear the form. Because, when the user wants to add a second customer, tthe user sees the previously entered values.
$scope.add = function () {
$scope.loading = true;
$http.post('/api/Customer/', this.newcustomer).success(function (data) {
alert("Added Successfully!!");
$scope.addMode = false;
$scope.customers.push(data);
$scope.loading = false;
}).error(function (data) {
$scope.error = "An Error has occured while Adding Customer! " + data;
$scope.loading = false;
});
};
Try this:
$scope.add = function () {
$scope.loading = true;
$http.post('/api/Customer/', this.newcustomer).success(function (data) {
alert("Added Successfully!!");
$scope.addMode = false;
$scope.customers.push(data);
$scope.loading = false;
this.newcustomer = {};
}).error(function (data) {
$scope.error = "An Error has occured while Adding Customer! " + data;
$scope.loading = false;
});
};
You have to manually clear the values of the form elements
This should do it:
delete $scope.newcustomer

Not able to obtain value in view (directive)

I have an array in the profile-form.html directive's controller.
But I am neither able to obtain the value of that array (all_languages) nor iterate over it using ng-options in the directive. It's simply printing as string. I am new to Angular and maybe doing everything terribly wrong.
Directive
app.directive("profileForm", function() {
return {
restrict: "E",
templateUrl: "/static/translatorNgApp/profile-form.html",
controller: ['$scope','$http',function($scope, $http) {
this.getCookie = function(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
console.log(cookieValue);
return cookieValue;
};
$scope.csrftoken = this.getCookie('csrftoken');
$scope.myForm={};
$scope.all_languages = ['English', 'Hindi'];
$scope.language_pairs = [];
$scope.getAllLanguages = function () {
$http.get('/getAllLanguages'
).success(function(response) {
// success
$scope.all_languages.concat(response);
}).error(function(response) {
// failed
});
};
$scope.submitForm = function() {
var postData = {
method: 'POST',
url: '/accounts/tprofile/',
// headers : {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
headers: {'X-CSRF-Token' : $scope.csrftoken },
data: $scope.myForm
};
$http(postData)
.then(function(response) {
// success
},
function(response) { // optional
// failed
});
console.log("Form submitted");
// $scope.message = "Sent Successfully 2";
// console.log(postData);
console.log(postData);
console.log($scope.myForm);
};
$document.ready(function(){
console.log("document ready");
$scope.getAllLanguages(); //This can be commented out for the question's sake.
});
}],
controllerAs: "profileFormCtrl"
};
});
Directive Template (profile-form.html)
<div class="form-group" >
<label for="id_source_language">Source language: </label>
<ul>
<li>
<pre>all_languages = {{all_languages | json}}</pre>
<select data-ng-model="source" ng-options="language for language in all_languages" class="form-control" id="id_source_language" name="source_language" placeholder="Source Language" required>
</select>
<button ng-click="language_pairs.pop($index)" aria-label="Remove">Remove</button>
<button ng-click="language_pairs.push({})">Add more pair</button>
</li>
</ul>
</div>
Using document.ready event inside a angular directive doesn't make sense to call specific method of scope. Because document.ready event has already happened after that event only angular started process page.
Ideally to make your code working state you need to remove $document.ready(function(){ .... }); code which isn't required there. And as document.ready is already accomplished, so the one which you had registered from directive wouldn't get call.

How to pass value from ng-click (AngularJS) to Laravel?

How to get value from ng-click and send to laravel for query?
//.html
<div ng-controller="recipientsController">
<div ng-repeat="recipient in recipients | orderBy:'-created_at'" ng-click="select(recipient.id)">
<p class="recipientname">{{ recipient.name }}</p>
</div>
</div>
//xxController.js
$scope.select = function() {
Comment.get()
.success(function(data) {
$scope.comments = data;
$scope.loading = false;
});
}
//xxService.js
get:function(){
var comments = $http.get('api/comments');
return comments;
},
//xxController.php [laravel]
public function index()
{
$comments = DB::table('c')
->join('u', 'c.id', '=', 'u.id')
->select('u.id', 'u.name', 'c.comments', 'c.created_at')
->where('u.id','=', Auth::user()->id)
->orWhere('u.id','=', **39 => this part has to be from ng-click value**)
->orderBy('c.created_at','asc')
->get();
return Response::json($comments);
}
You have passing the recipient.id parameter in your ng-click function but you did't retrieve the parameter in your js function
you need to retrieve the parameter
$scope.select = function(**id**) {
var selectedId=id;//you can check here
Comment.get()
.success(function(data) {
$scope.comments = data;
$scope.loading = false;
});
}
For passing data with $http.get method, there is second argument for [config] you can use that.
see: https://docs.angularjs.org/api/ng/service/$http#get for more reference about get method

How to avoid data mix between $scope variables in ng-repeat when it is broadcasted in other controller?

I have two controllers. In one controller I am storing the data in scope variable for different categories and for different weeks and days. Here is the function for the same:
$scope.fetchWeekList = function(type) {
$scope.loading = true;
var paramtype = (type == 'mo')?'Mobiles':((type == 'ta')?'Tablets':((type == 'la')?'Laptops':'TVs'));
var weekListUrl = url + "/" + paramtype;
var request = $http({
method: "GET",
url: weekListUrl,
headers: { 'Accept' :'application/json','Content-Type' :'application/json', 'Accept-Language': 'en'}
});
request.success(
function(data) {
$scope.weekList = data.object;
$scope.loading = false;
});
request.error(
function(data, status) {
console.log(status);
$scope.weekList = data || "Request failed";
$scope.loading = false;
});
};
Please pat attention that I am fetching the data for the week lists for all the categories with this single function.
Then I am using this:
$scope.$on('fetchSaleDetails', function(event,type) {
$scope.fetchWeekList(type);
}
Then I am broadcasting it in the other controller like this:
$rootScope.$broadcast('fecthSaleDetails','mo');
$rootScope.$broadcast('fecthSaleDetails','ta');
$rootScope.$broadcast('fecthSaleDetails','la');
But when I switch the company the weeks of one category appears in the other and when I click again on the company the data changes. This is the function to update company.
$scope.updateCom = function(corresCom) {
$("html, body").animate({scrollTop: 0 }, "slow");
$rootScope.$broadcast('updateComDetail',corresCom);
$rootScope.$emit('fetchSaleDetails','mo');
$rootScope.$broadcast('fecthSaleDetails','mo');
$rootScope.$broadcast('fecthSaleDetails','ta');
$rootScope.$broadcast('fecthSaleDetails','la');
$scope.selectedCom = corresCom;
};
I would be grateful if someone can tell me the issue here. I have tried my best but no luck.
Thanks.

Categories

Resources