Update ng-repeat values in angular js - javascript

I am listing some elements and each element has a click event and as a parameter the same element.
<a class="item item-avatar item-lista" ng-click="verView({{$index}},{{view}})">
Function verView :
$scope.verView = function(index,view){
sessionService.set("view_leido",view);
$location.path("/event/view/"+index);
}
Function darLike:
$scope.darLike = function(view_id, index){
console.log(UrlService.url+'likeView/'+sessionService.get("user_id")+'/'+sessionService.get("hash")+"/"+view_id+"/");
$http({method: 'GET', url: UrlService.url+'likeView/'+sessionService.get("user_id")+'/'+sessionService.get("hash")+"/"+view_id+"/"})
.success(function(data){
if(data.status == 1){
angular.copy(data.view.TableView, $scope.views[index]);
}
})
.error(function(){
})
.finally(function(){
});
}
These elements can be given LIKE this creates a record in my database and return the number of Likes having my element, so I update my object in the list. But while sending object parameter arrives outdated, for example:
If you would LIKE to one that has 0 likes, stay at 1 like, when you click and view detail I get 0 likes yet.

Related

Make each new item created in a list (each one with a different ID) execute a certain function automatically

I explain myself: I have a Sharepoint custom list and I'm using AngularJS to call this list. With the data I obtain from the list, I'm making a "single bar chart" for each item in this list. I'm using jquery.lineProgressbar.js to make the charts.
I'm doing the table with ng-repeat. And I need to provide a different ID name to each "chart div", otherwise the jquery.lineProgressbar.js won't work. Here's my HTML:
<table>
<tr>
<td>Name</td>
<td>Productivity percentage</td>
</tr>
<tr ng-repeat="item in items">
<td>{{item.Name}}</td>
<td>
<!-- The "ng-attr-id" provides the div a different ID depending the name they introduce. i.e.: "chart-Person1" -->
<div ng-attr-id="{{'chart-' + item.Name}}" data-percentage="{{item.Productivity_x0020_percentage}}"></div>
</td>
</tr>
</table>
and my main problem, the SCRIPT:
<script>
//I need to call each chart, one by one like this:
chartFunction('chart-Person1');
chartFunction('chart-Person2');
chartFunction('chart-Person3');
chartFunction('chart-Person4');
//and I need to make this automatically,
//because people will submit new items whenever they want,
//and I can't be updating the script each time someone uploads something.
function chartFunction(elementID) {
var dataPercentage = $("#" + elementID).data('percentage');
//this calls the chart code
$("#" + elementID).LineProgressbar({
//it says that the div selected will have a "percentage" equals to the percentage they wrote in the list.
percentage: dataPercentage
});
}
</script>
I have a Plunker. It is a little different because it has a function which runs the charts only when they're in the viewport, and it doesn't use AngularJS. But it's only so you can see how it works: my Plunker
So, as I said in my code, I need to call each new element added to the sharepoint list, but I can't be creating new calls in my code each time someone uploads an item. Thanks in advance for your help.
I've found the solution to this.
I needed to do it directly in the call of the list (in the Angular code).
<script>
var myApp = angular
.module('myApp', [])
.controller('myController', function ($scope, $http) {
//first I call the Sharepoint List with AngularJS
$http({
method: 'GET',
url: "SiteURL/_api/web/lists/getByTitle('Employees List')/items?$select=*",
headers: { "Accept": "application/json;odata=verbose" }
}).then(function onSuccess(response) {
//If the call is successful I create an empty Array called "peopleArray"
//Here I will store the names of the divs which will run the chart's code
$scope.items = response.data.d.results;
var theItems = $scope.items,
peopleArray = [];
//I run a loop to go through all the items in the Sharepoint list
//I assign a name for each person in the "peopleArray"
for(var i=0; i<theItems.length; i++) {
var currentItem = theItems[i];
peopleArray.push('chart-' + currentItem.Name);
};
//I run another loop, this one goes through the "peopleArray"
//each item executes the function below with the div name assigned in the previous loop
for(var z=0; z<peopleArray.length; z++) {
chartFunction(peopleArray[z]);
}
//and this is the function to make the charts for each person
function chartFunction(elementID) {
var dataPercentage = $("#" + elementID).data('percentage');
$("#" + elementID).LineProgressbar({
percentage:dataPercentage
});
}
}).catch(function onError(response) {
//In case of Error, it will pop an alert
alert("Error! The charts can't be loaded.");
});
});
</script>

update a element with jquery

