Avoiding duplicate index in columns in table when using ng-repeat - javascript

Below is my plunker in which I'm tring to display the output types based on different months.I want to save the maximum capacity for each month on click of save button by getting all the values in an array.But when I type in a text box the value gets repeated as the index is repeated column wise.
ng-repeat in table
Below is the code:
JavaScript:
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.outputType=["Coal","ROM","WASTE"];
$scope.months=["JAN","FEB","MARCH","APRIL"];
$scope.values = [];
$scope.save=function(){
alert($scope.values)
}
});
HTML:
<table style="border:1px solid red;">
<thead>
<tr>
<th> </th>
<th ng-repeat="i in months"><b>{{i}}</b></th>
</tr>
</thead>
<tbody ng-repeat="item in outputType">
<tr>
<td>{{item}} </td>
<td ng-repeat="i in months">
<input type="text" ng-model="values[$index]"
placeholder="Max.Capacity">
</td>
</tr>
</tbody>
</table>

Check that http://plnkr.co/edit/4DUDIBoTOCI4J89FiQeM?p=preview
JS
$scope.values = {};
HTML
<input type="text" ng-model="values[item][i]" placeholder="Max.Capacity">
or
<input type="text" ng-model="values[i][item]" placeholder="Max.Capacity">

Solution if you want to leave an array.
You need to change your ngModel in input
<input type="text" ng-model="values[$index]" placeholder="Max.Capacity">
to
ng-model="values[$parent.$index][$index]".
Here is an example:
Example

Related

Create a dynamic table in Angular based on the amount of rows chosen in a drop down list

I am trying to learn AngularJS 1.6 and I am trying to populate a table with rows depending on the amount of rows selected in a dropdown list. It could be anywhere from 1 to 12. So far I have the following code.
<body ng-controller="myController">
<div>
<p>Blue Corner Boxer: </p> <input type="text" ng-model="nameBlue">
<br>
<p>Red Corner Boxer: </p> <input type="text" ng-model="nameRed">
<br>
<p>Number of Rounds:</p> <select ng-model="selectedRounds"><option ng-repeat="x in rounds">{{x}}</option></select>
</div>
<div>
<table class="table table-striped">
<thead>
<tr>
<th style="text-align:center">{{nameBlue}}</th>
<th style="text-align:center">Round</th>
<th style="text-align:center">{{nameRed}}</th>
</tr>
</thead>
<tbody class="tablerows">
<tr ng-repeat="x in selectedRounds">
<td>Test</td>
<td>Test</td>
<td>Test</td>
</tr>
</tbody>
</table>
<h2 style="text-align: center">Final Score: </h2> {{scoreBlue1 + ScoreBlue2}}
</div>
</body>
Then in the js file
//Create the module
var myApp = angular.module("myModule", []);
//Create the controller and register the module in one line
myApp.controller("myController", function ($scope) {
$scope.message = "AngularJS tutorial";
$scope.score = [1,2,3,4,5,6,7,8,9,10];
$scope.rounds = [1,2,3,4,5,6,7,8,9,10,11,12];
});
So far the table will add 1 row on selection of anything 1 to 9, but 10 to 12 adds 2 rows. So I think I am wondering how to create an array length of size "selectedrounds" that will repeat rows with the repeater.
Thanks
If you need an array only for iterating and you don't worry about data in it. You can do something like this:
In your controller:
$scope.selectedRounds = 0;
$scope.getRoundsArray(){
return new Array($scope.selectedRounds);
}
We just create an array with needed length and with all elements are 'undefined'. If you create an array with 3 lenght you will get: ['undefined', 'undefined', 'undefined'].
In view:
<tr ng-repeat="x in getRoundsArray() track by $index">
You need this track by $index cause your array contains only 'undefined' values so to prevent angular arguing about duplicate keys we need to use track by.

ng-repeat only repeating once while trying to populate table

