0

When I click a specific element on the table (code with $scope below), I want to retrieve the information of that element (say "apple" in the example code).

Currently, I'm having trouble search up an element in the $scope.studentsObj and attach an onClick to all of them (this includes the one being added by the $scope.studentsObj.push function.)

Also, right now when I use $scope.studentsObj.push, it always goes to the next row, how do I push element to specific key value? For example, when I add "first: apple, last: juice" , "first: apple, last: pie" row, it should be replaced by "first: apple, last: juice".

<html>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<style>
  table, th, td {
    border: 1px solid black;
  }
</style>
<body>    
  <div ng-app="myApp" ng-controller="myController">
  <h1>Table of Names/h1>
  <table> 
    <th> <h2>First Name</h2></th> <th> <h2>Last Name</h2></th>
    <tr ng-repeat="student in studentsObj"> 
      <td ng-repeat="(key, value) in student"> {{value}} </td>
    </tr> 
  </table>

  <script>
    var app = angular.module('myApp', []);
    app.controller('myController', function($scope) {
      $scope.studentsObj = 
       [ {first: "apple", last: "pie"},
         {first: "dance", last: "marathon"},
         {first: "tom", last: "boy"}],
         $scope.studentsObj.push({first:"karen"}),
         $scope.studentsObj.push({first:,last:"smith"});
    });
  </script>
</body>
</html>
1
  • You can just set somewhere ng-click="addStudent() and add an addStudent function to your $scope object in the controller Commented May 1, 2017 at 14:45

1 Answer 1

2

Question #1

Currently, I'm having trouble search up an element in the $scope.studentsObj and attach an onClick to all of them(this includes the one being added by the $scope.studentsObj.push function.)

Create function in your scope that will have parameter that you will pass from the cell.

$scope.cellClicked = (value) => {
  alert(value)
}

Then add ng-click attribute to the cell, calling the function with parameter you want, in your case student or value:

<td ng-repeat="(key, value) in student" ng-click='cellClicked(value)'> {{value}} </td>

Question #2

Also, right now when I use $scope.studentsObj.push, it always goes to the next row, how do I push element to specific key value? For example, when I add "first: apple, last: juice" , "first: apple, last: pie" row, it should be replaced by "first: apple, last: juice".

There is many ways how to achieve this. I will show you not-mutating way. It means not modifying the existing object in memory, but rathe creating new object of new version.

This has often many advantages. It is I think easier to reason and also implement as the code is simpler. But especially in Angular it make sure that Angular will see the new version, because the rendering engine detects if object is the same as previous it doesn't refresh the rendering. This way there is always new object.

You can do it by simple function with map over the array:

var updateStudentByFirst = (students, name, newStudent) =>
  students.map(student => 
    student.first == name ? 
    Object.assign({}, student, newStudent) : 
    student)

This function returns new version of students array where student that matches first value with name parameter will have new fields from newStudent. Other students will by just copied over intact.

You can use it then in your $scope by storing result of it to the same scope variable:

$scope.studentsObj = updateStudentByFirst(
  $scope.studentsObj, "dance", {last: "competition"})

See it all in action:

var updateStudentByFirst = (students, name, newStudent) =>
  students.map(student => 
    student.first == name ? 
    Object.assign({}, student, newStudent) : 
    student)

var app = angular.module('myApp', []);
app.controller('myController', function($scope) {
  $scope.cellClicked = (value) => {
    alert(value)
    // update students to new studence where "dance" has surname "competition"
    $scope.studentsObj = updateStudentByFirst($scope.studentsObj, "dance", {last: "competition"})
  }

  $scope.studentsObj = [{
      first: "apple",
      last: "pie"
    },
    {
      first: "dance",
      last: "marathon"
    },
    {
      first: "tom",
      last: "boy"
    }
  ]
});
table,
th,
td {
  border: 1px solid black;
}
<div ng-app="myApp" ng-controller="myController">
  <h1>Table of Names</h1>
  <table>
    <tr>
      <th>
        <h2>First Name</h2>
      </th>
      <th>
        <h2>Last Name</h2>
      </th>
    </tr>
    <tr ng-repeat="student in studentsObj">
      <td ng-repeat="(key, value) in student" ng-click='cellClicked(value)'> {{value}} </td>
    </tr>
  </table>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>

Sign up to request clarification or add additional context in comments.

4 Comments

but how do I push an element to the table at a specific index? like say I want to push to dance with last name value competition
Can you explain bit more what you want to actually achieve by doing that? Not quite sure why not just to put the "competition" directly in the original list?
Yes, when I put {dance, competition}. It should replace marathon in the Last Name column. The entire row of dance marathon will become dance |competition
Let me know if you are still unsure about my goal

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.