1

This down is small from my html code.The code add/remove dynamical row.

 <tr class="clone" ng-repeat="dataItem in dataInvoce.Invoicetoitem.items track by $index">
                <td class="number">{{$index + 1}}</td>
    <td><input type="text" id="codeto{{$index}}"  size="11" ng-model="dataItem.item.code" ng-keyup="getCodeItem($index)" class="tagsItem">
                <td><input type="hidden" id="hidden{{$index + 1}}"   ng-model="dataItem.item.itemID" >
                    <input type="text" ng-model="dataItem.item.itemName"  id="item{{$index}}"  class="tagsItem" ng-keyup="getItemInvoice($index)"  name="itemName" required></td>
                <td><input type="text" ng-model="dataItem.item.solid" size="11" id="solid{{$index + 1}}"   ng-disabled="invoice.itemName.$error.required"    required></td>
                <td><input type="text"  ng-model="dataItem.quantity" id="quantity{{$index+1}}" ng-keyup="totals($index+1)" size="10"  ng-disabled="invoice.itemName.$error.required" required></td>
                <td><input type="text" ng-model="dataItem.price"    ng-keyup="totals($index+1)" value="111" id="price{{$index + 1}}"  ng-disabled="invoice.itemName.$error.required" required></td>
    <td><input type="text" ng-model="dataItem.discount"  id="discount{{$index+1}}" ng-keyup="totals($index+1)" size="11" ng-disabled="invoice.itemName.$error.required" required></td>
                <td>{{dataItem.quantity * dataItem.price * (1 - dataItem.discount / 100) | number:2}}</td>
                <td><a class="btn btn-default" ng-click="removeItem ($index)">-</a></td>

            </tr>

This is my funciton for remove dynamical row.When click on "removeItem" button removen row, but and removen element from array on my all items. I want to remove dynamicla row, but do not delete element from my array with all items.

$scope.removeItem = function (index)
{
console.log($scope.dataInvoce.Invoicetoitem.items);

$scope.dataInvoce.Invoicetoitem.items.splice (index, 1);

console.log($scope.dataInvoce.Invoicetoitem.items);
$scope.total ($scope.dataInvoce.Invoicetoitem.items);
};

3 Answers3

1

You need to add ngIf directive to the row:

 <tr class="clone" ng-repeat="dataItem in dataInvoce.Invoicetoitem.items track by $index" ng-if="!dataItem.deleted">

And you can pass the object to the removeItem function in the controller:

ng-click="removeItem (dataItem)" <!-- Instead of '$index' -->

And change the controller function:

$scope.removeItem = function (dataItem) {
    console.log($scope.dataInvoce.Invoicetoitem.items);
    dataItem.deleted = true;
    var total = $scope.dataInvoce.Invoicetoitem.items.filter(function(item) { return typeof(item.deleted) === 'undefined' || !item.deleted; });  // get only the undeleted items

    $scope.total (total);
};
Alon Eitan
  • 11,997
  • 8
  • 49
  • 58
  • Hi your script is Perfect work, but have anorther problem: After i click on removeItem (), my result in html code have problem.After Ng-repeat my result are: 1 some text,2 some text ,3 some text.After click on function i deleted result (2) i see: 1 some text, 3 some text. – Стилиян Георгиев Apr 28 '16 at 07:19
  • @СтилиянГеоргиев Hey, in that case, you can remove the `ngIf` and add to the `ngRepeat` a filter that will show only the un-deleted items: `ng-repeat="....... | filter: { 'deleted': '!true'}` **IMPORTANT!!! -** You MUST **NOT** trust `$index` as a reference to an item inside `dataInvoce.Invoicetoitem.items` because it's actually the index of the filtered list. You need to convert functions like `ng-keyup="getItemInvoice($index)"` to `ng-keyup="getItemInvoice(dataItem)"` to avoid unexpected behaviours – Alon Eitan Apr 28 '16 at 10:18
  • Hey this work in half.I click on function ( removeItem ), but no deleted table row in my html. – Стилиян Георгиев Apr 28 '16 at 11:26
  • You mean that after you click on the remove button, you can still see the row in the view? – Alon Eitan Apr 28 '16 at 11:29
  • Yes!Result after ne-repeat are 4 rows, i click on remove button and i see 4-rows again, all everything else works. – Стилиян Георгиев Apr 28 '16 at 11:39
  • $scope.removeItem = function (dataItem) { console.log ($scope.dataInvoce.Invoicetoitem.items); dataItem.deleted = 1; var dataItems = $scope.dataInvoce.Invoicetoitem.items.filter (function ( item) { return !item.deleted; }); // get only the undeleted items console.log ($scope.dataInvoce.Invoicetoitem.items); $scope.total ($scope.dataInvoce.Invoicetoitem.items); }; – Стилиян Георгиев Apr 28 '16 at 11:40
  • And does your `ngRepeat` is `ng-repeat="dataItem in dataInvoce.Invoicetoitem.items track by $index | filter: { 'deleted': '!true'}"`? You may also try to remove ` track by $index` if it doesn't work (Not sure if it will work, but worth a try) – Alon Eitan Apr 28 '16 at 11:44
  • Yes,I remove this track by $index, no work again – Стилиян Георгиев Apr 28 '16 at 11:50
  • Oh, you put `dataItem.deleted = 1;` in your controller, so try replace `filter: { 'deleted': '!true'}` with `filter: { 'deleted': '!1'}` or change your controller from `dataItem.deleted = 1;` to `dataItem.deleted = true;` – Alon Eitan Apr 28 '16 at 11:55
  • 1
    I am very sorry for the stupid mistake, even if I did not see that there really is a difference! Many, many thanks- Now all work perfect ! – Стилиян Георгиев Apr 28 '16 at 11:59
  • That's totally fine. Glad to help out! – Alon Eitan Apr 28 '16 at 12:05
0

I think what you want is a soft delete in angularjs.

you can achieve this by using a Filter on your ng-repeat:

<tr class="clone" ng-repeat="dataItem in dataInvoce.Invoicetoitem.items track by $index | filter: { 'isDeleted': 'false'}">...</tr>

By setting the isDeleted property of dataItem (any rows of dataInvoce.Invoicetoitem.items) to true, the filter will remove all of the rows that contain the property isDeleted : true.

Doing this will have the correct display behaviour while keeping the rows that are removed from display.

reference for ng-repeat filter

Community
  • 1
  • 1
Jun Duan
  • 218
  • 1
  • 9
  • Beware of using `$index` and `filter` - It will get the index of the filtered collection, and not the original index of the item – Alon Eitan Apr 27 '16 at 14:54
0

Use ng-if for better performance. Not a issue of extra watcher.

<tr class="clone" ng-repeat="dataItem in dataInvoce.Invoicetoitem.items track by $index" ng-if="dataItem.isDeleted">

inside controller $scope.removeItem method set dataItem.isDeleted = true; also pass dataItem rather than $index

Ankit Pundhir
  • 1,097
  • 8
  • 13