Hi i have a id of #item_quantity in a span. once a button is clicked with and id of #update_cart. I want the span to refresh its contents. the target data would have already been updated on the click also that works, but cant seem to get the span to update its data.
i am using the following script to try refresh it:
the link i m targeting was the same page i was on. Once a product is added to the cart, and the page is refreshed, then the list updates, so i thought i could right a scripts that just refreshes that div once something is clicked and all will be done. but it does nothing.
script
$(function() {
$("#update_cart").click(function(evt) {
$("#item_quantity").load("http://apecenergy.co.uk/products.php?p=4")
evt.preventDefault();
})
});
html
<div class="menu_cart_units "><span class="" id="item_quantity">
<cms:number_format quantity decimal_precision='0'/></span>×</div>
<div class="menu_cart_option"><cms:show title /></div>
<div class="menu_cart_subtotal"><span class="" id="item_price"> £<cms:number_format line_total /></span></div>
json
"id": <cms:show id/>,
"quantity": <cms:show quantity/>,
"price": <cms:show price/>,
"line_total": <cms:show line_total/>,
"requires_shipping": <cms:if requires_shipping>true<cms:else/>false</cms:if>,
"name": "<cms:show name/>",
"title": "<cms:addslashes><cms:show title/></cms:addslashes>",
"link": "<cms:show link/>",
"remove_item_link": "<cms:pp_remove_item_link/>",
"line_id": "<cms:show line_id/>",
If i go down the ajax json method, there will be multiple ids which relate to different products, from each id i require quantity, name and line total, to be updated in the div.
what data your request returns??
$("#item_quantity").load("http://apecenergy.co.uk/products.php?p=4")
Assuming the user returns valid JSON i would say a simply "success" with count of items as [{'result':'success'},{'count','<count>'}] if items updated in cart successfully else return something like [{'result':'error'}]! this should be simple as
making ajax call with jquery:
$.ajax({
type:"POST",
url:'Your url that return JSON encoded success with Count of items or Error message',
data:'item id to update here 4 i guess or post Data'
datatype:"JSON",
success:function(data)
{
var tmp=Jquery.parseJSON(data);
switch(data.result)
{
case 'success':
$('#item_quantity').text(data.count); //update the span
break;
case 'error':
alert('something went Wrong');
break;
default:
alert('error');
break;
}
},
error:function()
{
alert('Ajax Request Failed');
}
});
// parse the JSON into a javascript object
var cart_items = JSON.parse(json);
// matches all items in the cart_items list, which have the id == 30
// filter returns an array of matched items
var matching_items = cart_items.filter(
function (item) {
if (item.id == 30) {
return item;
}
});
// since it should only match one item, we take the first element of the array
var item = matching_items[0];
// print out the items quantity
console.log(item.quantity);

Reset ng-model value from controller after ng-change

How can I reset the value of an ng-model in the controller after an ngChange without using a directive
<div ng-repeat="i in items">
<!-- Some DOM comes here -->
<select ng-model="i.avail" ng-change="changeAvail(i.id, i.avail)">
<option value="true">Available</option>
<option value="false">Unavailable</option>
</select>
<!-- More DOM follows -->
</div>
The Javascript in the controller is as follows
$scope.changeAvail = function(itemId, value){
if(confirm("You cannot undo this action")){
//Send an ajax request to backend for an irreversible action
}
else{
//Restore input to initial value;
}
}
I wouldn't want to implement a directive just for this single occurence
You should Ideally store old value of items inside scope & do use them later to revert back to original one.
$scope.loadItem = function(){
$http.get('/api/getitems').then(function(response){
$scope.items = response.data;
$scope.oldCopy = angular.copy($scope.items); //do it where ever you are setting items
});
}
Then do send whole item to ng-change method like ng-change="changeAvail(i)"
$scope.changeAvail = function(item){
if(confirm("You cannot undo this action")){
//save object
$http.post('/api/data/save', item).then(function(){
//alert('Date saved successfully.');
$scope.loadItem(); //to update items from DB, to make sure items would be updated.
})
}
else{
//get current old object based on itemId, & then do revert it.
var oldItem = $filter('filter')($scope.oldCopy, {itemId: item.itemId}, true)
if(oldItem && oldItem.length){
item = oldItem[0]; //filters return array, so take 1st one while replacing it.
}
}
}

Three condition button based on Angular

I am fairly new to Angular an I am feeling lost in all of it's documentation.
Problem:
I am trying to create a button which has three phases:
Add User - Remove Request - Remove User
So if you want to add a user you click on the Add button, which
sends an ajax request to the server and if successful the button
should then turn into a Pending button.
In the pending state if you click on it again, your request will be
deleted and it will again turn back to a Add button.
The third phase is also if the user has accepted your request, you
will be seeing a Remove user button which when you click on
you will again see the Add button which if you click you will get
the Pending button and so forth.
So basically it is a familiar button if you've been using social networks.
When the page is loaded the user will see the users and the buttons for each user based on it's current condition (so the server will be handling this part). From this part Angular should handle the ajax calls and changing of the button per user connection request.
What I need:
I have done the Ajax part for sending the request. However I can't manage to handle the part which Angular needs to change the button to it's new state (for a specific user on the list, meaning the list has more than 1 user which you can send connection add/pending/delete requests.) I have tried different solutions but failed till now.
Some of my messy failure code which I have left unfinished:
Angular Controller:
foundationApp.controller('ConnectionButtonCtrl', function ($scope, $http) {
$scope.addUser = function(id) {
$http({
method : 'GET',
url : '/api/connections/add/'+id,
dataType: "html",
})
.success(function() {
$scope.activeId;
$scope.activeId = id;
$scope.isAdd = function(id){
return $scope.activeId === id;
};
})
};
$scope.removeRequest = function(id) {
$http({
method : 'GET',
url : '/api/connections/removeRequest/'+id,
dataType: "html",
})
.success(function() {
})
};
});
Laravel Blade View:
<span ng-controller="ConnectionButtonCtrl" >
<a class="label radius fi-plus" ng-show="!isRemove(1)" ng-click="addUser(1)"></a>
<a class="label radius fi-clock info" ng-show="isRemove(1)" ng-click="removeRequest(1)"></a>
<a class="label radius fi-x alert" ng-show="!isAdd(1)" ng-click="removeUser(1)"></a>
</span>
If I understand correctly, just use $index or user.id. I am assuming your buttons are on the same line as the user. If that's true then you are probably using an ng-repeat.
For example:
<div ng-repeat="user in users">
<a class="label radius fi-plus" ng-show="!isRemove(user.id)" ng-click="addUser(user.id)"></a>
<a class="label radius fi-clock info" ng-show="isRemove(user.id)" ng-click="removeRequest(user.id)"></a>
<a class="label radius fi-x alert" ng-show="!isAdd(user.id)" ng-click="removeUser(user.id)"></a>
<div> some user information {{user.name}} </div>
</div>
Then you can pass the id of the user with your ajax request. You can also use $index (as a parameter in my code instead for the index of the user in the array).
DEMO: http://plnkr.co/edit/hhOdNTV6ogJHhtXcM03a?p=preview
js
var app = angular.module('myApp', []);
app.controller('myController', function ($scope) {
$scope.users = {
user1: {
'status': 'add',
'statusClass': 'positive'
},
user2: {
'status': 'pending',
'statusClass': 'waiting'
},
user3: {
'status': 'remove',
'statusClass': 'negative'
}
};
$scope.handle = function (user) {
if (user.status === 'add') {
alert('send request to the user');
user.status = 'pending';
user.statusClass = 'waiting'
}
else if (user.status === 'pending') {
alert('send request to discard a connection req');
user.status = 'add';
user.statusClass = 'positive'
}
else {
alert('send req for removal');
user.status = 'add';
user.statusClass = 'positive'
}
};
});
app.$inject = ['$scope'];
HTML:
<body ng-app="myApp" ng-controller="myController">
<div ng-repeat="user in users">
User {{$index+1}} - <button ng-click="handle(user)" ng-class="user.statusClass">{{ user.status }}</button>
</div>
</body>
http://plnkr.co/edit/hhOdNTV6ogJHhtXcM03a?p=preview

view not updating in Angular

Problem Question,
I have a delete method on my cart, so when I press on delete button it delete the item of it. But my view is not getting update whereas item is getting successfully deleted.
//Cart controller
(function() {
var cartController = function($scope,cartService,NotificationService) {
getCart();
function getCart() {
cartService.getCart()
.success(function (cart) {
if (cart != null || cart != 'undefined') {
$scope.cartData = cart;
console.log(cart)
}
})
.error(function (status, data) {
console.log(status);
console.log(data);
})
};
$scope.deleteItem = function (productID) {
cartService.deleteCartItem(productID)
.success(function () {
NotificationService.add("success", "Item deleted from the cart", 3000);
getCart();
})
.error(function (status, data) {
console.log(status);
console.log(data);
})
}
cartController.$inject = ['$scope', 'cartService', 'NotificationService'];
angular.module('cartApp').controller('cartController', cartController);
}
}());
//my view
<div class="mainContainer" ng-controller="cartController">
<tr ng-repeat="cart in cartData.carts" >
<td>
<button ng-click="deleteItem(cart.id)" class="btn btn-primary">Delete</button>
</td>
</tr>
</div>
Please guide me what I am doing wrong.
Add $scope.$apply(); after the ajax call.
$scope.cartData = cart;
console.log(cart);
$scope.$apply();
When working with $scope in angular you will run into this issue when you overwrite an object on $scope (as opposed to modifying properties of that object). As previously mentioned $scope.$apply() will force Angular to reevaluate all your bindings and should cause your UI to update. That being said, making a call to your API to get the entire contents of the cart following a delete operation seems very inefficient here. You either want to send back an empty 200 OK and use that as a trigger to know that it is safe to remove the item client side using splice. The other option would be to send the new cart contents as the body of your 200 OK following a successful delete and at least save yourself an extra round trip.
Add a $scope.$apply() to the end of your call. This will run the angular digest loop and update your view.
Update the $scope.cartData array removing the deleted one on the success method
$scope.cartData.splice($scope.cartData.indexOf(productID), 1 );

Categories

Resources