I have been looking for an example on how to implement a button to remove a selected row, but I couldn't find anything useful so far.
Can anyone please give me a hint? Here is the plunker example.
The function I implement acts weird, as it removes other rows.
Thank you.
That is not a proper way to delete any row
Try like this:
$scope.removeRow = function() {
var index = this.row.rowIndex;
$scope.gridOptions.selectItem(index, false);
$scope.myData.splice(index, 1);
};
PLUNKER --> Its working and tested
thanks for the hint but
I tried the snippet and it doesn't work
so I changed it in
var removeTemplate = '<input type="button" value="remove" ng-click="removeRow()" />';
$scope.removeRow = function() {;
var index = this.row.rowIndex;
alert(index);
$scope.gridOptions.selectItem(index, false);
$scope.items.splice(index, 1);
};
and it works like a charme :)
Hope this help.
This might help you, and also this is for deleting multiple rows in the grid.
$scope.mySelections = [];
$scope.gridOptions = {
data :'gridData',
selectedItems : $scope.mySelections,
showSelectionCheckbox : true
}
$scope.deleteSelected = function() {
angular.forEach($scope.mySelections, function(rowItem) {
$scope.gridData.splice($scope.gridData.indexOf(rowItem),1);
});
}
mySelections is the array which has selected rows
Previous answer to this question won't work once the array has been sorted because the row.index changes based on the way the array has been sorted but the original data in the array remains in it's original index. We must find the correct index in the data array in order to remove the correct row. The row contains a reference to the original data in row.entity so we can use indexOf to find the correct index.
$scope.actionTemplate = '<input type="button" value="Delete" ng-click="delete($event);" />';
$scope.delete = function($event) {
$event.stopPropagation(); //keep the row from being selected
$scope.data.selectAll(false); //remove all selections: necessary for issues with the selection array
var index = $scope.data.indexOf(this.row.entity); //get the correct index to splice
$scope.metrics.splice(index, 1); //remove the element
};
Edit: The original solution may have worked at the time but ng-grid has since been updated and it no longer works.
It might help you
<!doctype html>
<html ng-app="deleteApp">
<head>
<title>Example - www.code-sample.com</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.1/angular.min.js"></script>
<script>
angular.module('deleteApp', [])
.controller('deleteController', ['$scope', function ($scope) {
$scope.Rows = [
{ row: 'RowCount1'},
{ row: 'RowCount2'},
{ row: 'RowCount3'},
{ row: 'RowCount4'},
{ row: 'RowCount5'}];
$scope.delete = function(index){
$scope.Rows.splice(index, 1);
}
}]);
</script>
</head>
<body ng-controller="deleteController">
<div ng-repeat="ro in Rows">
<div>{{$index + 1}} : {{ro.row}} <input type="button" value="delete" ng-click="delete($index)" /></div>
</div>
</body>
</html>
This works:
showSelectionCheckbox : true ->it adds checkbox to grid
and
$scope.delItem = function() -> it works for both multiple rows or single row selection
$scope.mySelections = [];
$scope.gridOptions = {
data :'data',
selectedItems : $scope.mySelections,
showSelectionCheckbox : true
}
$scope.delItem = function() {
for (var i = 0; i < $scope.mySelections.length; i++) {
var index = $scope.data.indexOf($scope.mySelections[i]);
if (index != -1) {
$scope.data.splice(index, 1);
}
}
}
Related
I have two select drop down list and one text box.
There is option to clone each row using ng-repeat.
When selecting dropdown value i will get value from database. So i need to bind that value in textbox.
Controller:
$scope.major_change = function(value, index){
$scope.major_id = value;
};
$scope.minor_change = function(value, index){
$scope.minor_id = value;
$scope.active = 'active';
var temp = surveyService.getDistList($scope.major_id, $scope.minor_id);
temp.then(function (msg) {
alert(msg.data[0].gi_code);
$scope.gi_code[index] = msg.data[0].gi_code;
}, function () {
$scope.Error = 'Error in adding record';
});
};
Html Screen
You are binding the wrong value to ng-model. This was the reason two way binding was not working.
$scope.minor_change = function(value, index){
$scope.minor_id = value;
/*$scope.dist.gi_code[index] = value;*/
$scope.dist_list[index].gi_code=value;
}
Working Plunker: https://plnkr.co/edit/dRr90YtjtSRhHUZKisMQ?p=preview
I don't know what actually your html code look like but may be this help you as desired.You can use two-way data binding as :
HTML Code :
<tr>
<td><select class="select1"></option></option></td>
<td><select class="select1"></option></option></td>
<td><input type="text" ng-model="value" ></td>
Javascript Code :
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.value= $('.select1').val();
});
</script>
I have to access some objects inside an array:
.success(function(data) {
$scope.activities = data.result[0].attributes
});
And I can access this particular index, as expected, inside my view with
<div ng-repeat="x in activities">
<p>{{x.name}}: {{x.value}}</p>
</div>
Now obviously, this only returns the first object in the array, at index 0. (Right?). So I figure I have to somehow loop the function..
.success(function(data) {
for(var i = 0; i < data.result.length; i++) {
$scope.activities = data.result[i].attributes;
}
});
As far as I can tell, the actual for loop is working.. but I need help in the next step exposing this to my view.
Here is my plunker: https://plnkr.co/edit/2ZukY3Oq8vYvghfCruHx?p=preview
(although the data is not available, I have added what the response looks like in the comments)
Well, since the JSON data you pasted in plnkr is invalid, I don't know what attributes means, if it's just an object or it's an array of objects, anyway I made it as a single object.
EDIT
Since now I know attributes is an Array of objects, you can achieve what you want using special repeats.
Here's a snippet working:
(function() {
"use strict";
angular.module('app', [])
.controller('mainCtrl', function($scope) {
$scope.getLeadActivities = function() {
var url = 'xxxxxxxx.mktorest.com';
var endpoint = '/rest/v1/activities.json';
var activityTypeIds = '46';
var access_token = $scope.access_token;
var leadIds = $scope.leadId;
var nextPageToken = $scope.pagingToken;
// This is your data from API
var data = {
"requestId":"14213#155c8de2578",
"success":true,
"nextPageToken":"EOXAPD2V5UOJ5B3S5GGP7NUCX6UI6BFXCWHPJXF245PN2QTGMF3Q====",
"moreResult":false,
"result":[
{
"id":75843491,
"leadId":5334578,
"activityDate":"2016-07-06T06:45:11Z",
"activityTypeId":46,
"primaryAttributeValue":"Web",
"attributes":[
{
"name":"myDataName",
"value":"myDataValue"
}
]
},
{
"id":75843491,
"leadId":5334578,
"activityDate":"2016-07-06T06:45:11Z",
"activityTypeId":46,
"primaryAttributeValue":"Web",
"attributes":[
{
"name":"myDataName2",
"value":"myDataValue2"
}
]
},
{
"id":75843491,
"leadId":5334578,
"activityDate":"2016-07-06T06:45:11Z",
"activityTypeId":46,
"primaryAttributeValue":"Web",
"attributes":[
{
"name":"myDataName3",
"value":"myDataValue3"
}
]
}
]
};
// You'll put it inside the THEN method of your $http.get
$scope.activities = data.result;
}
});
})();
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
</head>
<body ng-controller="mainCtrl">
<button ng-click="getLeadActivities()">Get Lead Activities</button>
<div ng-repeat-start="activity in activities"></div>
<ul ng-repeat-end ng-repeat="attr in activity.attributes">
<li ng-bind="attr.name + ': ' + attr.value"></li>
</ul>
</body>
</html>
As per my understanding of your issue, you can solve it by using two ng-repeat clauses.
Your controller code,
.success(function(data) {
$scope.ativitiesArray = data.result;
});
Your html code,
<div ng-repeat="activities in activitiesArray track by $index">
<div ng-repeat="x in activities.attributes track by $index">
<p>{{x.name}}: {{x.value}}</p>
</div>
</div>
I've added track by $index phrase to ng-repeat as it will increase performance. Also, as per suggestions in the comments, please avoid using .success(). It is recommended to use .then().
Hope this solves the issue.
I am using this Plunker as a reference. I want to create a similar one however, the change is I want to add a button and on click each entry should be added in the list. I have created this Plunker. However, I need to add one by one item on click. How can I achieve that? Somehow, I am doing something wrong in this code.
$scope.addRow = function() {
$scope.source.push($scope.counter);
$scope.counter++;
}
Any help would be appreciated.
In order to do what you want, you need to call $scope.source.pageSize(page); after changing it, and then $scope.source.refresh() to apply this change to the source.
angular.module("app", ["kendo.directives"]).controller("MyCtrl", function ($scope) {
var page =1;
$scope.source = new kendo.data.DataSource({
transport: {
read: {
url: "http://demos.telerik.com/kendo-ui/service/products",
dataType: "jsonp"
}
},
pageSize: page
});
$scope.add= function(){
page++;
$scope.source.pageSize(page);
$scope.source.refresh();
}
});
here's working plnkr
You are just pushing the counter into the array, you should push the text instead.
angular.module("app", []).controller("MyCtrl", function ($scope) {
$scope.source = [];
$scope.addRow = function(text) {
$scope.source.push(text);
}
});
and in your view:
<div ng-app="app" ng-controller="MyCtrl">
<input type="text" ng-model="some_text"/>
<input type="submit" value="Add" ng-click="addRow(some_text)"/>
</div>
Take a look at this Plunker: http://plnkr.co/edit/m1gkM4Yp9xzAa09NDACK?p=preview
I am trying to remove elements from the array $scope.items so that items are removed in the view ng-repeat="item in items"
Just for demonstrative purposes here is some code:
for(i=0;i<$scope.items.length;i++){
if($scope.items[i].name == 'ted'){
$scope.items.shift();
}
}
I want to remove the 1st element from the view if there is the name ted right? It works fine, but the view reloads all the elements. Because all the array keys have shifted. This is creating unnecessary lag in the mobile app I am creating..
Anyone have an solutions to this problem?
There is no rocket science in deleting items from array. To delete items from any array you need to use splice: $scope.items.splice(index, 1);. Here is an example:
HTML
<!DOCTYPE html>
<html data-ng-app="demo">
<head>
<script data-require="angular.js#1.1.5" data-semver="1.1.5" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div data-ng-controller="DemoController">
<ul>
<li data-ng-repeat="item in items">
{{item}}
<button data-ng-click="removeItem($index)">Remove</button>
</li>
</ul>
<input data-ng-model="newItem"><button data-ng-click="addItem(newItem)">Add</button>
</div>
</body>
</html>
JavaScript
"use strict";
var demo = angular.module("demo", []);
function DemoController($scope){
$scope.items = [
"potatoes",
"tomatoes",
"flour",
"sugar",
"salt"
];
$scope.addItem = function(item){
$scope.items.push(item);
$scope.newItem = null;
}
$scope.removeItem = function(index){
$scope.items.splice(index, 1);
}
}
For anyone returning to this question. The correct "Angular Way" to remove items from an array is with $filter. Just inject $filter into your controller and do the following:
$scope.items = $filter('filter')($scope.items, {name: '!ted'})
You don't need to load any additional libraries or resort to Javascript primitives.
You can use plain javascript - Array.prototype.filter()
$scope.items = $scope.items.filter(function(item) {
return item.name !== 'ted';
});
Because when you do shift() on an array, it changes the length of the array. So the for loop will be messed up. You can loop through from end to front to avoid this problem.
Btw, I assume you try to remove the element at the position i rather than the first element of the array. ($scope.items.shift(); in your code will remove the first element of the array)
for(var i = $scope.items.length - 1; i >= 0; i--){
if($scope.items[i].name == 'ted'){
$scope.items.splice(i,1);
}
}
Here is filter with Underscore library might help you, we remove item with name "ted"
$scope.items = _.filter($scope.items, function(item) {
return !(item.name == 'ted');
});
I liked the solution provided by #madhead
However the problem I had is that it wouldn't work for a sorted list so instead of passing the index to the delete function I passed the item and then got the index via indexof
e.g.:
var index = $scope.items.indexOf(item);
$scope.items.splice(index, 1);
An updated version of madheads example is below:
link to example
HTML
<!DOCTYPE html>
<html data-ng-app="demo">
<head>
<script data-require="angular.js#1.1.5" data-semver="1.1.5" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div data-ng-controller="DemoController">
<ul>
<li data-ng-repeat="item in items|orderBy:'toString()'">
{{item}}
<button data-ng-click="removeItem(item)">Remove</button>
</li>
</ul>
<input data-ng-model="newItem"><button data-ng-click="addItem(newItem)">Add</button>
</div>
</body>
</html>
JavaScript
"use strict";
var demo = angular.module("demo", []);
function DemoController($scope){
$scope.items = [
"potatoes",
"tomatoes",
"flour",
"sugar",
"salt"
];
$scope.addItem = function(item){
$scope.items.push(item);
$scope.newItem = null;
}
$scope.removeItem = function(item){
var index = $scope.items.indexOf(item);
$scope.items.splice(index, 1);
}
}
Just a slight expansion on the 'angular' solution. I wanted to exclude an item based on it's numeric id, so the ! approach doesn't work.
The more general solution which should work for { name: 'ted' } or { id: 42 } is:
mycollection = $filter('filter')(myCollection, { id: theId }, function (obj, test) {
return obj !== test; });
My solution to this (which hasn't caused any performance issues):
Extend the array object with a method remove (i'm sure you will need it more than just one time):
Array.prototype.remove = function(from, to) {
var rest = this.slice((to || from) + 1 || this.length);
this.length = from < 0 ? this.length + from : from;
return this.push.apply(this, rest);
};
I'm using it in all of my projects and credits go to John Resig John Resig's Site
Using forEach and a basic check:
$scope.items.forEach(function(element, index, array){
if(element.name === 'ted'){
$scope.items.remove(index);
}
});
At the end the $digest will be fired in angularjs and my UI is updated immediately without any recognizable lag.
If you have any function associated to list ,when you make the splice function, the association is deleted too. My solution:
$scope.remove = function() {
var oldList = $scope.items;
$scope.items = [];
angular.forEach(oldList, function(x) {
if (! x.done) $scope.items.push( { [ DATA OF EACH ITEM USING oldList(x) ] });
});
};
The list param is named items.
The param x.done indicate if the item will be deleted. Hope help you. Greetings.
Using the indexOf function was not cutting it on my collection of REST resources.
I had to create a function that retrieves the array index of a resource sitting in a collection of resources:
factory.getResourceIndex = function(resources, resource) {
var index = -1;
for (var i = 0; i < resources.length; i++) {
if (resources[i].id == resource.id) {
index = i;
}
}
return index;
}
$scope.unassignedTeams.splice(CommonService.getResourceIndex($scope.unassignedTeams, data), 1);
My solution was quite straight forward
app.controller('TaskController', function($scope) {
$scope.items = tasks;
$scope.addTask = function(task) {
task.created = Date.now();
$scope.items.push(task);
console.log($scope.items);
};
$scope.removeItem = function(item) {
// item is the index value which is obtained using $index in ng-repeat
$scope.items.splice(item, 1);
}
});
My items have unique id's. I am deleting one by filtering the model with angulars $filter service:
var myModel = [{id:12345, ...},{},{},...,{}];
...
// working within the item
function doSthWithItem(item){
...
myModel = $filter('filter')(myModel, function(value, index)
{return value.id !== item.id;}
);
}
As id you could also use the $$hashKey property of your model items: $$hashKey:"object:91"
I have a given array of objects, whose objects I would like to add to a 'selected'-list depending on related checkboxes. How could I set them up without having to set up the controller to much.
Here is the fiddle which works fine, when using radio-boxes instead:
http://jsfiddle.net/JohannesJo/6ru2R/
JavaScript:
app = angular.module('app',[]);
app.controller('controller', function($scope){
$scope.aData = [
{i:1},
{i:2}
];
$scope.aSelected = [];
});
html:
<body ng-app="app">
<div ng-controller='controller'>
<input type = "checkbox" ng-model = "aSelected" value = "{{aData[0]}}">
<input type = "checkbox" ng-model = "aSelected" value = "{{aData[1]}}">
<div>test: {{oSelected}}</div>
</div>
</body>
One option is to watch for changes on the oSelected Array and create the list of related objects base on it.
$scope.$watch(function () {
return $scope.oSelected;
}, function (value) {
$scope.selectedItems = [];
angular.forEach($scope.oSelected, function (v, k) {
v && $scope.selectedItems.push($scope.aData[k]);
});
}, true);
jsfiddle: http://jsfiddle.net/bmleite/zea7g/2/