I am trying to create a table based on the selection of a drop down list. The user would choose 1 to 12 and that number would be the amount of rows to create in the table. Here is my code so far
<body ng-controller="myController">
<div>
<p>Blue Corner Boxer: </p> <input type="text" ng-model="nameBlue">
<br>
<p>Red Corner Boxer: </p> <input type="text" ng-model="nameRed">
<br>
<p>Number of Rounds:</p> <select ng-model="selectedRounds"><option ng-repeat="x in rounds">{{x}}</option></select>
</div>
<div>
<table class="table table-striped">
<thead>
<tr>
<th style="text-align:center">{{nameBlue}}</th>
<th style="text-align:center">Round</th>
<th style="text-align:center">{{nameRed}}</th>
</tr>
</thead>
<tbody class="tablerows">
<tr ng-repeat="x in getRoundsArray(selectedRounds) track by $index">
<td><select ng-options="x for x in score"></select></td>
<td>Score</td>
<td><select ng-options="x for x in score"></select></td>
</tr>
</tbody>
</table>
var myApp = angular.module("myModule", []);
myApp.controller("myController", function ($scope) {
$scope.message = "AngularJS tutorial";
$scope.score = [1,2,3,4,5,6,7,8,9,10];
$scope.rounds = [1,2,3,4,5,6,7,8,9,10,11,12];
$scope.selectedRounds = 0;
$scope.getRoundsArray = function(rounds){
return new Array(rounds);
}
});
No matter what number I choose in the drop down list it just adds 1 row to the table at a time for each selection I make. Instead I want 6 rows as soon as user selects 6.
You need to re-architect your code slightly.
The repeat needs to be over a scoped variable (tableArray in my example) that changes whenever the dropdown changes.
You also do need the $index in the track for it to work.
Here is a working plunker.
Your function
return new Array(rounds);
has changed to
$scope.tableArray = new Array( $scope.selectedRounds * 1);
$scope.getRoundsArray = function(rounds){
return new Array(rounds);
}
});
this does not do what you think it does. You are calling it as getRoundsArray(6), which creates an array with one entry, which is 6, and not, as you want, an array with six entries.
See, for example, https://www.w3schools.com/js/js_arrays.asp.
Thus, your
<tr ng-repeat="x in getRoundsArray(selectedRounds) track by $index">
repeats for each of the one entries of that array, giving the result that you describe.
(and you don't need that track by)

Angular Editable table not working with ng-repeat

<table class="table table-bordered">
<tbody>
<tr ng-repeat="playerOrTeam in template.editableTable track by $index">
<td style="text-align: center;" ng-repeat="playerOrTeamCat in playerOrTeam track by $index">
<input ng-model="playerOrTeamCat" type="text" class="form-control input-sm">
</td>
</tr>
</tbody>
</table>
template.editableTable is a multi dimensional array just filled with standard variables. when I change one of the values in the input box and then i look at the output of the template.editable table, i don't see the changes. Am I missing something obvious?
EDIT with more details because i'm getting no responses =\
//Template Class
app.factory('Template', function () {
var Template = function () {
/*
* Public Variables
*/
this.editableTable = someMultiDimensionalTable;
}
/*
* Functions
*/
Template.prototype.SeeEditableTableContents = function () {
console.log(this.editableTable);
}
}
//Main Controller
app.controller('MainController', function () {
$scope.template = new Template();
//etc
}
You cannot perform direct in-line modifications within ng-repeat. You can update your array entry using a function.
You'd want something like:
$scope.saveEntry = function (idx) {
console.log("Saving entry");
$scope.template.editableTable[idx] = angular.copy($scope.model.selected);
$scope.reset();
};
See JSFiddle for sample.
okay i actually got it to work so that i CAN make direct in-line modifications with ng-repeat by making my multidimensional table full of objects rather than soley a value.
so by doing that, i modified the table to look like this
<table class="table table-bordered">
<tbody>
<tr ng-repeat="playerOrTeam in template.editableTable track by $index">
<td style="text-align: center;" ng-repeat="playerOrTeamCat in playerOrTeam track by $index">
<input ng-model="playerOrTeamCat.value" type="text" class="form-control input-sm">
</td>
</tr>
</tbody>
</table>
got the idea looking here
Modifying objects within Angular Scope inside ng-repeat

How can I change the innerHTML of div with a variable, inside the scope function in angular js?

I have 2 HTML pages. In my index.html page you can see products information that comes from JSON file. I need to have detail of product in detail.html page when people click on particular product. Alert can show the details but unfortunately the innerHTML of my <p> does not change, please guide me.
<div ng-app="myApp" ng-controller="AppController">
<div id="serachWrapper">
<h1 id="headerTopic">Our Products</h1>
<input id="searchInput" name="search" type="text" placeholder="Search products" ng-model="searchquery"/>
<table id="searchTable">
<thead id="tbHead">
<tr class="tbRow">
<th class="tbTopics">ID</th>
<th class="tbTopics">Name</th>
<th class="tbTopics">Color</th>
<th class="tbTopics">Type</th>
<th class="tbTopics">Capacity</th>
<th class="tbTopics">Price</th>
</tr>
</thead>
<tbody id="tbBody">
<tr class="tbRow" ng-repeat="x in myData | filter:searchquery ">
<td class="tbcontents" >{{x.id}}</td>
<td class="tbcontents">{{x.name}}</td>
<td class="tbcontents">{{x.color}}</td>
<td class="tbcontents">{{x.type}}</td>
<td class="tbcontents">{{x.capacity}}</td>
<td class="tbcontents">{{x.price}}</td>
</tr>
</tbody>
</table>
</div>
And this is my Angular js code:
var app = angular.module('myApp', ['ngSanitize']);
app.controller('AppController', AppController);
function AppController($scope , $http) {
$http.get("products.json").success(function(myData){
$scope.myData = myData;
$scope.go = function(item){
var detail = item.detail;
var productDetail = angular.element(document.getElementById('product-detail')).html();
productDetail = detail;
alert(detail)
};
});
}
You can keep both codes in the page and to solve this with an ng-if directive
Angular ng-if directive
<body ng-app="ngAnimate">
<label>Click me: <input type="checkbox" ng-model="checked" ng-init="checked=true" /></label><br/>
Show when checked:
<span ng-if="checked" class="animate-if">
This is removed when the checkbox is unchecked.
</span>
</body>
Why is your $scope.go function defined inside the http.get request?
Try:
function AppController($scope , $http) {
$http.get("products.json").success(function(myData){
$scope.myData = myData;
});
$scope.go = function(item) {
var detail = item.detail;
var productDetail = angular.element(document.getElementById('product-detail')).html();
productDetail = detail;
alert(detail)
};
}

Pass value from table to input text Angularjs

I have an input text with a table in which I filter some values from a JSON with an ng-repeat in meanwhile I'm typing.
<input type="text" placeholder="Choose" ng-model="item.sTxt"/>
<table>
<thead>
<tr>
<th>First Value</th>
<th>Second Value</th>
</tr>
</thead>
<tbody>
<tr
data-ng-repeat="item in numberList.getList | filter:searchText"
ng-click="setSelected(item.last)">
<td>{{item.first}}</td>
<td>{{item.last}}</td>
</tr>
</tbody>
</table>
I can show an alert when I click a row in the table in this way:
$scope.idSelectedVote = null;
$scope.setSelected = function (idSelectedVote) {
$scope.idSelectedVote = idSelectedVote;
alert(idSelectedVote);
};
but i would take that value and pass it in my input text. How could i do it in angularjs?
you can use ng-model to create a model on text input, then just pass the value of clicked table row to that model, like this
<input ng-model='input' type="text" placeholder="Choose"/>
$scope.setSelected = function (idSelectedVote) {
$scope.idSelectedVote = idSelectedVote;
$scope.input=idSelectedVote;
//alert(idSelectedVote);
};
Also if you want to filter out the repeated list, you can use the same model, in the filter.
you can see this Fiddle, it does both filter on input and place text in input on click of tr

Categories