简体   繁体   中英

How to hide rows using ng-repeat from Angularjs table

I'm new to angular, and also to stackoverflow, it's my first question here.

So I'm building an angular table, so far so god, I've done Add data, and Delete data, the tricky part is to Edit data in table.
I've created two input text and bind them with ng-model and data from table,
but when I click the edit button it grabes all data from table, but I want to edit only the one where i click edit,
I'm guessing i should hide the other rows or should I make the ng-model not to grab all data. I've try some things they didnt work.I tryed with google and stackoverfllow i found some examples, i applyed that code and edited to my app but it didnt work.

Thank you.

<<!DOCTYPE html>
<html ng-app="incercari">
<head>
    <title>incercari</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>



<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>




<body ng-controller="firstCtrl">

<input type="text" ng-model="search" placeholder="search...">
<table class="table table-bordered">
<thead>
    <tr>
        <th>City</th>
        <th>Sport</th>
        <th>Remove<th>

    </tr>
</thead>
<tbody>
    <tr ng-repeat="(productIndex, ppl) in cities | filter:search">

        <td>{{ppl.name}}</td>
        <td>{{ppl.sport}}</td>
        <td><input type="button" class="btn btn-danger" value="Delete" ng-click="removeRow(productIndex)"/></td>
        <td><a href="#" ng-click="edit(ppl)">Edit</a>
        <input type="text" id="name"  ng-model="current.name" value="{{current.name}}">
        <input type="text" id="sport"  ng-model="current.sport" value="{{current.sport}}">
        <button ng-click="save(current)">Save</button></td>
    </tr>
</tbody>
</table>
 <form ng-submit="addData(cities)">


     Add data<br />                           
   <input type="text"  placeholder="City" ng-model="cities.name" required >   


 <input type="text"  placeholder="Sport" ng-model="cities.sport" >   



  <input type="submit" value="Submit" class="btn btn-primary">    


<script src="app.js"></script>
</body>
</html>>

Here is the app var app = angular .module("incercari", []) .controller("firstCtrl", function($scope){

               $scope.cities = [

                 {'name': 'New York', 'sport': 'basketball'},
                 {'name': 'Bucharest', 'sport': 'soccer'},
                 {'name': 'Sydney', 'sport': 'rugby'},
                 {'name': 'Toronto', 'sport': 'hockey'}

               ];


               $scope.addData = function(cities) {
                $scope.cities.push({'name': cities.name,
                                    'sport': cities.sport,
                                });
                $scope.cities.name = "";
                $scope.cities.sport= "";
               };

                $scope.removeRow = function (productIndex) {
                $scope.cities.splice(productIndex, 1);
  };

                $scope.edit = function(ppl) {

                $scope.current = ppl;
                };

               $scope.current = {};


               $scope.save = function(ppl) {

                $scope.current = {};
               };


               $scope.selectedIndex = '';


                 });

Here is the link to my app: http://plnkr.co/edit/vsB5lRB15RiQn6wH2kHp?p=preview

Click edit and see what happens.

Check the updated code.

Your data is in ng-repeat, to make your ng-model dynamic for each item you need to create dynamic ng-model by using it's $index.

current[productIndex].name
current[productIndex].sport

To identify which edit item is clicked, pass the current clicked item with it's index to assign them edit data.

ng-click="edit(ppl, productIndex)"

Finally, assign the data based on the clicked item.

$scope.edit = function(ppl, index) {
      $scope.currentEdit = index;
      $scope.current = {};
      $scope.current[index] = ppl;
};

For more details, see this working snippet.

 var app = angular .module("incercari", []) .controller("firstCtrl", function($scope){ $scope.cities = [ {'name': 'New York', 'sport': 'basketball'}, {'name': 'Bucharest', 'sport': 'soccer'}, {'name': 'Sydney', 'sport': 'rugby'}, {'name': 'Toronto', 'sport': 'hockey'} ]; $scope.addData = function(cities) { $scope.cities.push({'name': cities.name, 'sport': cities.sport, }); $scope.cities.name = ""; $scope.cities.sport= ""; }; $scope.removeRow = function (productIndex) { $scope.cities.splice(productIndex, 1); }; $scope.edit = function(ppl, index) { $scope.currentEdit = index; $scope.current = {}; $scope.current[index] = ppl; }; $scope.current = {}; $scope.save = function(ppl) { $scope.current = {}; }; $scope.selectedIndex = ''; }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!DOCTYPE html> <html ng-app="incercari"> <head> <title>incercari</title> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script> <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <!-- Optional theme --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"> <!-- Latest compiled and minified JavaScript --> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> </head> <body ng-controller="firstCtrl"> <input type="text" ng-model="search" placeholder="search..."> <table class="table table-bordered"> <thead> <tr> <th>City</th> <th>Sport</th> <th>Remove<th> </tr> </thead> <tbody> <tr ng-repeat="(productIndex, ppl) in cities | filter:search "> <td>{{ppl.name}}</td> <td>{{ppl.sport}}</td> <td><input type="button" class="btn btn-danger" value="Delete" ng-click="removeRow(productIndex)"/></td> <td><a href="#" ng-click="edit(ppl, productIndex)">Edit</a> <div ng-if="currentEdit == productIndex"> <input type="text" id="name" ng-model="current[productIndex].name" value="{{current_productIndex.name}}"> <input type="text" id="sport" ng-model="current[productIndex].sport" value="{{current_productIndex.sport}}"> <button ng-click="save(current)">Save</button> </div> </td> </tr> </tbody> </table> <form ng-submit="addData(cities)"> Add data<br /> <input type="text" placeholder="City" ng-model="cities.name" required > <input type="text" placeholder="Sport" ng-model="cities.sport" > <input type="submit" value="Submit" class="btn btn-primary"> <script src="script.js"></script> </body> </html> 

With the way you have it now, your ng-model for all of the text fields is always getting the same data. To get around this you can make current an array and pass $index in your edit function so it only get's the data from that ppl, like so:

html:

<!-- Pass ppl and $index to your edit function -->
<td><a href="#" ng-click="edit(ppl, $index)">Edit</a>
<!-- ng-if to hide the inputs and button unless edit is clicked. -->
<div ng-if="currentEdit == $index">
    <!-- call current[$index] instead of current -->
    <input type="text" id="name"  ng-model="current[$index].name" value="{{current[$index].name}}">
    <input type="text" id="sport"  ng-model="current[$index].sport" value="{{current[$index].sport}}">
<div>

and in your controller:

//Accept ppl and index in your edit function
$scope.edit = function(ppl, index) {
  $scope.currentEdit = index;
  //reset current so when you press edit all other inputs will become blank.
  $scope.current = {};
  //set current at index to ppl
  $scope.current[index] = ppl;
};

Here is an updated plunker:

http://plnkr.co/edit/0yzkjmLtpHI87V8BApaf?p=preview

Edit: I misunderstood the problem.

Edit2: Went ahead and added a div with ng-if so the inputs and button are only shown if that is the current edit.

You can add the edit fields and button in a span and only show in case this is the selected edit

    <span ng-if="ppl==current">
    <input type="text" id="name"  ng-model="current.name" value="{{current.name}}">
    <input type="text" id="sport"  ng-model="current.sport" value="{{current.sport}}">
    <button ng-click="save(current)">Save</button>
    </span>

Note: if you want to display all fields with correct data , you can just replace the current.name with ppl.name .. etc and it will reflect the "current" when editing it but it will be confusing i think.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM